20.1 Introduction to Skins, Style Selectors, and Style Properties

Build a skin and a cascading style sheet (CSS) using defined style selectors and configure your ADF application to use the skin and style sheet.

Use style properties to override the style information from the skin CSS to set specific instances of component display.

ADF Faces components delegate the functionality of the component to a component class, and the display of the component to a renderer. By default, all tags for ADF Faces combine the associated component class with an HTML renderer, and are part of the HTML render kit. HTML render kits are included with ADF Faces for display on both desktop and PDA. You cannot customize ADF Faces renderers. However, you can customize how components display using skins.

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. You can also programmatically set styles conditionally. For example, you may want to display text in red only under certain conditions. For more information, see Section 20.4, "Changing the Style Properties of a Component".

20.1.1 ADF Faces Skins

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. You do not have to make design-time changes to JSF pages to change their appearance when you use a skin. The skin allows you to globally change the appearance of ADF Faces components.

Existing ADF Faces applications use the skin that the application was configured to use when the application was created. For example, if you created an application using Oracle ADF 11g (11.1.1.2.0), the application uses the fusion skin. Applications created with subsequent releases use skins that extend this skin. If you upgrade an application, the application continues to use the skin that it was configured to use when first created. You edit the trinidad-config.xml file, as described in Section 20.2.4, "How to Configure an Application to Use a Custom Skin," if you want your application to use another skin.

fusion-11.1.1.3.0: Modifies the fusion skin to make the hierarchy structure in certain components that render tabs clearer. These components are panelTabbed, navigationPane (attribute hint="tabs"), and decorativeBox. This skin also defines a more subtle background image for disclosed panelAccordion component panes to make text that appears in these panes easier to read.

fusionFx-v1: This skin extends from the fusion-11.1.1.3.0 skin. If you create a custom skin that extends any of the skins provided by ADF Faces, you need to register it in the trinidad-skins.xml file. Use the following values in the trinidad-skins.xml file if you extend the fusionFx-v1 skin:

Use the following value in the trinidad-config.xml file if you want your application to use the fusionFx-v1 skin:

<skin-family>fusionFx</skin-family>

The fusionFx-v1 contains design improvements and changes to address a number of issues. Specifically, it adds:

A background color to the .AFMaskingFrame global style selector to prevent the display of content from an underlying frame when an inline popup displays in certain browsers.

A boolean ADF skin property, -tr-stretch-dropdown-table, for the inputComboboxListOfValues component. This property determines whether the table in the dropdown list stretches to show the content of the table columns or limits the width of the table to the width of the input field in the inputComboboxListOfValues component.

The inlineFrame component displays an image that serves as a loading indicator until the browser determines that the frame's contents have been loaded.

You can implement this functionality in a custom skin that you create. The af|inlineFrame selector has "busy" and "flow" pseudo-classes that enable you to do this. The inlineFrame component only generates an IFrame element when the parent component does not stretch the inlineFrame component (the inlineFrame component is flowing). Use af|inlineFrame:busy:flow to define a background-image style that references a loading indicator. When the parent component stretches the inlineFrame component, the generated content is more complex. This complexity allows you define a content image URL using the af|inlineFrame::status-icon and an optional additional background-image using the af|inlineFrame::status-icon-style. It also allows you to reuse images that other component selectors use. For example, the carousel component's af|carousel::status-icon and af|carousel::status-icon-style selectors. Use skinning aliases to reuse these images.

The following global selectors have also been introduced that you can use if you implement this functionality in your ADF skin:

.AFBackgroundImageStatus:alias: use to reference the background image used in af|inlineFrame::busy:flow.

.AFStatusIcon:alias use to reference the af|carousel::status-icon and af|inlineFrame::status-icon.

.AFStatusIconStyle:alias use to reference the af|carousel::status-icon-style and af|inlineFrame::status-icon-style.

A resource key (af_inlineFrame.LABEL_FETCHING) defines the string to display for the inlineFrame component's loading icon.

fusionFx-v1.1: This skin extends from the fusionFx-v1 skin. It adds supports for the ability to clear Query-By-Example (QBE) filters in an af:table component.

If you create a custom skin that extends any of the skins provided by ADF Faces, you need to register it in the trinidad-skins.xml file. Use the following values in the trinidad-skins.xml file if you want to extend the fusionFx-v1.1 skin:

Use the following value in the trinidad-config.xml file if you want your application to use the fusionFx-v1.1 skin:

<skin-family>fusionFx</skin-family>
<skin-version>v1.1<skin-version>

Projector skins: ADF Faces provides skins that define styles for an application that you want to demonstrate to an audience using a projector. Each projector skin modifies a number of elements in its parent skin so that an application renders appropriately when displayed using table-top projectors (particularly older models of projector). For example, the fusion-projector skin modifies a number of elements in the fusion skin. These skins are useful if the audience is present at the same location as the projector. They may not be appropriate for an audience that views an application online through a web conference. ADF Faces provides the projector skins as a download from the Oracle Technology Network (OTN) web site.

The syntax in a skin style sheet is based on the CSS 3.0 specification. However, many browsers do not yet adhere to this version. At runtime, ADF Faces converts the CSS to the CSS 2.0 specification.

Figure 20-1 Index Page Using the Fusion Skin

ADF Faces also provides the simple skin, shown in Figure 20-2 as applied to the File Explorer Application index page.

Figure 20-2 Index Page Using the Simple Skin

Skins provide more options than setting standard CSS styles and layouts. The skin's CSS file is processed by the skin framework to extract skin properties and icons and register them with the Skin object. For example, you can customize the skin file using rules and pseudo classes that are supported by the skinning framework. Supported rules and pseudo classes include @platform, @agent, @accessibility-profile, :rtl, and @locale. For more information, see Section 20.1.2, "Skin Style Selectors".

20.1.2 Skin Style Selectors

Style sheet rules include a style selector, which identifies an element, and a set of style properties, which describe the appearance of the components. ADF Faces components include two categories of skin style selectors:

Global selectors

Global selectors determine the style properties for multiple ADF Faces components. If the global selector name ends in the :alias pseudo-class, then the selector is most likely included in other component-specific selectors and will affect the skin for more than one component. For example, most, if not all, components use the .AFDefaultFontFamily:alias definition to specify the font family. If your skin overrides this selector with a different font family, that change will affect all the components that have included it in their selector definition. Example 20-1 shows the global selector for the default font family for ADF Faces components in an application.

Component-specific selectors are selectors that can apply a skin to a particular ADF Faces component. Example 20-2 shows the selector set to red as the background color for the content area of the af:inputText component.

Example 20-2 af:inputText Component Selector

af|inputText::content {
background-color: red;
}

Each category may include one or more of these types of ADF Faces skin selectors:

Standard selectors

Standard selectors are those that directly represent an element that can have styles applied to it. For example, af|body represents the af:body component. You can set CSS styles, properties, and icons for this type of element.

Selectors with pseudo-elements

Pseudo-elements are used to denote a specific area of a component that can have styles applied. Pseudo-elements are denoted by a double colon followed by the portion of the component the selector represents. For example, af|chooseDate::days-row provides the styles and properties for the appearance of the dates within the calendar grid.

Icon selectors

Some components render icons (<img> tags) using a set of base icons. These icons can have skins applied even though no entries appear in the CSS source file for the icons in the way, for example, that entries appear for the background-image CSS property. Instead, the icons are registered with the Skin object for use by the renderer. As no entries for an icon selector appear in the CSS source file that a browser interprets, you cannot create containment selector definitions for an icon definition. You can only create a containment selector definition for items that have an entry in the CSS source file.

Icon selectors are denoted by -icon for component selectors and Icon:alias for global selectors. For example, the af:inputDate component has a changed icon that can have a skin using the selector af|inputDate::changed-icon. The changed icon can also be globally set for all components using that icon with the global selector .AFChangedIcon:alias. For more information, see Section 20.3.2, "How to Apply Skins to Icons".

Resource strings

The text rendered by ADF Faces components is translatable. The text is abstracted as a resource string that has skins applied. For example, af_dialog.LABEL_OK is a resource string for the text label of an af:dialog component when the OK button has been configured. Resource strings do not have skins in the CSS skin file, but in a resource bundle referenced from the skin definition file in the trinidad-skins.xml file using the <bundle-name> parameter. You can also use the <translation-source> parameter for an EL binding to point to a Map or ResourceBundle. For more information, see Section 20.3.1, "How to Apply Skins to Text".

Selectors with style properties

Skin style properties allow you to customize the rendering of a component throughout the application. A CSS property is stored with a value in the Skin object and is available when the component is being rendered. For example, in af|breadCrumbs{-tr-show-last-item: false}, the skin property -tr-show-last-item is set to hide the last item in the af:breadCrumbs navigation path.

The CSS specification defines pseudo-classes such as :hover and :active that can apply to almost every component. ADF Faces provides additional pseudo-classes for specialized functions. Pseudo-classes are denoted in the selector by a colon followed by the class definition. The following are common pseudo-classes used by ADF Faces style selectors:

Alias: The :alias pseudo-class is a special type of class that serves as a syntax aid to organize code in your skin file. You can, for example, use it to set styles for more than one component or more than one portion of a component. You can also create your own alias classes that you can then include on other selectors. For example, you can define an alias pseudo-class (.AFLabel:alias) where you define label colors for a number of form components. Subsequent changes to the alias pseudo-class impact all components referenced by the alias pseudo-class.

Drag and drop: The two pseudo-classes available are :drag-source applied to the component initiating the drag and removed once the drag is over, and :drop-target applied to a component willing to accept the drop of the current drag.

Standard: In CSS, pseudo-classes like :hover,:active, and :focus are considered states of the component. This same concept is used in applying skins to components. Components can have states like read-only or disabled. When states are combined in the same selector, the selector applies only when all states are satisfied.

Right-to-left: Use this pseudo-class to set a style or icon definition when the browser is in a right-to-left language. Another typical use case is asymmetrical images. You will want the image to be flipped when setting skin selectors that use the image in a right-to-left reading direction. Be sure to append the :rtl pseudo-class to the very end of the selector and point it to a flipped image file. For example, the end image of the panelBox component will be the panelBoxStart.png file when the browser is set to right-to-left. The panelBox end image in right-to-left is the same as the flipped left-to-right panelBox start image.

Inline editing: This pseudo-class is applied when the application activates a component subtree for editing in the browser. For example, :inline-selected is a pseudo-class applied to currently selected components in the active inline-editable subtree.

You may not want your selector's CSS properties to be applied to all browsers, all platforms, all locales, and both reading-directions. For example, you may need to add some padding in Internet Explorer that you do not need on any other browser. You may want the font style to be different on Windows than it is on other platforms. To style a selector for a particular user environment, put that skinning information inside a skinning framework rule or :rtl pseudo-class. The skinning framework picks the styles based on the HTTP request information, such as agent and platform, and merges them with the styles without rules. Those CSS properties that match the rules get merged with those outside of any rules. The most specific rules that match a user's environment take precedence. The skinning framework currently supports these rules and pseudo-classes:

@platform and @agent

Define platform styles using @platform and browser styles using @agent.

The supported values to set a platform-specific style are windows, macos, linux, solaris, and ppc. For a browser agent-specific style, the supported values are ie, mozilla, gecko, webkit (maps to safari), ice, and email.

In this example, the content area of the af:inputText component is set to the color pink for versions 7 and 8 of Internet Explorer, and set to version 1.9 of gecko on Windows and Linux platforms:

In order to specify only version 7.0.x of Internet Explorer, use the following syntax:

@agent ie and (version: 7.0)

There is currently no syntax to specify a range of versions.

@accessibility-profile

Define @accessibility-profile, which defines styles for high-contrast and large-fonts accessibility profile settings from the trinidad-config.xml file.

The high-contrast value would be for cases where background and foreground colors need to be highly contrasted with each other. The large-fonts value would be for cases where the user must be allowed to increase or decrease the text scaling setting in the web browser. Defining large-fonts does not mean that the fonts are large, but rather that they are scalable fonts or dimensions instead of fixed pixel sizes.

Use the :rtl pseudo-class to create a style or icon definition when the browser is displaying a right-to-left language.

@locale

Suppress skin styles with the -tr-inhibit skin property.

Suppress or reset CSS properties inherited from a base skin with the -tr-inhibit skin property. For example, the -tr-inhibit:padding property will remove any inherited padding. Remove (clear) all inherited properties with the -tr-inhibit:all property. The suppressed property name must be matched exactly with the property name in the base skin.

The selectors used to apply skins to the ADF Faces components are defined in the "Skin Selectors for Fusion's ADF Faces Components" and "Skin Selectors for Fusion's Data Visualization Tools Components" topics in JDeveloper's online help.

20.1.3 Component Style Properties

You can adjust the look and feel of any component at design time by changing the style-related properties, inlineStyle and styleClass, both of which render on the root DOM element. Any style-related property you specify at design time overrides the comparable style specified in the application skin or CSS for that particular instance of the component.

The inlineStyle attribute is a semicolon-delimited string of CSS styles that can set individual attributes, for example, background-color:red; color:blue; font-style:italic; padding:3px. The styleClass attribute is a CSS style class selector used to group a set of inline styles. The style classes can be defined using an ADF public style class, for example, .AFInstructionText, sets all properties for the text displayed in an af:outputText component.

20.2 Applying Custom Skins to Applications

Custom skins can change the colors, fonts, and even the location of portions of ADF Faces components to represent your company's preferred look and feel. You build the skin by defining style selectors in a CSS file. After you create your custom style sheet, register it as a valid skin in the application, and then configure the application to use the skin. If you versioned multiple ADF skins in the same skin family, as described in Section 20.6, "Versioning Custom Skins," use the <skin-version> element to identify the specific version that you want the application to use.

By default, ADF Faces components use the fusion skin. Custom skins can extend to any of the ADF Faces skins, fusion, blafplus-rich, blafplus-medium, or simple. To create a custom skin, you declare selectors in a style sheet that override or inhibit the selectors in the style sheet being extended. Any selectors that you choose not to override will continue to use the style as defined in that skin.

Extending the simple skin does not require inhibiting as many properties as you would if you extended the BLAF Plus skins. For example, the BLAF Plus skins use many different colors for style properties, including text, background, and borders. The simple skin uses the :alias pseudo-class, as in .AFDarkBackground:alias, instead of specific colors. Changing a color scheme would require overriding far fewer global skin selectors than component skin selectors that specify multiple colors.

The text used in a skin is defined in a resource bundle. As with the selectors for the blafplus-rich skin, you can override the text by creating a custom resource bundle and declaring only the text you want to change. After you create your custom resource bundle, register it with the skin.

You can create and apply multiple skins. For example, you might create one skin for the version of an application for the web, and another for when the application runs on a PDA. Or you can change the skin based on the locale set on the current user's browser. Additionally, you can configure a component, for example an af:selectOneChoice component, to allow a user to switch between skins.

While you can bundle the custom skin resources and configuration files with the application for deployment, you can also store skin definitions in a Java Archive (JAR) file and then add it to the deployed application. The advantages to using a JAR file are that the custom skin can be developed and deployed separately from the application, improving consistency in the look and feel, and that skin definitions and image files can be partitioned into their own JAR files, reducing the number of files that may have to be deployed to an application.

The steps to apply a custom skin to your application are the following:

20.2.1 How to Add a Custom Skin to an Application

To add a custom skin to your application, create a CSS file within JDeveloper, which places the CSS in a project's source file for deployment with the application.

To add a custom skin to an application:

In JDeveloper, make sure that CSS Level 3 and ADF Faces are selected. From the main toolbar, choose Tools > Preferences > CSS Editor. For Support Level, choose CSS Level 3 from the dropdown menu, and for Supported Components, select ADF Faces Extension.

In the Application Navigator, right-click the project that contains the code for the user interface and choose New from the context menu.

In the New Gallery under Categories, expand Web Tier and select HTML.

Double-click the CSS File option.

In the Create Cascading Style Sheet dialog, enter a name and path for the CSS.

20.2.2 How to Register the XML Schema Definition File for a Custom Skin

You need to register the trindidad-skins.xsd file with JDeveloper if you plan to register a custom skin, as described in Section 20.2.3, "How to Register a Custom Skin". The trindidad-skins.xsd file defines the valid elements for a custom skin.

To register an XML schema definition file:

In JDeveloper, select Tools > Preferences.

In the Preferences dialog, select XML Schemas in the left pane and click Add.

In the Add Schema dialog, click Browse to navigate to the XML schemas included in your version of JDeveloper.

In the Add Schema dialog, make sure the value in the Extension input field is .xml. If you change it to .xsd, when you later create XML files, you will not be able to use the XML schema you have created.

Click OK.

20.2.3 How to Register a Custom Skin

Registering a skin involves creating a file named trinidad-skins.xml and populating it with values that identify the skin's ID, family, location, and the custom resource bundle if you are using one.

A skin is required to have a unique ID. You can also use an EL expression to reference the skin ID. For example, if you want to have different skins for different locales, create an EL expression that selects the correct skin based on its ID. The convention is to put a "desktop" or ".pda" or ".portlet" at the end of the ID, such as "fusion.desktop".

<family>

You configure an application to use a particular family of skins. This allows you to group skins together for an application, based on the render kit used.

For example, you can define the blafplus-rich.desktop skin and the blafplus-rich.pda skin to be part of the richDemo family and the system automatically chooses the right skin based on the render-kit-id.

This value determines which render kit to use for the skin. You can enter one of the following:

org.apache.myfaces.trinidad.desktop: The skin will automatically be used when the application is rendered on a desktop.

org.apache.myfaces.trinidad.pda: The skin will be used when the application is rendered on a PDA.

<style-sheet-name>

This is the URL of the custom style sheet. The style sheet name file is retrieved as a URL object using the following methods:

For nonstatic URLs, those that could change after the server has started, the URL is created by calling new java.new.URL(style-sheet-name) if style-sheet-name starts with http:, https:, file:, ftp:, or jar:. Otherwise, the URL is created by calling <FacesContext><ExternalContext>getResource<style-sheet-name>. It will add a slash (/) to delimit the URL parts if it is not already present. For example, the slash is added between skins/bigfont/bigfont.css.

If still not retrieved, the URL is created using the <ClassLoader> getResource in a style-sheet-name format similar to META-INF/purpleSkin/styles/myPurpleSkin.css. Once the URL is converted to this format, it can be searched for in JAR files that may contain the style sheet.

If you have created localized versions of the resource bundle, then you need to register only the base resource bundle.

<translation-source>

This is an EL binding that can point to a Map or a ResourceBundle. You can use this instead of the bundle name if you would like to be more dynamic in your skin translations at runtime. The <bundle-name> tag takes precedence.

Example 20-4 shows the entry in the trinidad-skins.xml file for the mySkin skin.

To conditionally set the value, enter an EL expression that can be evaluated to determine the skin to display.

For example, if you want to use the German skin when the user's browser is set to the German locale, and to use the English skin otherwise, you would have the following entry in the trinidad-config.xml file:

During development, after you make changes to the custom skin, you can see your CSS changes without restarting the server by setting the web.xml file parameter org.apache.myfaces.trinidad.CHECK_FILE_MODIFICATION to true, as shown in Example 20-6. However, you must always restart the server to see icon and skin property changes.

20.3 Defining Skin Style Properties

The ADF Faces skin style selectors support multiple options for applying skins to a component to create a custom look and feel to your application. The af:goButton component skin style selectors are described in Table 20-1.

Table 20-1 af:goButton Component Style Selectors

Name

Description

af|goButton

Style on the root element of the af:goButton component. You can use any valid CSS-2.1 pseudo-class, like :hover, :active, or :focus, as well as :disabled, to style the component for different states. Note that for buttons, the :active and :focus pseudo-classes do not work in Internet Explorer 7 (IE7). IE7 also does not allow disabled buttons to be styled. You should use the .AFButton*:alias selectors as a shortcut to apply a skin to all button components in the same manner.

af|goButton::icon-style

Style on the button icon, if the icon attribute is set on the af:goButton.

af|goButton::access-key

Style on the text of the button. This includes the .AFButtonAccessKeyStyle:alias style.

Figure 20-3 shows the application of the default fusion skin on the af:goButton component and the component icon.

Figure 20-3 af:goButton Component Default Appearance

Figure 20-4 shows the new appearance of the button and icon by setting the following style properties in a custom skin:

The ADF Faces skin style selectors used by the default skin are defined in the "Skin Selectors for Fusion's ADF Faces Components" and "Skin Selectors for Fusion's Data Visualization Tools Components" topics in JDeveloper's online help. They are located in All Online Help > Developing Oracle ADF Faces Applications.

JDeveloper provides coding support while editing your CSS files. You can invoke the CSS code editor when editing your file directly or when editing an ADF Faces component in the JSP source editor. Code support is available for the following:

Code insight

Error highlighting

Preview of styles

Refactoring

Finding usages

Quick comment

Formatting

Matching tag highlighting

20.3.1 How to Apply Skins to Text

In addition to using a CSS file to determine styles, skins also use a resource bundle to determine the text within a component. The text that ADF Faces components render can be translated and abstracted as a resource string. For example, af_chooseDate.LABEL_SELECT_YEAR is the resource string for the label of the field used to select the year using an af:chooseDate component. All the ADF Faces skins use the same resource bundle.

To apply a skin to the text in ADF Faces components, create a custom resource bundle and override the default resource string values. Then, set the <bundle-name> property for your custom resource bundle in the trinidad-skins.xml file.

Note:

ADF Faces components provide automatic translation. The resource bundle used for the components' skin is translated into 28 languages. If a user sets the browser to use the German (Germany) language, any text contained within the components will automatically be displayed in German. For this reason, if you create a resource bundle for a custom skin, you must also create localized versions of that bundle for any other languages the application supports.

Another option for applying skins to text is to use the <translation-source> parameter instead of <bundle-name>. The <translation-source> parameter is an EL binding that points to a Map or a ResourceBundle. The benefit of this option is that you can automatically change the translation value based on any logic that you want at runtime. The <bundle-name> tag takes precedence if both are set. Example 20-9 shows the code for using an EL expression to set the <translation-source> parameter in a bundle map.

Icons and buttons can both use the rtl pseudo-class. This defines an icon or button for use when the application displays in right-to-left mode. Example 20-12 shows the rtl pseudo-class used for an icon.

20.3.3 How to Apply Skins to Messages

You can apply style to ADF Faces input components based on whether or not they have certain levels of messages associated with them. When a message of a particular type is added to a component, the styles of that component are automatically modified to reflect the new status. If styles are not defined for the status in question, then the default styles are used.

In order to define styles for your input components based on message levels that are tied to them, you would append a style pseudo-class to your component definition. For example, to define the base style for the content region of the af:inputText component to a background color of purple, use the style selector af|inputText::content{background-color:purple}. To define the content region of the component when an error message is present, use the skin style selector af|inputText:error::content.

20.3.4 How to Apply Themes to Components

Themes are a way of implementing a look and feel at a component level. The purpose is to provides a consistent look and feel across multiple components for a portion of a page. A common usage for themes is in a JSF page template where certain areas have a distinct look. For example, a page may have a branding area at the top with a dark background and light text, a navigation component with a lighter background, and a main content area with a light background.

A component that sets a theme exposes that theme to its child components and therefore the theme is inherited. Themes can be set (started or changed) by the following components:

af:document

af:decorativeBox

af:panelStretchLayout

af:panelGroupLayout

The Fusion and BLAF Plus skins (blafplus-rich and blafplus-medium) support the following themes:

Dark

Medium

Light

None (default)

In the JSPX page, the theme is started by the af:document component, as in:

To set the theme for a component, specify a theme attribute in the skin selector in the CSS file. For example, the selector to change the text color under an af:panelTabbed component to a dark theme is:

af|panelTabbed[theme="dark"] {
color: red;
}

If you do not want a child component to inherit modifications made to a parent component in a JSPX page, set a value for the -tr-children-theme property in the CSS file. For example, you do not want the af:panelTabbed child component to inherit the dark theme defined for the af:document parent component in the JSPX page. Set the -tr-children-theme property in the CSS file as follows:

af|panelTabbed::content {
-tr-children-theme: default;
}

By default, themes are not set for components or their child components. Because themes are inherited, the following values are supported when a component has a theme attribute that is not set:

not given - If no theme is given, the theme is inherited, as in <af:decorativeBox>...

#{null}- The theme is inherited; same as not given.

inherit - The theme is inherited; same as null.

default - The theme is removed for the component and its child components.

empty string - If the theme is set to a blank string, it has the same behavior as default. For example, <af:decorativeBox theme=""> will remove the theme for the component and its child components.

Because the themes are added to every HTML element of a component that supports themes and that has style classes, there is no need for containment-style CSS selectors for themes. With the exception of :ltr and :rtl, all theme selectors should always appear on the last element of the selector. For example, the selector to apply a dark theme to each step of an af:breadCrumbs component would be:

af|breadCrumbs::step:disabled[theme="dark"] {
color:#FFFFFF;
}

Color incompatibility may occur if a component sets its background color to a color that is not compatible with its encompassing theme color. For example, if a panelHeader component is placed in a dark theme, the CSS styles inside the panelHeader component will set its component background to a light color without changing its foreground color accordingly. The result is a component with a light foreground on a light background. Many other components also set their foreground color to a light color when placed in a dark theme.

If color incompatibility occurs, you can resolve color incompatibility between parent and child components by setting a value for the -tr-children-theme property. For components that do not have a parent-child relationship, you can manually set the component's theme color to a color that is compatible with the surrounding theme color. You do this by inserting the panelGroupLayout or panelStretchLayout component inside the component and by setting the panelGroupLayout or panelStretchLayout theme to a compatible color.

20.3.6 How to Configure a Component for Changing Skins Dynamically

To configure a component to dynamically change the skin, you must first configure the component on the JSF page to set a scope value that can later be evaluated by the configuration file. You then configure the skin family in the trinidad-config file to be dynamically set by that value.

To conditionally configure a component to set the skin family:

Open the main JSF page (such as the index.jspx or a similar file) that contains the component that will be used to set the skin family.

Configure the page to display the skin family by using the sessionScope component.

Example 20-14 shows an af:selectOneChoice component that takes its selected value, and sets it as the value for the skinFamily attribute in the sessionScope component on the index.jspx page.

The Refresh button on the page resubmits the page. Every time the page refreshes, the EL expression is evaluated and if there is a change, the page is redrawn with the new skin.

To conditionally configure a component for changing skins at runtime:

In the trinidad-config.xml file, use an EL expression to dynamically evaluate the skin family:

<skin-family>#{sessionScope.skinFamily}</skin-family>

20.4 Changing the Style Properties of a Component

ADF Faces components use the CSS style properties based on the Cascading Style Sheet (CSS) specification. Cascading style sheets contain rules, composed of selectors and declarations, that define how styles will be applied. These are then interpreted by the browser and override the browser's default settings.

WARNING:

Do not use styles to achieve stretching of components. Using styles to achieve stretching is not declarative and, in many cases, will result in inconsistent behavior across different web browsers. Instead, you can use the geometry management provided by the ADF Faces framework to achieve component stretching. For more information about layouts and stretching, see Section 8.2.1, "Geometry Management and Component Stretching.".

You can use an EL expression for the inlineStyle attribute itself to conditionally set inline style attributes. For example, if you want the date to be displayed in red when an action has not yet been completed, you could use the code similar to that in Example 20-16.

The ADF Faces component may have other style attributes not available for styling that do not register on the root DOM element. For example, for the af:inputText component, set the text of the element using the contentStyle property, as shown in Example 20-17.

Example 20-17 Using the contentStyle Property

<af:inputText value="outputText1"
contentStyle="color:Red;"/>

20.4.2 How to Set a Style Class

You can define the style for a component using a style class. You create a style class to group a set of inline styles.

To set a style using a style class:

Set the styleClass attribute of the component to the style class you want to use.

Example 20-18 shows an example of a style class being used in the page source.

Example 20-18 Page Source for Using a Style Class

<af:outputText value="Text with a style class"
styleClass="overdue"/>

You can also use EL expressions for the styleClass attribute to conditionally set style attributes. For example, if you want the date to be displayed in red when an action has not yet been completed, you could use code similar to that in Example 20-16.

20.5 Referring to URLs in a Skin's CSS File

You can refer to a URL from a skin's CSS file in a number of different formats. The supported formats are:

Absolute

You specify the complete URL to the resource. For example, a URL in the following format:

http://www.mycompany.com/WebApp/Skin/skin1/img/errorIcon.gif

Relative

You can specify a relative URL if the URL does not start with / and no protocol is present. A relative URL is based on the location of the skin's CSS file. For example, if the skin's CSS file directory is WebApp/Skin/skin1/ and the specified URL is img/errorIcon.gif, the final URL is /WebApp/Skin/mySkin/img/errorIcon.gif

Context relative

This format of URL is resolved relative to the context root of your web application. You start a context relative root with /. For example, if the context relative root of a web application is:

/WebApp

and the specified URL is:

/img/errorIcon.gif

the resulting URL is:

/WebApp/img/errorIcon.gif

Server relative

A server relative URL is resolved relative to the web server. This differs to the context relative URL in that it allows you reference a resource located in another application on the same web server. You specify the start of the URL using //. For example, write a URL in the following format:

//WebApp/Skin/mySkin/img/errorIcon.gif

20.6 Versioning Custom Skins

You can specify version numbers for your custom skins in the trinidad-skins.xml file using the <version> element. Use this capability if you want to distinguish between custom skins that have the same value for the <family> element in the trinidad-skins.xml file. Note that when you configure an application to use a particular custom skin, you do so by specifying values in the trinidad-config.xml file, as described in Section 20.2, "Applying Custom Skins to Applications."

20.6.1 How to Version a Custom Skin

You specify a version for your custom skin by entering a value for the <version> element in the trinidad-skins.xml file.

To version a custom skin:

In the Application Navigator, double-click the trinidad-skins.xml file. By default, this is in the Web Content/WEB-INF node.

In the structure window, right-click the skin node for the custom skin that you want to version and choose Insert inside skin > version.

In the Insert version dialog, select true from the default list if you want your application to use this version of the custom skin when no value is specified in the <skin-version> element of the trinidad-config.xml file, as described in Section 20.2, "Applying Custom Skins to Applications."

Enter a value in the name field. For example, enter v1 if this is the first version of the custom skin.

Click OK.

20.6.2 What Happens When You Version Custom Skins

Example 20-19 shows an example trinidad-skins.xml that references three source files for custom skins (skin1.css, skin2.css, and skin3.css). Each of these custom skins have the same value for the <family> element (test). The values for the child elements of the <version> elements distinguish between each of these custom skins. At runtime, an application that specifies test as the value for the <skin-family> element in the application's trinidad-config.xml file uses skin3 because this custom skin is configured as the default skin in the trinidad-skins.xml file (<default>true</default>). You can override this behavior by specifying a value for the <skin-version> element in the trinidad-config.xml file, as described in Section 20.2, "Applying Custom Skins to Applications."

20.7 Deploying a Custom Skin File in a JAR File

You may want to store skin definitions in a Java Archive (JAR) file and then add it to the deployed application. The benefits of packaging skins into a JAR file as compared to bundling them into the application are the following:

A skin can be deployed and developed separately from the application. This also helps to reduce the number of files to be checked in case some changes must be applied to the skin. Foremost is that using a skin definition contained in a JAR file improves consistency in the look and feel of the application.

Skin definitions and images can be separated into their own JAR files. Therefore, you can partition the image base into separate JAR files, so that not all files have to be deployed with all applications.

To deploy a skin into a JAR file, follow these rules:

The trinidad-skins.xml file that defines the skin and that references the CSS file must be within the META-INF directory.

All image resources and CSS files must also be under the META-INF directory. The images must be in a directory that starts with an adf root directory or any directory name that is mapped in the web.xml file for the resource servlet, as shown in Example 20-20.

The JAR file must be placed in the WEB-INF/lib directory of the view layer project of the application to deploy (or use a shared library at the application-server level).

Confirm that the directory in the META-INF directory starts with adf. The images directory contains all the images used within the oracleblaf.css skin. The CSS reference to the images should have a path similar to this:

Note the two leading periods in front of the image path ../adf/oracle/skin/images/cfsortl.png. This allows the search for the META-INF root to start one directory above the META-INF/skin directory in which the CSS is located.

Check that the trinidad-skins.xml file is located in the META-INF directory and that it contains content in a format similar to this:

This example defines the skin as richdemo.desktop in the richDemo family. The trinidad-skins.xml file can have more than one skin definition. The richdemo.css file (or your custom CSS file) is referenced from the style-sheet-name element.

To create the JAR file, issue the following command from the c:\temp directory:

jar -cvf customSkin.jar META-INF/

Copy the resulting customSkin.jar file to the WEB-INF/lib directory of the consuming ADF project. Configure the trinidad-skins.xml file located on the WEB-INF directory of the ADF project.