Today a discussion arose with one of the UI Designers on the ADF 11g project I work on. He is used to a certain way of styling web applications. He wants to work with ‘clean’ HTML – as little styling in it as possible, very W3C compliant and preferably structured – DIVs, ULs, … – in a way that makes applying external stylesheets very easy. He would like the HTML to contain values for the (style) class at specific points. And he will then take it from there.
While this approach is fairly common for Web Designers, it is not one that works well with most component based web frameworks, such as JavaServer Faces libraries. With JSP tag libraries and JSF components, web page developers have no direct control over the HTML that is rendered. Components provide productivity and help achieve consistency in source code and in look & feel. Typically this is seen as ample compensation for the loss of control over the exact HTML rendered.
The loss of control over styling with component based web frameworks is usually addressed in an inside out manner. Instead of applying CSS stylesheets on the final HTML result – styles are set on the components themselves. Server side styling instructions are interpreted by the components themselves and turned into CSS styling code for the browser.
The use of stand-alone components has consequences for the HTML that gets rendered. Instead of designing an HTML page in its entirety, taking care to proper alignments across containers, leveraging relative CSS positioning, components can only generate the HTML for themselves. HTML that must work in any circumstance. Typically this HTML is not what it would be when a web designer creates the entire page – knowing what will come where and creating the best HTML and CSS for the page. Again, using components means sacrificing some (or sometimes a lot) in terms of proper HTML and CSS to gain tremendous productivity.
With the use of external stylesheets, the styling is not component oriented (it is probably component unaware, as the components do not really appear in the generated HTML) but focused on the HTML; the HTML is not as structured as would be desired; more importantly: the HTML rendered by components can change with new versions of the components; styling that builds on the HTML structure currently produced by components may well be outdated in the near future.
Skinning – Component aware, Server Side Styling
Skins are server-side artefacts that determine the styling of ADF Faces components. " A skin is a style sheet based on the CSS 3.0 syntax specified in one place for an entire application. Instead of providing a style sheet for each component, or inserting a style sheet on each page, you can create one skin for the entire application. Every component automatically uses the styles as described by the skin." The 11g RichClient Components have been designed with skinning engrained from the very beginning. These components when rendered through the HTML renderkit know how to read skin specifications and turn them into CSS styleclasses on the HTML that gets rendered. At the same time, the server side skin is converted to a client side CSS stylesheet – on the fly – that the browser can interpret and use to style according to the styleclasses written by the components in the rendered HTML.
Skins apply to the entire application. They are not used to style individual instances of components, although to some extent we can make skin features conditional.
It is easy to switch skins between pages. The skin is configured in the
trinidad-config.xml file. This configuration can use an EL expression. When a page is rendered – full page refresh – the expression is reevaluated and can result in another skin being applied – for example depending on the application module the user has entered, the time of day of the preferences of the user.
ADF Faces Skins have built in support for browser version, operating system and locale – CSS for specific browser generated at run-time. The supplied skins are aware of the issues for specific combinations of browser (version), OS and locale and cater for them. Our own custom skins can have such facilities as well.
Styling individual components
"If you do not wish to change ADF Faces components throughout the entire application, you can choose to change the styles for the instance of a component on a page using the styleClass property – to refer to a style defined in a external CSS stylesheet – or even specify the style right on the component."
When we specify a styleClass on a component, it typically appears as the class attribute on a single HTML element. Yet, the component may well render multiple HTML elements. Styling visual attributes of the other HTML elements can be quite complex as the styling instructions have to take the currently rendered HTML structure into account.
In addition to styleClass, most components also allow the style itself to be defined – right there in the page definition – using an EL expression for dynamic or conditional assignment if we like. Note that in some cases components – such as ADF 11g RichClient components – allow multiple styleclasses to be set. For example the inputText component has inlineStyle and contentStyle. The latter applies to input item in the HTML page – where the user enters the value – while inlineStyle is a set of CSS styles that are applied to the root DOM element of the component. Many components are composed of several DOM elements which may have their own styles applied to them.
The component based approach of JSF in general and ADF Faces in particular do not go well together with an outside-in styling approach. Control over the HTML rendered is very limited. Styling should not be made to depend on the HTML structure. Instead, styling should be done inside out – using skins (server side styling) technology to achieve the desired look & feel. Apart from several benefits – skin styles inherit properties from each other, making global changes across all or all similar components fairly simple; skins offer automatic support for differences between browsers and locales; skins can be switched dynamically; skins are component oriented and through skins most visual component characteristics can be set – there are limitations with skins. For starters, they do not style individual component instances. And they are – at least initially – less intuitive than the use of external stylesheets will be for most web designer. You have to learn how to work with skins.
ADF 11g Documentation on Skinning and defining Styles.
Live demo of ADF 11g – including demonstration of skinning options.