Icons

Andy Bailey

October 2015

In this article by Andy Bailey and Sudheer Jonna, the authors of the book, PrimeFaces Theme Development, we'll cover icons, which add a lot of value to an application based on the principle that a picture is worth a thousand words. Equally important is the fact that they can, when well designed, please the eye and serve as memory joggers for your user. We humans strongly associate symbols with actions. For example, a save button with a disc icon is more evocative. The association becomes even stronger when we use the same icon for the same action in menus and button bars. It is also possible to use icons in place of text labels. It is an important thing to keep in mind when designing the user interface of your application that the navigational and action elements (such as buttons) should not be so intrusive that the application becomes too cluttered with the things that can be done. The user wants to be able to see the information that they want to see and use input dialogs to add more. What they don't want is to be distracted with links, lots of link and button text, and glaring visuals.

In this article, we will cover the following topics:

  • The standard theme icon set
  • Creating a set of icons of our own
  • Adding new icons to a theme
  • Using custom icons in a commandButton component
  • Using custom icons in a menu component
  • The FontAwesome icons as an alternative to the ThemeRoller icons

(For more resources related to this topic, see here.)

Introducing the standard theme icon set

jQuery UI provides a big set of standard icons that can be applied by just adding icon class names to HTML elements. The full list of icons is available at its official site, which can be viewed by visiting http://api.jqueryui.com/theming/icons/.

Also, available in some of the published icon cheat sheets at http://www.petefreitag.com/cheatsheets/jqueryui-icons/.

The icon class names follow the following syntax in order to add them for HTML elements:

.ui-icon-{icon type}-{icon sub description}-{direction}
.ui-icon-{icon type}-{icon sub description}-{direction}

For example, the following span element will display an icon of a triangle pointing to the south:

<span class="ui-icon ui-icon-triangle-1-s"></span>

Other icons such as ui-icon-triangle-1-n, ui-icon-triangle-1-e, and ui-icon-triangle-1-w represent icons of triangles pointing to the north, east, and west respectively. The direction element is optional, and it is available only for a few icons such as a triangle, an arrow, and so on.

These theme icons will be integrated in a number of jQuery UI-based widgets such as buttons, menus, dialogs, date picker components, and so on.

The aforementioned standard set of icons is available in the ThemeRoller as one image sprite instead of a separate image for each icon. That is, ThemeRoller is designed to use the image sprites technology for icons. The different image sprites that vary in color (based on the widget state) are available in the images folder of each downloaded theme.

An image sprite is a collection of images put into a single image. A webpage with many images may take a long time to load and generate multiple server requests. For a high-performance application, this idea will reduce the number of server requests and bandwidth. Also, it centralizes the image locations so that all the icons can be found at one location.

The basic image sprite for the PrimeFaces Aristo theme looks like this:

The image sprite's look and feel will vary based on the screen area of the widget and its components such as the header and content and widget states such as hover, active, highlight, and error styles.

Let us now consider a JSF/PF-based example, where we can add a standard set of icons for UI components such as the commandButton and menu bar.

First, we will create a new folder in web pages called chapter6. Then, we will create a new JSF template client called standardThemeIcons.xhtml and add a link to it in the chaptersTemplate.xhtml template file. When adding a submenu, use Chapter 6 for the label name and for the menu item, use Standard Icon Set as its value.

In the title section, replace the text title with the respective topic of this article, which is Standard Icons:

<ui:define name="title">
  Standard Icons
</ui:define>

In the content section, replace the text content with the code for commandButton and menu components.

Let's start with the commandButton components. The set of commandButton components uses the standard theme icon set with the help of the icon attribute, as follows:

<h:panelGroup style="margin-left:830px">
  <h3 style="margin-top: 0">Buttons</h3>
  <p:commandButton value="Edit" icon="ui-icon-pencil" 
    type="button" />
  <p:commandButton value="Bookmark" icon="ui-icon-bookmark" 
    type="button" />
  <p:commandButton value="Next" icon="ui-icon-circle-arrow-e" 
    type="button" />
  <p:commandButton value="Previous" icon="ui-icon-circle-arrow-w" 
    type="button" />
</h:panelGroup>

The generated HTML for the first commandButton that is used to display the standard icon will be as follows:

<button id="mainForm:j_idt15" name="mainForm:j_idt15" class="ui- 
  button ui-widget ui-state-default ui-corner-all ui-button-text- 
  icon-left" type="button" role="button" aria-disabled="false">
  <span class="ui-button-icon-left ui-icon ui-c   ui-icon- 
    pencil"></span>
  <span class="ui-button-text ui-c">Edit</span>
</button>

The PrimeFaces commandButton renderer appends the icon position CSS class based on the icon position (left or right) to the HTML button element, apart from the icon CSS class in one child span element and text CSS class in another child span element. This way, it displays the icon on commandButton based on the icon position property. By default, the position of the icon is left.

Now, we will move on to the menu components. A menu component uses the standard theme icon set with the help of the menu item icon attribute. Add the following code snippets of the menu component to your page:

<h3>Menu</h3>
<p:menu style="margin-left:500px">
  <p:submenu label="File">
    <p:menuitem value="New" url="#" icon="ui-icon-plus" />
    <p:menuitem value="Delete" url="#" icon="ui-icon-close" />
    <p:menuitem value="Refresh" url="#" icon="ui-icon-refresh" />
    <p:menuitem value="Print" url="#" icon="ui-icon-print" />
  </p:submenu>
  <p:submenu label="Navigations">
    <p:menuitem value="Home" url="http://www.primefaces.org" 
      icon="ui-icon home" />
    <p:menuitem value="Admin" url="#" icon="ui-icon-person" />
    <p:menuitem value="Contact Us" url="#" icon="ui-icon- 
      contact" />
  </p:submenu>
</p:menu>

You may have observed from the preceding code snippets that each icon from ThemeRoller starts with ui-icon for consistency.

Now, run the application and navigate your way to the newly created page, and you should see the standard ThemeRoller icons applied to buttons and menu items, as shown in the following screenshot:

For further information, you can use PrimeFaces showcase (http://www.primefaces.org/showcase/), where you can see the default icons used for components, applying standard theme icons with the help of the icon attribute, and so on.

Creating a set of icons of our own

In this section, we are going to discuss how to create our own icons for the PrimeFaces web application. Instead of using images, you need to use image sprites by considering the impact of application performance.

Most of the time, we might be interested in adding custom icons to UI components apart from the regular standard icon set. Generally, in order to create our own custom icons, we need to provide CSS classes with the background-image property, which is referred to the image in the theme images folder.

For example, the following commandButton components will use a custom icon:

<p:commandButton value="With Icon" icon="disk"/>
<p:commandButton icon="disk"/>

The disk icon is created by adding the .disk CSS class with the background image property. In order to display the image, you need to provide the correct relative path of the image from the web application, as follows:

.disk {
  background-image: url('disk.png') !important;
}

However, as discussed earlier, we are going to use the image sprite technology instead of a separate image for each icon to optimize web performance.

Before creating an image sprite, you need to select all the required images and convert those images (PNG, JPG, and so on) to the icon format with a size almost equal to to that of the ThemeRoller icons. In this article, we used the Paint.NET tool to convert images to the ICO format with a size of 16 by 16 pixels. Paint.NET is a free raster graphics editor for Microsoft Windows, and it is developed on the .NET framework. It is a good replacement for the Microsoft Paint program in an editor with support for layers blending, transparency, and plugins. If the ICO format is not available, then you have to add the file type plug-in for the Paint.NET installation directory.

So, this is just a two-step process for the conversion:

  1. The image (PNG, JPG, and so on) need to be saved as the Icons (*.ico) option from the Save as type dropdown.
  2. Then, select 16 by 16 dimensions with the supported bit system (8-bit, 32-bit, and so on). All the PrimeFaces theme icons are designed to have the same dimensions.

There are many online and offline tools available that can be used to create an image sprite. I used Instant Sprite, an open source CSS sprite generator tool, to create an image sprite in this article. You can have a look at the official site for this CSS generator tool by visiting http://instantsprite.com/.

Let's go through the following step-by-step process to create an image sprite using the Instant Sprite tool:

  1. First, either select multiple icons from your computer, or drag and drop icons on to the tool page.
  2. In the Thumbnails section, just drag and drop the images to change their order in the sprite.
  3. Change the offset (in pixels), direction (horizontal, vertical, and diagonal), and the type (.png or .gif) values in the Options section.
  4. In the Sprite section, right-click on the image to save it on your computer. You can also save the image in a new window or as a base64 type.
  5. In the Usage section, you will find the generated sprite CSS classes and HTML.
  6. Once the image is created, you will be able to see the image in the preview section before finalizing the image.

Now, let's start creating the image sprite for button bar and menu components, which are going to be used in later sections.

First, download or copy the required individual icons on the computer. Then, select all those files and drag and drop them in a particular order, as follows:

We can also configure a few options, such as an offset of 10 px for icon padding, direction as horizontal to display them horizontally, and then finally selecting the image as the PNG type:

The image sprite is generated in the sprite section, as follows:

Right-click on the image to save it on your computer. Now, we have created a custom image sprite from the set of icons. Once the image sprite has been created, change the sprite name to ui-custom-icons and copy the generated CSS styles for later.

In the generated HTML, note that each div class is appended with the ui-icon class to display the icon with a width of 16 px and height of 16 px.

Adding the new icons to your theme

In order to apply the custom icons to your web page, we first need to copy the generated image sprite file and then add the generated CSS classes from the previous section.

The following generated sprite file has to be added to the images folder of the primefaces-moodyBlue2 custom theme. Let's name the file ui-custom-icons:

After this, copy the generated CSS rules from the previous section.

The first CSS class (ui-icon) contains the image sprite to display custom icons using the background URL property and dimensions such as the width and height properties for each icon. But since we are going to add the image reference in widget state style classes, you need to remove the background image URL property from the ui-icon class. Hence, the ui-icon class contains only the width and height dimensions:

.ui-icon {
  width: 16px;
  height: 16px;
}

Later, modify the icon-specific CSS class names as shown in the following format. Each icon has its own icon name:

.ui-icon-{icon name}

The following CSS classes are used to refer individual icons with the help of the background-position property. Now after modification, the positioning CSS classes will look like this:

.ui-icon-edit { background-position: 0 0; }
.ui-icon-bookmark { background-position: -26px 0; }
.ui-icon-next { background-position: -52px 0; }
.ui-icon-previous { background-position: -78px 0; }
.ui-icon-new { background-position: -104px 0; }
.ui-icon-delete { background-position: -130px 0; }
.ui-icon-refresh { background-position: -156px 0; }
.ui-icon-print { background-position: -182px 0; }
.ui-icon-home { background-position: -208px 0; }
.ui-icon-admin { background-position: -234px 0; }
.ui-icon-contactus { background-position: -260px 0; }

Apart from the preceding CSS classes, we have to add the component state CSS classes. Widget states such as hover, focus, highlight, active, and error need to refer to different image sprites in order to display the component state behavior for user interactions. For demonstration purposes, we created only one image sprite and used it for all the CSS classes. But in real-time development, the image will vary based on the widget state.

The following widget states refer to image sprites for different widget states:

.ui-icon,
.ui-widget-content .ui-icon {
  background-image: url("#{resource['primefaces- 
    moodyblue2:images/ui-custom-icons.png']}");
}

.ui-widget-header .ui-icon {
  background-image: url("#{resource['primefaces- 
    moodyblue2:images/ui-custom-icons.png']}");
}

.ui-state-default .ui-icon {
  background-image: url("#{resource['primefaces- 
    moodyblue2:images/ui-custom-icons.png']}");
}

.ui-state-hover .ui-icon,
.ui-state-focus .ui-icon {
  background-image: url("#{resource['primefaces- 
    moodyblue2:images/ui-custom-icons.png']}");
}

.ui-state-active .ui-icon {
  background-image: url("#{resource['primefaces- 
    moodyblue2:images/ui-custom-icons.png']}");
}

.ui-state-highlight .ui-icon {
  background-image: url("#{resource['primefaces- 
    moodyblue2:images/ui-custom-icons.png']}");
}

.ui-state-error .ui-icon,
.ui-state-error-text .ui-icon {
  background-image: url("#{resource['primefaces- 
    moodyblue2:images/ui-custom-icons.png']}");
}

In the JSF ecosystem, image references in the theme.css file must be converted to an expression that JSF resource loading can understand.

So at first, in the preceding CSS classes, all the image URLs are appeared in the following expression:

background-image: url("images/ui-custom-icons.png");

The preceding expression, when modified, looks like this:

background-image: url("#{resource['primefaces- 
  moodyblue2:images/ui-custom-icons.png']}");

 We need to make sure that the default state classes are commented out in the theme.css (the moodyblue2 theme) file to display the custom icons. By default, custom theme classes (such as the state classes and icon classes available under custom states and images and custom icons positioning) are commented out in the source code of the GitHub project. So, we need to uncomment these sections and comment out the default theme classes (such as the state classes and icon classes available under states and images and positioning). This means that the default or custom style classes only need to be available in the theme.css file.

(OR)

You can see all these changes in moodyblue3 theme as well. The custom icons appeared in Custom Icons screen by just changing the current theme to moodyblue3.

Using custom icons in the commandButton components

After applying the new icons to the theme, you are ready to use them on the PrimeFaces components. In this section, we will add custom icons to command buttons. Let's add a link named Custom Icons to the chaptersTemplate.xhtml file. The title of this page is also named Custom Icons.

The following code snippets show how custom icons are added to command buttons using the icon attribute:

<h3 style="margin-top: 0">Buttons</h3>
<p:commandButton value="Edit" icon="ui-icon-edit" type="button" />
<p:commandButton value="Bookmark" icon="ui-icon-bookmark" 
  type="button" />
<p:commandButton value="Next" icon="ui-icon-next" type="button" />
<p:commandButton value="Previous" icon="ui-icon-previous" 
  type="button" />

Now, run the application and navigate to the newly created page. You should see the custom icons applied to the command buttons, as shown in the following screenshot:

The commandButton component also supports the iconpos attribute if you wish to display the icon either to the left or right side. The default value is left.

Using custom icons in a menu component

In this section, we are going to add custom icons to a menu component. The menuitem tag supports the icon attribute to attach a custom icon.

The following code snippets show how custom icons are added to the menu component:

<h3>Menu</h3>
<p:menu style="margin-left:500px">
  <p:submenu label="File">
    <p:menuitem value="New" url="#" icon="ui-icon-new" />
    <p:menuitem value="Delete" url="#" icon="ui-icon-delete" />
    <p:menuitem value="Refresh" url="#" icon="ui-icon-refresh" />
    <p:menuitem value="Print" url="#" icon="ui-icon-print" />
  </p:submenu>
  <p:submenu label="Navigations">
    <p:menuitem value="Home" url="http://www.primefaces.org" 
      icon="ui-icon-home" />
    <p:menuitem value="Admin" url="#" icon="ui-icon-admin" />
    <p:menuitem value="Contact Us" url="#" icon="ui-icon- 
      contactus" />
  </p:submenu>
</p:menu>

Now, run the application and navigate to the newly created page. You will see the custom icons applied to the menu component, as shown in the following screenshot:

Thus, you can apply custom icons on a PrimeFaces component that supports the icon attribute.

The FontAwesome icons as an alternative to the ThemeRoller icons

In addition to the default ThemeRoller icon set, the PrimeFaces team provided and supported a set of alternative icons named the FontAwesome iconic font and CSS framework. Originally, it was designed for the Twitter Bootstrap frontend framework. Currently, it works well with all frameworks. The official site for the FontAwesome toolkit is http://fortawesome.github.io/Font-Awesome/.

The features of FontAwesome that make it a powerful iconic font and CSS toolkit are as follows:

  • One font, 519 icons: In a single collection, FontAwesome is a pictographic language of web-related actions
  • No JavaScript required: It has minimum compatibility issues because FontAwesome doesn't required JavaScript
  • Infinite scalability: SVG (short for Scalable Vector Graphics) icons look awesome in any size
  • Free to use: It is completely free and can be used for commercial usage
  • CSS control: It's easy to style the icon color, size, shadow, and so on
  • Perfect on retina displays: It looks gorgeous on high resolution displays
  • It can be easily integrated with all frameworks
  • Desktop-friendly
  • Compatible with screen readers

FontAwesome is an extension to Bootstrap by providing various icons based on scalable vector graphics. This FontAwesome feature is available from the PrimeFaces 5.2 release onwards. These icons can be customized in terms of size, color, drop and shadow and so on with the power of CSS.

The full list of icons is available at both the official site of FontAwesome (http://fortawesome.github.io/Font-Awesome/icons/) as well as the PrimeFaces showcase (http://www.primefaces.org/showcase/ui/misc/fa.xhtml).

In order to enable this feature, we have to set primefaces.FONT_AWESOME context param in web.xml to true, as follows:

<context-param>
  <param-name>primefaces.FONT_AWESOME</param-name>
  <param-value>true</param-value>
</context-param>

The usage is as simple as using the standard ThemeRoller icons. PrimeFaces components such as buttons or menu items provide an icon attribute, which accepts an icon from the FontAwesome icon set. Remember that the icons should be prefixed by fa in a component.

The general syntax of the FontAwesome icons will be as follows:

fa fa-[name]-[shape]-[o]-[direction]

Here, [name] is the name of the icon, [shape] is the optional shape of the icon's background (either circle or square), [o] is the optional outlined version of the icon, and [direction] is the direction in which certain icons point.

Now, we first create a new navigation link named FontAwesome under chapter6 inside the chapterTemplate.xhtml template file. Then, we create a JSF template client called fontawesome.xhtml, where it explains the FontAwesome feature with the help of buttons and menu. This page has been added as a menu item for the top-level menu bar.

In the content section, replace the text content with the following code snippets.

The following set of buttons displays the FontAwesome icons with the help of the icon attribute. You may have observed that the fa-fw style class used to set icons at a fixed width. This is useful when variable widths throw off alignment:

<h3 style="margin-top: 0">Buttons</h3>
<p:commandButton value="Edit" icon="fa fa-fw fa-edit" 
  type="button" />
<p:commandButton value="Bookmark" icon="fa fa-fw fa-bookmark" 
  type="button" />
<p:commandButton value="Next" icon="fa fa-fw fa-arrow-right" 
  type="button" />
<p:commandButton value="Previous" icon="fa fa-fw fa-arrow-  left" 
  type="button" />

After this, apply the FontAwesome icons to navigation lists, such as the menu component, to display the icons just to the left of the component text content, as follows:

<h3>Menu</h3>
<p:menu style="margin-left:500px">
  <p:submenu label="File">
    <p:menuitem value="New" url="#" icon="fa fa-plus" />
    <p:menuitem value="Delete" url="#" icon="fa fa-close" />
    <p:menuitem value="Refresh" url="#" icon="fa fa-refresh" />
    <p:menuitem value="Print" url="#" icon="fa fa-print" />
  </p:submenu>
  <p:submenu label="Navigations">
    <p:menuitem value="Home" url="http://www.primefaces.org" 
      icon="fa fa-home" />
    <p:menuitem value="Admin" url="#" icon="fa fa-user" />
    <p:menuitem value="Contact Us" url="#" icon="fa fa- 
      picture-o" />
  </p:submenu>
</p:menu>

Now, run the application and navigate to the newly created page. You should see the FontAwesome icons applied to buttons and menu items, as shown in the following screenshot:

Note that the 40 shiny new icons of FontAwesome are available only in the PrimeFaces Elite 5.2.2 release and the community PrimeFaces 5.3 release because PrimeFaces was upgraded to FontAwesome 4.3 version since its 5.2.2 release.

Summary

In this article, we explored the standard theme icon set and how to use it on various PrimeFaces components. We also learned how to create our own set of icons in the form of the image sprite technology. We saw how to create image sprites using open source online tools and add them on a PrimeFaces theme. Finally, we had a look at the FontAwesome CSS framework, which was introduced as an alternative to the standard ThemeRoller icons. To ensure best practice, we learned how to use icons on commandButton and menu components. Now that you've come to the end of this article, you should be comfortable using web icons for PrimeFaces components in different ways.

Resources for Article:


Further resources on this subject:


You've been reading an excerpt of:

PrimeFaces Theme Development

Explore Title