index.mustache revision daa301d2a0f17b5c1b04d777de3acf969b9b63d2
a4544a5a0e622ef69e38641f87ab1b5685e05911Phill Cunnington<div class="intro component">
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster The StyleSheet module normalizes the dynamic creation and modification
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster of CSS stylesheets on a page. This makes it easy to manage the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster development, storage, and reapplication of personalized user
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster stylesheets. Because it targets styles at the CSS level, it also
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster allows you to modify styles applied to a CSS pseudo-element such as
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>p::first-letter</code>, or pseudo-class such as
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>a:hover</code>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster StyleSheet is capable of creating new stylesheets from scratch or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modifying existing stylesheets held as properties of
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code><link></code> or <code><style></code> elements. It
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster should be noted that not all browsers support reading or modifying
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster external stylesheets from other domains.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster{{>getting-started}}
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h2 id="using">Using the StyleSheet Utility</h2>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h3 id="instantiating">Instantiating a <code>Y.StyleSheet</code></h3>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster The <code>Y.StyleSheet</code> constructor is written to support both
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster function syntax and normal constructor syntax making the <code>new</code>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster prefix unnecessary (but harmless).
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster The constructor has no required parameters. Passing no arguments will
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster create a new, empty StyleSheet instance.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// These are equivalent; both create new empty StyleSheets
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervar myStyleSheet = new Y.StyleSheet();
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottvar myOtherStyleSheet = Y.StyleSheet();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster To seed a new StyleSheet with a number of CSS rules, you can pass the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster constructor any of the following:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster a <code><style></code> or <code><link></code> node
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster the id of a <code><style></code> or <code><link></code>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <li>a string of CSS</li>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott<link id="local" type="text/css" rel="stylesheet" href="local_file.css">
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott<style id="styleblock" type="text/css">
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster margin-right: 2em;
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterYUI().use('node','stylesheet', function (Y) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // Node or HTMLElement reference for a style or locally sourced link element
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster var sheet = Y.StyleSheet(Y.one("#styleblock"));
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott // OR the id of a style element or locally sourced link element
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott sheet = Y.StyleSheet('#local');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster // OR string of css text
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster var css = ".moduleX .alert { background: #fcc; font-weight: bold; } " +
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott ".moduleX .warn { background: #eec; } " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ".hide_messages .moduleX .alert, " +
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster ".hide_messages .moduleX .warn { display: none; }";
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott sheet = new Y.StyleSheet(css);
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Be aware that the <a
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford href="http://en.wikipedia.org/wiki/Same_origin_policy">Same Origin
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster policy</a> prevents access in some browsers to the style data of
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code><link></code> elements with <code>href</code>s pointing to
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster other domains. Attempts to seed a <code>Y.StyleSheet</code> instance with
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster a cross-domain <code><link></code> may result in a security
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<link id="remote" type="text/css" rel="stylesheet" href="http://other.domain.com/remote_file.css">
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// ERROR - Same Origin Policy prevents access to remote stylesheets
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervar styleSheet = Y.StyleSheet('remote');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h3 id="registry">Getting a StyleSheet by registered name</h3>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>Y.StyleSheet</code> supports registering instances by name allowing
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster them to be recalled by that same name elsewhere in your code. Internally,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>Y.StyleSheet</code> maintains a registry of all created StyleSheet
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster instances, using a unique generated id that the host node is tagged with.
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott This allows future attempts to create a StyleSheet instance from the same
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster node to return the previously created instance associated with that id.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Register a StyleSheet instance manually using the static
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>register</code> method or pass the desired name as a second parameter
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster to the constructor.
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottvar sheetA = Y.StyleSheet('my_stylesheet');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// Create a registry alias to sheetA. We'll call it bob.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// Create another StyleSheet passing the name as the second parameter
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottvar css = ".some .css { white-space: pre-wrap; color: pink; }";
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottvar sheetB = Y.StyleSheet(css, 'my sheet');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// Meanwhile, elsewhere in your code
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// sheetA is the same instance as sheet1 and sheet2
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervar sheet1 = Y.StyleSheet(Y.one('#my_stylesheet')),
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford sheet2 = Y.StyleSheet('bob');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// sheetB is the same instance as sheet3
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervar sheet3 = Y.StyleSheet('my sheet');
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott If an unregistered name is passed as the <em>first</em> argument to the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster constructor, a new empty StyleSheet will be created and registered with
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster that name. This allows you to use the following code pattern:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// Whichever of these executes first, an empty StyleSheet will be created
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// and registered as 'MyApp'.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// In one area of your app
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterY.StyleSheet('MyApp').set('.module .messages', { display: 'none' });
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford// In another area of your app
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterY.StyleSheet('MyApp').unset('.module .messages','display');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h3 id="first_param">Summary of how the constructor handles the first argument</h3>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott When nothing is passed as the first argument, a new StyleSheet instance is
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster When a <code><style></code> or <code><link></code> element is
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster passed as the first argument, it is inspected for the id stamp that
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott StyleSheet tags known host nodes with. If it finds one, it will return the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster associated StyleSheet from the registry. If not, it will stamp the node
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster and seed the instance from the node's CSS content.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster When a string is passed as the first argument, StyleSheet does the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster following things in order:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Check the registry for an instance associated to that name. If found,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster return the instance.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford Check the DOM for a <code><style></code> or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code><link></code> node with that id. If found, check the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster registry for an instance associated to its tagged id if present. If
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster found, return that instance. If not, use that node to seed a new
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster StyleSheet instance.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Check the string for a curly brace { character. If found, create a new
4dc32d1e92477080fa1652a865cadc3f63ae04edBrian Bailey instance seeded with the string as initial <code>cssText</code>.
4dc32d1e92477080fa1652a865cadc3f63ae04edBrian Bailey Create a new empty StyleSheet and register the instance by the provided
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h3 id="set">Creating and modifying CSS style rules</h3>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster The core method of StyleSheet instances is <code>set(selector,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster style_properties)</code>. It will create or alter a CSS rule using the
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford property:value pairs in <code>style_properties</code> targeting the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster provided <code>selector</code>. In essence, it looks very much like
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster natural CSS syntax, <em>except style properties must be in JavaScript's
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster camelCase</em>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster fontSize : "150%", // note the camel casing
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott background : "#030 url(/images/bg_image.png) scroll repeat-y top left",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cssFloat : "left",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster opacity : 0.5
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Rather than continually add new rules that will override one another,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster StyleSheet manages one rule per selector and modifies them in place. This
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster may be relevant if you have two or more rules with selectors of the same
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster specificity.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford As with regular CSS syntax, comma-separated selectors are supported, but
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster internally StyleSheet splits them up into individual rules because browser
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster support for multiple selectors is not consistent. This means calling
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>set(..)</code> with such a selector string <em>will incur multiple
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster repaints or reflows</em>, but limited to the number of atomic
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// This is valid, but will trigger 3 reflows
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster '.foo, .bar, .baz', {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster borderRight: "1em solid #f00"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h3 id="normalized_properties">Some style properties are normalized</h3>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Two style properties have differing implementation between browsers, namely
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>float</code> and <code>opacity</code>. StyleSheet instances will
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster normalize these properties for you.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Because "float" is a reserved word in JavaScript, it is supported
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford by the name <code>cssFloat</code> in W3C compliant browsers and
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>styleFloat</code> in IE. StyleSheet will accept any of these to set
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster the <code>float</code> property.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// Any of these will work
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterY.StyleSheet('MyApp').set('.foo', {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "float" : "left", // "float" must be quoted
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster cssFloat : "right",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster styleFloat : "none"
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster IE does not support the <code>opacity</code> style property, but has
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster equivalent functionality offered by its proprietary <code>filter</code>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster property, though using a different value syntax. StyleSheet will translate
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>opacity</code> to <code>filter</code> for IE, but it <em>will
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster not</em> translate <code>filter</code> to <code>opacity</code> for
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster W3C-compliant browsers.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h3 id="unset">Removing and resetting CSS style rules</h3>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster When you want to remove a particular rule or style property from affecting
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster the cascade, use <code>unset(selector,propert[y|ies])</code>.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford <code>unset(..)</code> can be called in any of the following ways, with the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster noted result:
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>unset('.foo')</code> — removes the rule associated to the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster selector entirely.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>unset('.foo','font')</code> — unsets the <code>font</code>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster property and any child properties (e.g.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster 'font-weight','font-variant','font-size','line-height', and
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster 'font-family'). If there are no set properties left, the rule is
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford <code>unset('.foo',['font','border',...])</code> — same as above,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster but the rule is modified only once with the final applicable
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>cssText</code>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster It is important to note that there is a difference between setting a style
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott property to its default value and unsetting it. The former can be achieved
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster by calling <code>set(selector, { property: "auto" })</code> (or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster the respective default value for that property).
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster However, as the CSS is reapplied to the page, the "auto" value
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster will override any value for that property that may have cascaded in from
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster another rule. This is different than removing the property assignment
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford entirely, as this allows cascading values through.
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert WapshottY.StyleSheet('MyApp').set('.foo', { background: 'auto' });
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster// is NOT the same as
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterY.StyleSheet('MyApp').unset('.foo','background');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h3 id="not_selector">A note on selector strings</h3>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Though the StyleSheet Utility takes selector strings as input to its API,
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford it <em>does not</em> leverage the YUI selector engine. YUI's selector
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster functionality supplements native CSS support for DOM access, but
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster accomplishes this through efficient DOM traversal. Since the StyleSheet
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Utility uses the browser's built-in stylesheet and rule objects, it can not
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster handle selectors that are not supported by the browser's native CSS
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott// This will not cause a style change in IE 6, for example
8af80418ba1ec431c8027fa9668e5678658d3611Allan FosterY.StyleSheet('MyApp').set('input[type=checkbox]:checked', {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster verticalAlign : 'super'
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h3 id="disable">Disabling and enabling a StyleSheet</h3>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Disabling a StyleSheet effectively turns it off; no CSS from that
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster stylesheet is applied to the page. Disabling a StyleSheet does not remove
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster the host node from the page, and style can be reapplied by enabling the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster StyleSheet again.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster When StyleSheets are disabled, it is still possible to change their style
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster rules via <code>set</code> and <code>unset</code>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervar sheet = Y.StyleSheet(styleNode);
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottsheet.set('.foo', { backgroundColor: '#900', color: '#fff' });
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostersheet.set('.bar', { borderBottomColor: '#369' });
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h3 id="static">Static methods</h3>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>Y.StyleSheet</code> exposes a few static methods.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<div class="apisummary">
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford <th>Method</th>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <th>Use for</th>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <td><a href="../api/StyleSheet.html#method_StyleSheet.register"><code>register(instance, name)</code></a></td>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <td>Use to assign a named registry entry for a StyleSheet instance.</td>
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott <td><a href="../api/StyleSheet.html#method_StyleSheet.toCssText"><code>toCssText(property_obj, starting_cssText)</code></a></td>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <td>Use to translate an object of style property:value pairs to a single <code>cssText</code> string. The optional second argument is a <code>cssText</code> string of a style's "before" state.</td>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>Y.StyleSheet.toCssText</code> is used internally to assemble the
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford <code>cssText</code> strings for updating the stylesheet rules. However,
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster it may also be helpful for avoiding reflow overhead when substantially
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modifying a single element's style.
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshottvar el = Y.one('some_element'),
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster changes = { color : '#684', fontWeight: 'bold', padding: '2em' },
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott currentStyle = el.getStyle('cssText');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Y.StyleSheet.toCssText(changes, currentStyle));
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h2 id="mechanism">How <code>Y.StyleSheet</code> works</h2>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Browsers grant access via the DOM API to stylesheets included in markup as
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott <code><link></code> or <code><style></code> elements. Despite
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster differing implementations across the browser spectrum, they all support
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster adding, removing, and modifying CSS rules.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster CSS rules are comprised of a selector and collection of style
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott property:value pairs enclosed in curly braces.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/* | This is a CSS rule |
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster | selectorText | style properties | */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster div.this-is a .rule { font-color: #f00; }
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster In JavaScript, each rule object has a <code>selectorText</code> property
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford and a <code>style</code> property that operates in the same way as the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>style</code> property on regular DOM elements, such as
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code><p></code> or <code><strong></code> elements.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Arguably the most valuable property of the style collection is
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>cssText</code> which corresponds to the serialized summary of
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster property:value pairs applied by this collection (e.g. "font-size: 100%;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster color: #FF0000;"). The reason this property is important is that
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster modifications to the string value will cause changes to repopulate the
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott individual style properties <em>while only triggering a single repaint or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster reflow</em> by the browser.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervar el = document.getElementById('some_element');
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterel.style.borderBottom = '3px solid #eee'; // reflow
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterel.style.borderTop = '3px solid #ccc'; // another reflow
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterel.style.fontWeight = 'bold'; // another reflow
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford// Vs. three changes in one reflow
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterel.style.cssText += '; border-bottom: 3px solid #eee; border-top: 3px solid #ccc; font-weight: bold';
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford <code>Y.StyleSheet</code> leverages this mechanism in addition to applying
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford modifications at the CSS rule level rather than modifying each targeted DOM
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford node directly. This means changing multiple style properties on multiple
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford elements (that can be identified by a single selector) will only ever incur
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford one repaint or reflow.
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford It must be noted that all reflows are not the same. The scope of a reflow
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster is greatly affected by what element triggered it. For example, changing a
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford style of an absolutely positioned element will trigger a very limited
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster reflow because the browser understands that not much <em>could</em> change
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster as a result. Stylesheet modifications on the other hand are not tied to an
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott element, but the page as a whole. The CSS cascade must be recalculated and
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott applied, resulting in a full page reflow. This means it may be more
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster efficient to individually update many elements than to change the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster<h2 id="knownissues">Known Issues</h2>
0c893a059f84246bf91e2f0fbf63e4c92f8e5165Tony Bamford <strong>Unable to set style values with
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>!important</code></strong>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster CSS syntax for declaring that a style value has <code>important</code>
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster priority is to include the <code>!important</code> flag after the
35ab1c5bca11317474fe12bdd8d22c17cdaf2697Robert Wapshott color: #000 !important;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster However, the DOM API for modifying stylesheets does not parse out the
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>!important</code> flag from the assigned value string, and thus
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster considers the entire string to be an invalid value.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterel.style.color = "#000 !important"; // Error
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster StyleSheet will support <code>!important</code> in the value string in a
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster future release, but for now the only way to assign an
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster <code>!important</code> style is by creating a new StyleSheet, passing a
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster CSS text string to the constructor.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostervar sheet = new Y.StyleSheet();
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fostersheet.set(".foo", { color: "#000 !important" }); // FAIL
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosternew Y.StyleSheet(".foo { color: #000 !important; }"); // WORKS