Styling Text Input Fields

Table of Contents

A number of components use a text input field as their UI or part of their UI. These include AutoCompleteEntry, ComboBox, DateTimeEntry, MaskedEntry, TextAreaEntry and TextEntry.

The input fields have been pre-assigned various style classes, almost all of which have associated CSS rules in pre-defined stylesheets. To override any pre-defined rule, you need to craft your rule to have same or greater specificity. If a rule has the same specificity as a pre-defined rule, then it must come after the pre-defined rule, which is normally the case already, since app. stylesheets are loaded after pre-defined stylesheets. Use a debugging tool like Firebug to find out what rule is actually being applied by the browser.

The input fields share a style class called "ui-inputfield", which can be used to uniquely identify them. They can also have more general state-identifying classes: ui-state-default, ui-state-error, ui-state-optional, ui-state-required. These are assigned dynamically depending on the state of the input field.

So, for example, to distiguish between a normal input field and an input field with invalid data:

.ui-inputfield.ui-state-default {
    background-color: green;
}

.ui-inputfield.ui-state-error {
    background-color: red;
}

And to distinguish between an optional field and a required field:

.ui-inputfield.ui-state-optional {
    background-color: yellow;
}

.ui-inputfield.ui-state-required {
    background-color: blue;
}

Note that all the above rules have the same specificity. So if they are all present then the last applicable rule wins. That means optional fields are always yellow and required fields blue, whether they are in error or not. To further distinguish among these different cases, make more specific rules:

.ui-inputfield.ui-state-optional.ui-state-error {
    background-color: pink;
}

.ui-inputfield.ui-state-required.ui-state-error {
    background-color: purple;
}

The above examples use pre-defined style classes and apply to all input fields. If you want the rules to apply to one particular input field or one particular group of input fields, you have to define your own style class using the styleClass attribute:

.my-special.ui-inputfield.ui-state-optional {
    background-color: cyan;
}

.my-special.ui-inputfield.ui-state-required {
    background-color: brown;
}

In the webpage markup:

<ace:textEntry styleClass="my-special" id="address1Input" .../>
<ace:textEntry styleClass="my-special" id="address2Input" .../>
......

This assumes that the custom-defined style class is assigned to the same HTML element that the pre-defined classes are assigned to. In more complicated components like DateTimeEntry, that may not be the case. The custom style class may be assigned to an ancestor element. So we need to specify the rule slightly differnetly: (the only difference is the extra space after the custom class name in the rule)

.my-special .ui-inputfield.ui-state-optional {
    background-color: chartreuse;
}

In the webpage markup:

<ace:dateTimeEntry styleClass="my-special" renderAsPopup="true" .../>

A similar, more general technique may be useful. Say you don't want to bother figuring out every time whether the custom-defined style class would get assigned to the same element or an ancestor element. You can wrap the component(s) inside a <h:panelGroup> to create a "CSS scope":

.my-special .ui-inputfield.ui-state-optional {
    background-color: chartreuse;
}

In the webpage markup:

<h:panelGroup styleClass="my-special" ...>
    <ace:textEntry .../>
    <ace:dateTimeEntry renderAsPopup="true" .../>
    ......
</h:panelGroup>

And if you change the panelGroup styleClass into a variable, you will have a mini theme switcher: (this just switches the local CSS scope class, unlike the theme switcher component, which switches the global theme stylesheet)

.my-theme-1 .ui-inputfield.ui-state-optional {
    background-color: yellow;
}

.my-theme-2 .ui-inputfield.ui-state-optional {
    background-color: chartreuse;
}
......

In the webpage markup:

<h:panelGroup styleClass="#{myBean.themeClass}" ...>
    <ace:textEntry .../>
    <ace:dateTimeEntry renderAsPopup="true" .../>
    ......
</h:panelGroup>

Final notes:

  • styleClass attribute can have more than one class separated by spaces.
  • The order of the classes in the styleClass attribute value doesn't matter. See my comment in ICE-7868.
  • style attribute should be avoided. It is useful only in rare cases:
    • quick tests/hacks
    • CSS will never change or put in themes
    • numerous or infinite possible values, e.g. positioning coordinates
  • If you use the general "CSS scoping" technique, then no need to use individual component styleClass attribute either.
  • When in doubt, use Firebug to find out what CSS rule is actually being applied by the browser, and experiment with overriding it.
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

© Copyright 2021 ICEsoft Technologies Canada Corp.