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.
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.
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:
<!-- 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>
<!-- 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>
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.
This section will address how to create and use YAHOO.util.StyleSheet instances and includes:
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.
// These are equivalent; both create new empty StyleSheets var myStyleSheet = new YAHOO.util.StyleSheet(); var myOtherStyleSheet = YAHOO.util.StyleSheet();
// 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:
<style>
or <link>
node reference,<style>
or <link>
node, or
<link id="local" type="text/css" rel="stylesheet" href="local_file.css"> <style type="text/css"> .some select.or { margin-right: 2em; } </style>
<link id="local" type="text/css" rel="stylesheet" href="local_file.css"> <style type="text/css"> .some select.or { margin-right: 2em; } </style>
(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); })();
(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 href
s pointing to other domains. Attempts to seed a YAHOO.util.StyleSheet
instance with a cross-domain <link>
will result in a security error.
<link id="remote" type="text/css" rel="stylesheet" href="http://other.domain.com/remote_file.css">
<link id="remote" type="text/css" rel="stylesheet" href="http://other.domain.com/remote_file.css">
// ERROR - Same Origin Policy prevents access to remote stylesheets YAHOO.MyApp.styleSheet = YAHOO.util.StyleSheet('remote');
// ERROR - Same Origin Policy prevents access to remote stylesheets YAHOO.MyApp.styleSheet = YAHOO.util.StyleSheet('remote');
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.
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');
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:
// 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');
// 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');
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:
<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.cssText
.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.
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 });
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.
// This is valid, but will trigger 3 reflows YAHOO.util.StyleSheet('MyApp').set( '.foo, .bar, .baz', { borderRight: "1em solid #f00" });
// This is valid, but will trigger 3 reflows YAHOO.util.StyleSheet('MyApp').set( '.foo, .bar, .baz', { borderRight: "1em solid #f00" });
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.
// 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;");
// 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
.
// 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;");
// 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;");
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 entirelyunset('.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.
YAHOO.util.StyleSheet('MyApp').set('.foo', { background: 'auto' }); // is NOT the same as YAHOO.util.StyleSheet('MyApp').unset('.foo','background');
YAHOO.util.StyleSheet('MyApp').set('.foo', { background: 'auto' }); // is NOT the same as YAHOO.util.StyleSheet('MyApp').unset('.foo','background');
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.
// This will not cause a style change in IE 6, for example YAHOO.util.StyleSheet('MyApp').set('input[type=checkbox]:checked', { verticalAlign : 'super' });
// This will not cause a style change in IE 6, for example YAHOO.util.StyleSheet('MyApp').set('input[type=checkbox]:checked', { verticalAlign : 'super' });
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
.
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();
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();
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:
YAHOO.util.StyleSheet(styleNode). disable(). set('.foo', { backgroundColor: '#900', color: '#fff' }). set('.bar', { borderBottomColor: '#369' }). unset('.baz'). enable();
YAHOO.util.StyleSheet(styleNode). disable(). set('.foo', { backgroundColor: '#900', color: '#fff' }). set('.bar', { borderBottomColor: '#369' }). unset('.baz'). enable();
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.
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));
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));
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.
/* | This is a CSS rule | | selectorText | style properties | */ div.this-is a .rule { font-color: #f00; }
/* | 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.
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';
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.
// 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' });
// 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' });
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:
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:
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.
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.
be the first to bookmark this page!
All YUI 2.x users should review the YUI 2.8.2 security bulletin, which discusses a vulnerability present in YUI 2.4.0-2.8.1.
Copyright © 2013 Yahoo! Inc. All rights reserved.