YUI recommends YUI3.

YUI 2 has been deprecated since 2011. This site acts as an archive for files and documentation.

This documentation is no longer maintained.

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.

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:

  1. <!-- Dependencies -->
  2. <script src="http://yui.yahooapis.com/2.9.0/build/yahoo/yahoo-min.js" ></script>
  3. <script src="http://yui.yahooapis.com/2.9.0/build/stylesheet/stylesheet-min.js"></script>
  4.  
<!-- Dependencies -->
<script src="http://yui.yahooapis.com/2.9.0/build/yahoo/yahoo-min.js" ></script>
<script src="http://yui.yahooapis.com/2.9.0/build/stylesheet/stylesheet-min.js"></script>
 

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. 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.

  1. // These are equivalent; both create new empty StyleSheets
  2. var myStyleSheet = new YAHOO.util.StyleSheet();
  3.  
  4. var myOtherStyleSheet = YAHOO.util.StyleSheet();
  5.  
// These are equivalent; both create new empty StyleSheets
var myStyleSheet = new YAHOO.util.StyleSheet();
 
var myOtherStyleSheet = YAHOO.util.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
  1. <link id="local" type="text/css" rel="stylesheet" href="local_file.css">
  2. <style type="text/css">
  3. .some select.or {
  4. margin-right: 2em;
  5. }
  6. </style>
  7.  
<link id="local" type="text/css" rel="stylesheet" href="local_file.css">
<style type="text/css">
    .some select.or {
        margin-right: 2em;
    }
</style>
 
  1. (function () {
  2.  
  3. // style element or locally sourced link element
  4. var sheet = YAHOO.util.StyleSheet(YAHOO.util.Selector.query('style',null,true));
  5.  
  6. sheet = YAHOO.util.StyleSheet(YAHOO.util.Dom.get('local'));
  7.  
  8.  
  9. // OR the id of a style element or locally sourced link element
  10. sheet = YAHOO.util.StyleSheet('local');
  11.  
  12.  
  13. // OR string of css text
  14. var css = ".moduleX .alert { background: #fcc; font-weight: bold; } " +
  15. ".moduleX .warn { background: #eec; } " +
  16. ".hide_messages .moduleX .alert, " +
  17. ".hide_messages .moduleX .warn { display: none; }";
  18.  
  19. sheet = new YAHOO.util.StyleSheet(css);
  20.  
  21. })();
  22.  
(function () {
 
// style element or locally sourced link element
var sheet = YAHOO.util.StyleSheet(YAHOO.util.Selector.query('style',null,true));
 
sheet = YAHOO.util.StyleSheet(YAHOO.util.Dom.get('local'));
 
 
// OR the id of a style element or locally sourced link element
sheet = YAHOO.util.StyleSheet('local');
 
 
// OR string of css text
var css = ".moduleX .alert { background: #fcc; font-weight: bold; } " +
          ".moduleX .warn  { background: #eec; } " +
          ".hide_messages .moduleX .alert, " +
          ".hide_messages .moduleX .warn { display: none; }";
 
sheet = new YAHOO.util.StyleSheet(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.

  1. <link id="remote" type="text/css" rel="stylesheet" href="http://other.domain.com/remote_file.css">
  2.  
<link id="remote" type="text/css" rel="stylesheet" href="http://other.domain.com/remote_file.css">
 
  1. // ERROR - Same Origin Policy prevents access to remote stylesheets
  2. YAHOO.MyApp.styleSheet = YAHOO.util.StyleSheet('remote');
  3.  
// ERROR - Same Origin Policy prevents access to remote stylesheets
YAHOO.MyApp.styleSheet = YAHOO.util.StyleSheet('remote');
 

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.

  1. var sheetA = YAHOO.util.StyleSheet(YAHOO.util.Dom.get('my_stylesheet'));
  2.  
  3. // Create a registry alias to sheetA. We'll call it bob.
  4. YAHOO.util.StyleSheet.register(sheetA, 'bob');
  5.  
  6. // Create another StyleSheet passing the name as the second parameter
  7. var css = ".some .css { white-space: pre-wrap; color: pink; }";
  8. var sheetB = YAHOO.util.StyleSheet(css, 'my sheet');
  9.  
  10.  
  11. // Meanwhile, elsewhere in your code
  12.  
  13.  
  14. // sheetA is the same instance as sheet1 and sheet2
  15. var sheet1 = YAHOO.util.StyleSheet(YAHOO.util.Dom.get('my_stylesheet')),
  16. sheet2 = YAHOO.util.StyleSheet('bob');
  17.  
  18. // sheetB is the same instance as sheet3
  19. var sheet3 = YAHOO.util.StyleSheet('my sheet');
  20.  
var sheetA = YAHOO.util.StyleSheet(YAHOO.util.Dom.get('my_stylesheet'));
 
// Create a registry alias to sheetA.  We'll call it bob.
YAHOO.util.StyleSheet.register(sheetA, 'bob');
 
// Create another StyleSheet passing the name as the second parameter
var css = ".some .css { white-space: pre-wrap; color: pink; }";
var sheetB = YAHOO.util.StyleSheet(css, 'my sheet');
 
 
// Meanwhile, elsewhere in your code
 
 
// sheetA is the same instance as sheet1 and sheet2
var sheet1 = YAHOO.util.StyleSheet(YAHOO.util.Dom.get('my_stylesheet')),
    sheet2 = YAHOO.util.StyleSheet('bob');
 
// sheetB is the same instance as sheet3
var sheet3 = YAHOO.util.StyleSheet('my sheet');
 

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:

  1. // Whichever of these executes first, an empty StyleSheet will be created
  2. // and registered as 'MyApp'.
  3.  
  4. // In one area of your app
  5. YAHOO.util.StyleSheet('MyApp').set('.module .messages', { display: 'none' });
  6.  
  7. //...
  8.  
  9. // In another area of your app
  10. YAHOO.util.StyleSheet('MyApp').unset('.module .messages','display');
  11.  
// Whichever of these executes first, an empty StyleSheet will be created
// and registered as 'MyApp'.
 
// In one area of your app
YAHOO.util.StyleSheet('MyApp').set('.module .messages', { display: 'none' });
 
//...
 
// In another area of your app
YAHOO.util.StyleSheet('MyApp').unset('.module .messages','display');
 

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.

  1. YAHOO.util.StyleSheet('MyApp').set(".nav li", "font-size: 150%;");
  2.  
  3. YAHOO.util.StyleSheet('MyApp').set(
  4. "q.uoted select.or[str=ing]", {
  5. fontSize : "150%", // note the camel casing
  6. background : "#030 url(/images/bg_image.png) scroll repeat-y top left",
  7. cssFloat : "left",
  8. opacity : 0.5 // this will be normalized for IE
  9. });
  10.  
YAHOO.util.StyleSheet('MyApp').set(".nav li", "font-size: 150%;");
 
YAHOO.util.StyleSheet('MyApp').set(
    "q.uoted select.or[str=ing]", {
        fontSize   : "150%",   // note the camel casing
        background : "#030 url(/images/bg_image.png) scroll repeat-y top left",
        cssFloat   : "left",
        opacity    : 0.5       // this will be normalized for IE
    });
 

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.

  1. // This is valid, but will trigger 3 reflows
  2. YAHOO.util.StyleSheet('MyApp').set(
  3. '.foo, .bar, .baz', {
  4. borderRight: "1em solid #f00"
  5. });
  6.  
// This is valid, but will trigger 3 reflows
YAHOO.util.StyleSheet('MyApp').set(
    '.foo, .bar, .baz', {
        borderRight: "1em solid #f00"
    });
 

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.

  1. // Any of these will work for property:value object syntax
  2. YAHOO.util.StyleSheet('MyApp').set('.foo', {
  3. "float" : "left", // "float" must be quoted
  4. cssFloat : "right",
  5. styleFloat : "none"
  6. });
  7.  
  8. // Only this will work for CSS text syntax
  9. YAHOO.util.StyleSheet('MyApp').set(".foo","float: left;");
  10.  
// Any of these will work for property:value object syntax
YAHOO.util.StyleSheet('MyApp').set('.foo', {
    "float"    : "left",   // "float" must be quoted
    cssFloat   : "right",
    styleFloat : "none"
});
 
// Only this will work for CSS text syntax
YAHOO.util.StyleSheet('MyApp').set(".foo","float: left;");
 

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.

  1. // This will set opacity for W3C browsers, and filter for IE
  2. YAHOO.util.StyleSheet('MyApp').set('.foo', { opacity: 0.5 });
  3.  
  4. // However, this will not be normalized
  5. YAHOO.util.StyleSheet('MyApp').set(".foo","opacity: 0.5;");
  6.  
// This will set opacity for W3C browsers, and filter for IE
YAHOO.util.StyleSheet('MyApp').set('.foo', { opacity: 0.5 });
 
// However, this will not be normalized
YAHOO.util.StyleSheet('MyApp').set(".foo","opacity: 0.5;");
 

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.

  1. YAHOO.util.StyleSheet('MyApp').set('.foo', { background: 'auto' });
  2.  
  3. // is NOT the same as
  4.  
  5. YAHOO.util.StyleSheet('MyApp').unset('.foo','background');
  6.  
YAHOO.util.StyleSheet('MyApp').set('.foo', { background: 'auto' });
 
// is NOT the same as
 
YAHOO.util.StyleSheet('MyApp').unset('.foo','background');
 

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.

  1. // This will not cause a style change in IE 6, for example
  2. YAHOO.util.StyleSheet('MyApp').set('input[type=checkbox]:checked', {
  3. verticalAlign : 'super'
  4. });
  5.  
// This will not cause a style change in IE 6, for example
YAHOO.util.StyleSheet('MyApp').set('input[type=checkbox]:checked', {
    verticalAlign : 'super'
});
 

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.

  1. var sheet = YAHOO.util.StyleSheet(styleNode);
  2.  
  3. sheet.disable();
  4. sheet.set('.foo', { backgroundColor: '#900', color: '#fff' });
  5. sheet.set('.bar', { borderBottomColor: '#369' });
  6. sheet.unset('.baz');
  7. sheet.enable();
  8.  
var sheet = YAHOO.util.StyleSheet(styleNode);
 
sheet.disable();
sheet.set('.foo', { backgroundColor: '#900', color: '#fff' });
sheet.set('.bar', { borderBottomColor: '#369' });
sheet.unset('.baz');
sheet.enable();
 

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:

  1. YAHOO.util.StyleSheet(styleNode).
  2. disable().
  3. set('.foo', { backgroundColor: '#900', color: '#fff' }).
  4. set('.bar', { borderBottomColor: '#369' }).
  5. unset('.baz').
  6. enable();
  7.  
YAHOO.util.StyleSheet(styleNode).
    disable().
    set('.foo', { backgroundColor: '#900', color: '#fff' }).
    set('.bar', { borderBottomColor: '#369' }).
    unset('.baz').
    enable();
 

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.

  1. var el = YAHOO.util.Dom.get('some_element'),
  2. changes = { color : '#684', fontWeight: 'bold', padding: '2em' },
  3. currentStyle = YAHOO.util.Dom.getStyle(el, 'cssText');
  4.  
  5. YAHOO.util.Dom.setStyle(el,'cssText',
  6. YAHOO.util.StyleSheet.toCssText(changes, currentStyle));
  7.  
var el           = YAHOO.util.Dom.get('some_element'),
    changes      = { color : '#684', fontWeight: 'bold', padding: '2em' },
    currentStyle = YAHOO.util.Dom.getStyle(el, 'cssText');
 
YAHOO.util.Dom.setStyle(el,'cssText',
    YAHOO.util.StyleSheet.toCssText(changes, currentStyle));
 

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.

  1. /* | This is a CSS rule |
  2.   | selectorText | style properties | */
  3. div.this-is a .rule { font-color: #f00; }
  4.  
/* |            This is a CSS rule          |
   |    selectorText    |  style properties | */
   div.this-is a .rule  { font-color: #f00; }
 

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.

  1. var el = YAHOO.util.Dom.get('some_element');
  2.  
  3. el.style.borderBottom = '3px solid #eee'; // reflow
  4. el.style.borderTop = '3px solid #ccc'; // another reflow
  5. el.style.fontWeight = 'bold'; // another reflow
  6.  
  7. // Vs. three changes in one reflow
  8. el.style.cssText += '; border-bottom: 3px solid #eee; border-top: 3px solid #ccc; font-weight: bold';
  9.  
var el = YAHOO.util.Dom.get('some_element');
 
el.style.borderBottom = '3px solid #eee'; // reflow
el.style.borderTop    = '3px solid #ccc'; // another reflow
el.style.fontWeight   = 'bold';           // another reflow
 
// Vs. three changes in one reflow
el.style.cssText += '; border-bottom: 3px solid #eee; border-top: 3px solid #ccc; font-weight: bold';
 

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.

  1. // If getElementsByClassName finds 10 nodes, the browser will trigger
  2. // 10 repaints and 20 reflows
  3. YAHOO.util.Dom.getElementsByClassName('change-me','*','root',
  4. function (el) {
  5. YAHOO.util.Dom.setStyle(el,'color','#f00');
  6. YAHOO.util.Dom.setStyle(el,'fontWeight','bold');
  7. YAHOO.util.Dom.setStyle(el,'borderBottom','3px solid #f00');
  8. }
  9. )
  10.  
  11. // StyleSheet equivalent. This will trigger one reflow
  12. myStyleSheet.set('#root .change-me', {
  13. color : '#f00',
  14. fontWeight : 'bold',
  15. borderBottom : '3px solid #f00'
  16. });
  17.  
   // If getElementsByClassName finds 10 nodes, the browser will trigger
   // 10 repaints and 20 reflows
   YAHOO.util.Dom.getElementsByClassName('change-me','*','root',
      function (el) {
          YAHOO.util.Dom.setStyle(el,'color','#f00');
          YAHOO.util.Dom.setStyle(el,'fontWeight','bold');
          YAHOO.util.Dom.setStyle(el,'borderBottom','3px solid #f00');
      }
   )
 
   // StyleSheet equivalent.  This will trigger one reflow
   myStyleSheet.set('#root .change-me', {
      color        : '#f00',
      fontWeight   : 'bold',
      borderBottom : '3px solid #f00'
  });
 

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.

StyleSheet Utility Examples:

YUI StyleSheet Utility on del.icio.us:

bookmark on del.icio.us

be the first to bookmark this page!

Copyright © 2013 Yahoo! Inc. All rights reserved.

Privacy Policy - Copyright Policy - Job Openings