Developer Network Home - Help

YUI 2: StyleSheet Utility

YUI 2: StyleSheet Utility

The StyleSheet Utility allows you to create and modify CSS stylesheets on the fly.

StyleSheet addresses the need to apply style or style changes to multiple elements without incurring the cost of a page reflow for each element. In some cases, it is inefficient or impossible to support the range of styles for a set of elements using a regular CSS file. Additionally, if the number of elements needing style modification is large, the processing overhead involved with looping through elements in the DOM to apply these changes can be harmful to the user experience. In these situations, the cleanest and most efficient way to update the elements' style is using dynamic CSS. The StyleSheet Utility fills this gap.

The StyleSheet Utility is capable of creating new stylesheets from scratch as well as modifying the existing stylesheets held as properties of <link> elements sourced from the same domain or any inline <style> elements . Due to security restrictions, <link> elements sourced from different domains are inaccessible.

Note: The StyleSheet Utility is being released as a beta component. Please refer to the FAQ for what we mean by this designation. We look forward to your feedback in the YUI Forums.

Getting Started

The StyleSheet Utility's only dependency is the Yahoo Global Object. To use the StyleSheet Utility, include the following source files in your web page:

YUI dependency configurator.

YUI Dependency Configurator:

Instead of copying and pasting the filepaths above, try letting the YUI dependency Configurator determine the optimal file list for your desired components; the Configurator uses YUI Loader to write out the full HTML for including the precise files you need for your implementation.

Note: If you wish to include this component via the YUI Loader, its module name is stylesheet. (Click here for the full list of module names for YUI Loader.)

Where these files come from: The files included using the text above will be served from Yahoo! servers; see "Serving YUI Files from Yahoo!" for important information about this service. JavaScript files are minified, meaning that comments and white space have been removed to make them more efficient to download. To use the full, commented versions or the -debug versions of YUI JavaScript files, please download the library distribution and host the files on your own server.

Order matters: As is the case generally with JavaScript and CSS, order matters; these files should be included in the order specified above. If you include files in the wrong order, errors may result.

Using the StyleSheet Utility

This section will address how to create and use YAHOO.util.StyleSheet instances and includes:

Instantiating a YAHOO.util.StyleSheet

The YAHOO.util.StyleSheet constructor is written to support both function syntax and normal constructor syntax making the new prefix unnecessary, but harmless.

The constructor has no required parameters. Passing no arguments will create a new empty StyleSheet.

To seed a new StyleSheet with a number of CSS rules, you can pass the constructor any of the following:

  1. a <style> or <link> node reference,
  2. the id of a <style> or <link> node, or
  3. a string of CSS

Be aware that the Same Origin policy prevents access to the style data of <link> elements with hrefs pointing to other domains. Attempts to seed a YAHOO.util.StyleSheet instance with a cross-domain <link> will result in a security error.

Getting a StyleSheet by registered name

YAHOO.util.StyleSheet supports registering instances by name allowing them to be recalled by that same name elsewhere in your code. Internally YAHOO.util.StyleSheet maintains a registry of all created StyleSheet instances, using a unique generated id that the host node is tagged with. This allows future attempts to create a StyleSheet instance from the same node to return the previously created instance associated with that id.

Register a StyleSheet instance manually using the static register method or pass the desired name as a second parameter to the constructor.

If an unregistered name is passed as the first argument to the constructor, a new empty StyleSheet will be created and registered with that name. This allows you to use the following code pattern:

Summary of how the constructor handles the first argument

When nothing is passed as the first argument, a new StyleSheet instance is created.

When a <style> or <link> element is passed as the first argument, it is inspected for the id stamp that StyleSheet tags known host nodes with. If it finds one, it will return the associated StyleSheet from the registry. If not, it will stamp the node and seed the instance from the node's CSS content.

When a string is passed as the first argument, StyleSheet does the following things in order:

  1. Check the registry for an instance associated to that name. If found, return the instance.
  2. Check the DOM for a <style> or <link> node with that id. If found, check the registry for an instance associated to its tagged id if present. If found, return that instance. If not, use that node to seed a new StyleSheet instance.
  3. Check the string for a curly brace { character. If found, create a new instance seeded with the string as initial cssText.
  4. Create a new empty StyleSheet and register the instance by the provided string

Creating and modifying CSS style rules

The core method of StyleSheet instances is set(selector, style_properties). It will create or alter a CSS rule using the property:value pairs in style_property targeting the provided selector. Pass either a string of CSS text or an object of property:value pairs for style_properties. In essence, it looks very much like natural CSS syntax.

Note that if you use the string form of style_properties no opacity normalization will be applied. If you use the object form of style_properties, the properties must be in JavaScript's camelCase, but opacity will be normalized.

Rather than continually add new rules that will override one another, StyleSheet manages one rule per selector and modifies them in place. This may be relevant if you have two or more rules with selectors of the same specificity.

As with regular CSS syntax, comma separated selectors are supported, but internally StyleSheet splits them up into individual rules because browser support for multiple selectors is not consistent. This means calling set(..) with such a selector string will incur multiple repaints or reflows, but limited to the number of atomic selectors.

Some style properties are normalized

Two style properties have differing implementation between browsers, namely float and opacity.

Because "float" is a reserved word in JavaScript, it is supported by the name cssFloat in W3C compliant browsers, and styleFloat in IE. StyleSheet will accept any of these to set the float property.

IE does not support the opacity style property, but has equivalent functionality offered by its proprietary filter property. StyleSheet will translate opacity to filter for IE if you use the property:value object syntax for set.

Removing and resetting CSS style rules

When you want to remove a particular rule or style property from effecting the cascade, use unset(selector,propert[y|ies]).

unset(..) can be called in any of the following ways, with the noted result:

  • unset('.foo') - removes the rule associated to the selector entirely
  • unset('.foo','font') - unsets the font property and any child properties (e.g. 'font-weight','font-variant','font-size','line-height', and 'font-family'). If there are no set properties left, the rule is removed.
  • unset('.foo',['font','border',...]) - same as above, but the rule is modified only once with the final applicable cssText.

It is important to note that there is a difference between setting a style property to its default value and unsetting it. The former can be achieved by calling set(selector, { property: "auto" }) (or the respective default value for that property).

However, as the CSS is reapplied to the page, the "auto" value will override any value for that property that may have cascaded in from another rule. This is different than removing the property assignment entirely, as this allows cascading values through.

A note on selector strings

Though the StyleSheet Utility takes selector strings as input to its API, it does not leverage YAHOO.util.Selector. The Selector Utility supplements native CSS support for DOM access, but accomplishes this through efficient DOM traversal. Since the StyleSheet Utility uses the browser's built-in stylesheet and rule objects, it can not handle selectors that are not supported by the browser's native CSS parser.

Disabling and enabling a StyleSheet

Disabling a StyleSheet effectively turns it off; no CSS from that stylesheet is applied to the page. Disabling a StyleSheet does not remove the host node from the page, and style can be reapplied by enabling the StyleSheet again.

When StyleSheets are disabled, it is still possible to change their style rules via set and unset.

Support for method chaining

All instance methods except getId and getCssText return the StyleSheet instance, allowing for method chaining. So the code snippet above could instead be written like this:

Static methods

YAHOO.util.StyleSheet exposes a few static methods.

Method Use for
register(instance, name) Use to assign a named registry entry for a StyleSheet instance.
toCssText(property_obj, starting_cssText) Use to translate an object of style property:value pairs to a single cssText string. The optional second argument is a cssText string of a style's "before" state.

YAHOO.util.StyleSheet.toCssText is used internally to assemble the cssText strings for updating the stylesheet rules. However, it may also be helpful for avoiding reflow overhead when substantially modifying a single element's style.

How YAHOO.util.StyleSheet works

Browsers grant access via the DOM API to stylesheets included in markup as <link> or <style> elements. Despite differing implementations across the browser spectrum, they all support adding, removing, and modifying CSS rules.

CSS rules are comprised of a selector and collection of style property:value pairs enclosed in curly braces.

In JavaScript, each rule object has a selectorText property and a style property that operates in the same way as the style property on regular DOM elements, such as <p> or <strong> elements.

Arguably the most valuable property of the style collection is cssText which corresponds to the serialized summary of property:value pairs applied by this collection (e.g. "font-size: 100%; color: #FF0000;"). The reason this property is important is that modifications to the string value will cause changes to repopulate the individual style properties while only triggering a single repaint or reflow by the browser.

YAHOO.util.StyleSheet leverages this mechanism in addition to applying modifications at the CSS rule level rather than modifying each targeted DOM node directly. This means changing multiple style properties on multiple elements (that can be identified by a single selector) will only ever incur one repaint or reflow.

YUI on Mobile: Using StyleSheet Utility with "A-Grade" Mobile Browsers

About this Section: YUI generally works well with mobile browsers that are based on A-Grade browser foundations. For example, Nokia's N-series phones, including the N95, use a browser based on Webkit — the same foundation shared by Apple's Safari browser, which is found on the iPhone. The fundamental challenges in developing for this emerging class of full, A-Grade-derived browsers on handheld devices are:

  • Screen size: You have a much smaller canvas;
  • Input devices: Mobile devices generally do not have mouse input, and therefore are missing some or all mouse events (like mouseover);
  • Processor power: Mobile devices have slower processors that can more easily be saturated by JavaScript and DOM interactions — and processor usage affects things like battery life in ways that don't have analogues in desktop browsers;
  • Latency: Most mobile devices have a much higher latency on the network than do terrestrially networked PCs; this can make pages with many script, css or other types of external files load much more slowly.

There are other considerations, many of them device/browser specific (for example, current versions of the iPhone's Safari browser do not support Flash). The goal of these sections on YUI User's Guides is to provide you some preliminary insights about how specific components perform on this emerging class of mobile devices. Although we have not done exhaustive testing, and although these browsers are revving quickly and present a moving target, our goal is to provide some early, provisional advice to help you get started as you contemplate how your YUI-based application will render in the mobile world.

More Information:

Support & Community

The YUI Library and related topics are discussed on the on the YUILibrary.com forums.

Also be sure to check out YUIBlog for updates and articles about the YUI Library written by the library's developers.

Filing Bugs & Feature Requests

The YUI Library's public bug tracking and feature request repositories are located on the YUILibrary.com site. Before filing new feature requests or bug reports, please review our reporting guidelines.

Copyright © 2009 Yahoo! Inc. All rights reserved.

Privacy Policy - Terms of Service - Copyright Policy - Job Openings