Styling Buttons and Toolbars with the jQuery UI CSS Framework

By popular demand: coded real-world examples of themeable buttons and toolbars using the jQuery UI CSS framework, a system of classes developed for jQuery UI widgets that can easily be applied to any plugin, and even static content.

We got lots of requests in jQuery UI discussion groups for ThemeRoller-ready buttons when we launched our most recent version of ThemeRoller, so we’ve created some button examples here that demonstrate how to incorporate the power of the CSS framework classes in a custom widget.

Below, we create a range of button types that frequently appear in application interfaces — stand-alone buttons, toggles, and buttons grouped into multi-function toolbars — and use classes from the framework to demonstrate how you can leverage the CSS for non-jQuery elements. We tested the sample markup and the framework CSS to ensure that styles render the same whether the button markup is the actual button form element (<button>), a link (<a>), or any other tag that makes sense for your particular application.

Examples

Click the gray button in the top right corner to apply a different theme:

Demo page

Built on the jQuery UI CSS Framework

In January the jQuery UI team rolled out a new jQuery UI CSS framework which provides a set of semantic classes that can be applied across a wide range of UI widgets. The framework works by stacking multiple classes on an element, some generic to the framework and others that are custom to each widget.

The generic framework classes fall into four basic types:

  • Interaction role classes - define the style attributes that affect look and feel: background image and colors for fonts, icons and borders. These classes are commonly used in many interfaces to style the header, content, click/mouseover states, error and highlight states. [Note: This is the part of the framework that corresponds to the primary levers that define a unique “theme” created in ThemeRoller.]
  • Rounded corner classes - apply rules for CSS3 corner-radius that match the radius set in the selected theme. There are individual class names for adding rounded corners to all four corners or just top, bottom, left, right or one specific corner. This CSS property is not supported in IE or Opera so these browsers will be square corners until they include support.
  • Interaction cue classes - make any element disabled or adjust the visual weight by tagging it as primary or secondary. All of these use opacity and font-weight shifts to leave the theme colors intact.
  • Helper classes - don’t effect the visual design but are used to hide the element, add a clearfix, z-index fix or css reset to an element.

And finally, to style the widgets for a specific layout, we add our own unique set of custom classes:

  • Widget-specific classes - add structural style rules such as padding, margins, dimensions and floats that make the various components of a widget work together in a layout. These classes should never contain styles that apply colors or background images because these will override the interaction role classes and interfere with theming.

Note: Widget-specific classes classes are not included in the jQuery UI CSS framework; you add them to customize your layout by either appending them to the class attribute (next to framework classes), or for scoping framework classes to a specific element. In our examples, widget-specific classes all begin with “fg-”, and framework classes begin with “ui-”.

It’s important to note that you can use framework classes on any site or with any scripting library — all you need is the /theme/ folder created by ThemeRoller and a link to the ui.all.css stylesheet in your page to use the framework. We feel that adding a bit of scripting adds a lot of power, as you’ll see in this article, so we’ll be using jQuery in our examples, but these styles are very “portable” and can be used anywhere.

Creating a basic button

Creating a basic button is very simple with the jQuery UI CSS framework. Let’s say we start with a simple button or a link that needs to by styled as a button:

<button type="submit">Button</button>
<a href="#">Link</a>

To style these to look like a button, all you need to do is add the default “clickable” state by assigning the class ui-state-default. We also want these to have rounded corners, so we added the optional ui-corner-all framework class which adds CSS3 corner-radius properties to all corners without the need for any images or extra markup. [Note: this technique only works in Firefox and Safari, IE will display square corners unless you use a corner extension script]

<button class="ui-state-default ui-corner-all" type="submit">Button</button>
<a href="#" class="ui-state-default ui-corner-all">Link</a>

To globally control styling across all our buttons and add behavior later with Javascript, we also created a widget-specific class that isn’t part of the UI CSS framework called fg-button.

<button class="fg-button ui-state-default ui-corner-all" type="submit">Button</button>
<a href="#" class="fg-button ui-state-default ui-corner-all">Link</a>

The jQuery UI CSS framework classes only apply look and feel style rules so our new fg-button class adds styles for margin, padding, positioning and other rules that make our new button widget look good in a particular layout. It’s important to never specify any of the framework style attributes (like colors and background images) in your widget styles because these will override the theme styles. Your widget-specific styles and the framework styles should be written carefully to work together and so your widget will be themable. Here are the style rules for our fg-button:

.fg-button {
   outline: 0;
   margin:0 4px 0 0;
   padding: .4em 1em;
   text-decoration:none !important;
   cursor:pointer;
   position: relative;
   text-align: center;
   zoom: 1;
   }

Scripting the hover and click states

At this point, we have styled buttons that look great and work on a range of html elements — buttons, links, spans, etc. The only missing part is visual feedback for rollover and click. These effects can be easily added by swapping the interaction role ui-state-default class with ui-state-hover on mouseover with some very simple jQuery scripting. We can add similar scripts to swap the class of a button to ui-state-active when clicked.

.hover(
    function(){
        $(this).addClass("ui-state-hover");
    },
    function(){
        $(this).removeClass("ui-state-hover");
    }
)

Setting button priority

Buttons in a typical user interface may need to be emphasized or de-emphasized to show priority. For example, in a dialog, you may want to visually emphasize the default button (Save) and de-emphasize the secondary button (Cancel). The CSS framework has interaction cue classes to set the priority to primary (ui-priority-primary) and secondary (ui-priority-secondary), which take the core theme color and backgrounds style attributes and automatically apply visual weight: primary priority sets the font weight to bold and the button to full color saturation; and secondary sets the button opacity to 70% to make it look a bit lower contrast than the primary button, and sets the font weight to normal.

<button class="fg-button ui-state-default ui-priority-primary ui-corner-all">Primary</button>
<button class="fg-button ui-state-default ui-priority-secondary ui-corner-all">Secondary</button>

Disabling buttons

The jQuery UI CSS framework also includes a disabled state class that prevents an element from appearing clickable and sets the opacity to 35%. By using opacity, the framework preserves the theme styling for the button but makes it appear to be dimmed out and unclickable. To make a button disabled, apply the ui-state-disabled class.

<button class="fg-button ui-state-default ui-state-disabled ui-corner-all">Disabled button</button>

Adding icons to buttons

Included in the CSS framework is a full icon sprite containing a large set of commonly used icons. This set is colorized for each interaction state so icons can change color when hovered and clicked. Adding icons is easy — just add a span with a class of ui-icon which sets the icon dimensions to 16px. Then, apply a second class which name of the icon you’d like to use — for example, for a button with a “+” icon inside, you would use ui-icon-circle-plus. [Note: To see the full list of icons available, scroll to the bottom of the ThemeRoller page and hover over an icon to see its class name.]

<a href="#" class="fg-button fg-button-icon-left ui-state-default ui-corner-all"><span class="ui-icon ui-icon-circle-plus"></span>button</a>

In our examples we decided to show icons by themselves in a button or floated left or right next to a text label, so we created a set of widget-specific classes to handle the styling in these cases. For buttons with icons and text, we used fg-button-icon-left or fg-button-icon-right; and for buttons with an icon alone, we used the fg-button-icon-solo class.

Grouping buttons

Buttons are commonly grouped together visually in an interface. We created a widget-specific container class called fg-buttonset that we could apply to a set of buttons to logically group them together. This grouping container is used primarily as a way for us to apply floats and margins to the button set, but is also used to associate buttons that have shared behavior such as toggle and single select groups.

<div class="fg-buttonset">
   buttons go here...
</div>

Toggle Buttons and Toggle Groups

We created a set of grouped buttons that toggle to an active state when clicked by adding the widget-specific class fg-button-toggleable to buttons we wanted to toggle on and off. An example of this grouped multiple-toggle button is the bold, italic and underline formatting buttons in a word processor. To create this effect, we wrapped the buttons in a fg-buttonset container and attached an additional style of fg-buttonset-multi which added additional style rules and scripting to make the buttons look visually connected and individually toggle.

<div class="fg-buttonset fg-buttonset-multi">
    <button class="fg-button ui-state-default ui-corner-left"><b>B</b></button>
    <button class="fg-button ui-state-default"><i>I</i></button>
    <button class="fg-button ui-state-default  ui-corner-right"><u>U</u></button>
</div>

Single Select Buttons Groups

We also wanted to show how to allow one button to be selected at a time, so we created a class called fg-buttonset-single which adds a few style rules and scripting to apply the framework ui-state-active class to only one button at a time in the set. This acts like a radio button and is used for mutually exclusive options, like the text alignment options (left, center, right, justified) in a word processor.

<div class="fg-buttonset fg-buttonset-single">
    <button class="fg-button ui-state-default ui-priority-primary ui-corner-left">Visual</button>
    <button class="fg-button ui-state-default ui-priority-primary">Code</button>
    <button class="fg-button ui-state-default ui-priority-primary">Split</button>
    <button class="fg-button ui-state-default ui-priority-primary ui-corner-right">Preview</button>
</div>

Making a Toolbar

By taking a number of buttons organized into groups and placing them into a container with the CSS framework class ui-widget-header and a widget-specific class fg-toolbar, we can easily create a toolbar. The ui-widget-header class sets the toolbar borders and background texture and the fg-toolbar class adds a few rules to set padding, font sizes and margins:

.fg-toolbar { padding: .5em; margin: 0; width:50%; }
.fg-toolbar .fg-buttonset { margin-right:1.5em; padding-left: 1px; }
.fg-toolbar .fg-button { font-size: 1em;  }

Advantages of using this button technique

These buttons have a lot of advantages over traditional image-based buttons:

  • Clean, semantic markup - this technique will work with standard button and link elements with no additional spans or extra markup.
  • Scalable sizing - buttons gracefully adjust in size to accommodate changing font sizes and text that wraps to multiple lines.
  • Fewer background images - a single background image is used for each interaction state across the whole application (compared to sliding door buttons, for example, which require two or more images per button type).
  • Icon sprite set - the framework includes an extensive set of icons in a fast-loading sprite that can be used freely on any project.
  • Compatible with all modern browsers - tested in Internet Explorer 6 & 7, Firefox 2 & 3 (Mac & PC), Safari 3 and Opera 9.

Known Issues

For buttons that only contain an icon and no text label, you must either float or position the button to work in Firefox 2.

All blog posts