Monday, May 10, 2010

Mobile Web in JavaME apps - now with CSS!

Twitter's home page as rendered by HTMLComponent before CSS support and after

Following my post on Mobile Web in JavaME that discussed the new possibility of embedding web content inside LWUIT applications using HTMLComponent, I'm glad to announce that CSS support was added to HTMLComponent and is now publicly available in the LWUIT SVN.

Now, developers can not only render HTML documents in their JavaME apps, but can also design them with CSS by adding colors, borders, backgrounds, fonts and more. This means that now HTMLComponent is almost fully compliant with the XHTML Mobile Profile 1.0 standard, which requires WCSS support (WCSS specs here)

The support is about 90% complete and provides almost complete coverage for most pages today. The 10% that were not implemented (at least yet) are features that do not sit well with LWUIT's styling model and/or they require extensive efforts and provide with little value (Some of these are less used tags or edge cases). In any case, you should be able to see most pages rendered correctly (And if you create your own content you can simply avoid using unsupported properties for now).

And while there's a great difference in how HTML pages will look now, the change is transparent to developers, and there's almost no difference in using HTMLComponent. Basically once you load a page that has CSS segments (either external, embedded or via the style attribute) they will be parsed and rendered.

The only difference is that you can turn CSS off by calling HTMLComponent's setIgnoreCSS method, if you don't want CSS segments parsed for some reason. And actually there may be reasons for that - CSS does require extra memory, and adds some performance overhead as well, all depending on how complex the CSS used in specific pages are.

There are also more esoteric methods such as addSpecialKey and setCSSSupportedMediaTypes - I won't go into details on those here, you can read the documentation.

Here's the full list of what's supported and what not:

Fully supported CSS properties

Background: background-color, background-image, background-repeat, background-attachment, background-position-x, background-position-y
Border: border-*-width, border-*-style, border-*-color
Fonts: font-family, font-size, font-style, font-weight, font-variant
Lists: list-style-image, list-style-position, list-style-type
Margins: margin-* , padding-*
Text: text-align, text-indent, text-transform
Misc: color, height, width, visibility
WAP : -wap-access-key,-wap-input-format,-wap-input-required
Shorthand properties: All shorthand properties are fully supported
(* = top/left/bottom/right)

Unsupported/Partially supported properties:

Unsupported: clear, float

Partially supported:
- display - Supported: none, marquee / Unsupported: block, inline , list-item
- white-space - Supported: normal, nowrap / Unsupported: pre
- vertical-align - Works only within tables

Known issues
  • width/height work for simple elements, but may be problematic with complex elements.
  • font-family accepts the first mentioned font and ignores all fallback fonts, since finding a matching font is very time consuming, and also since in the ME environment usually there aren't that many fonts anyway.
  • text-decoration is unrelevant: since the only mandatory WCSS decoration value is 'none' which is usually used to remove underlines from links - since we don't have underlines it has no meaning.
  • text-transform may have issues when overriding a parent which has a different transform.
  • HTMLComponent.FIXED_WIDTH mode does not work with some CSS attributes, and thus its default value is now false (The downside is that in FIXED_WIDTH mode 'justify' alignment doesn't work).
  • Some properties will be ignored if associated with a pseudo-class (such as a:focus/hover) - and that's because while LWUIT does have separate styles for selected, unselected and pressed states - these styles include properties such as padding, margins, colors, background, font - but for example not alignment or visibility which affect the component in all of its states.