diff -r 322d0feea350 -r 89ef5ed3c48b src/cm/media/js/lib/yui/yui_3.10.3/docs/stylesheet/index.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cm/media/js/lib/yui/yui_3.10.3/docs/stylesheet/index.html Tue Jul 16 14:29:46 2013 +0200 @@ -0,0 +1,714 @@ + + + + + StyleSheet + + + + + + + + + + +
+
+

+
+ + Jump to Table of Contents + + +

StyleSheet

+
+
+
+
+

+ The StyleSheet module normalizes the dynamic creation and modification + of CSS stylesheets on a page. This makes it easy to manage the + development, storage, and reapplication of personalized user + stylesheets. Because it targets styles at the CSS level, it also + allows you to modify styles applied to a CSS pseudo-element such as + p::first-letter, or pseudo-class such as + a:hover. +

+ +

+ StyleSheet is capable of creating new stylesheets from scratch or + modifying existing stylesheets held as properties of + <link> or <style> elements. It + should be noted that not all browsers support reading or modifying + external stylesheets from other domains. +

+
+ +

Getting Started

+ +

+To include the source files for StyleSheet and its dependencies, first load +the YUI seed file if you haven't already loaded it. +

+ +
<script src="http://yui.yahooapis.com/3.10.3/build/yui/yui-min.js"></script>
+ + +

+Next, create a new YUI instance for your application and populate it with the +modules you need by specifying them as arguments to the YUI().use() method. +YUI will automatically load any dependencies required by the modules you +specify. +

+ +
<script>
+// Create a new YUI instance and populate it with the required modules.
+YUI().use('stylesheet', function (Y) {
+    // StyleSheet is available and ready for use. Add implementation
+    // code here.
+});
+</script>
+ + +

+For more information on creating YUI instances and on the +use() method, see the +documentation for the YUI Global Object. +

+ + +

Using the StyleSheet Utility

+ +

Instantiating a Y.StyleSheet

+ +

+ The Y.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 instance. +

+ +
// These are equivalent; both create new empty StyleSheets
+var myStyleSheet = new Y.StyleSheet();
+
+var myOtherStyleSheet = Y.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. +
  3. + the id of a <style> or <link> + node, or +
  4. +
  5. a string of CSS
  6. +
+ +
<link id="local" type="text/css" rel="stylesheet" href="local_file.css">
+<style id="styleblock" type="text/css">
+    .some select.or {
+        margin-right: 2em;
+    }
+</style>
+ + +
YUI().use('node','stylesheet', function (Y) {
+
+    // Node or HTMLElement reference for a style or locally sourced link element
+    var sheet = Y.StyleSheet(Y.one("#styleblock"));
+    sheet = Y.StyleSheet(Y.DOM.byId('local'));
+
+    // OR the id of a style element or locally sourced link element
+    sheet = Y.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 Y.StyleSheet(css);
+
+    //...
+});
+ + +

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

+ +
<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
+var styleSheet = Y.StyleSheet('remote');
+ + +

Getting a StyleSheet by registered name

+ +

+ Y.StyleSheet supports registering instances by name allowing + them to be recalled by that same name elsewhere in your code. Internally, + Y.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 = Y.StyleSheet('my_stylesheet');
+
+// Create a registry alias to sheetA.  We'll call it bob.
+Y.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 = Y.StyleSheet(css, 'my sheet');
+
+// Meanwhile, elsewhere in your code
+
+// sheetA is the same instance as sheet1 and sheet2
+var sheet1 = Y.StyleSheet(Y.one('#my_stylesheet')),
+    sheet2 = Y.StyleSheet('bob');
+
+// sheetB is the same instance as sheet3
+var sheet3 = Y.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
+Y.StyleSheet('MyApp').set('.module .messages', { display: 'none' });
+
+//...
+
+// In another area of your app
+Y.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. +
  3. + 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. +
  4. +
  5. + Check the string for a curly brace { character. If found, create a new + instance seeded with the string as initial cssText. +
  6. +
  7. + Create a new empty StyleSheet and register the instance by the provided + string. +
  8. +
+ +

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_properties targeting the + provided selector. In essence, it looks very much like + natural CSS syntax, except style properties must be in JavaScript's + camelCase. +

+ +
Y.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
+    });
+ + +

+ 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
+Y.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. StyleSheet instances will + normalize these properties for you. +

+ +

+ 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
+Y.StyleSheet('MyApp').set('.foo', {
+    "float"    : "left",   // "float" must be quoted
+    cssFloat   : "right",
+    styleFloat : "none"
+});
+ + +

+ IE does not support the opacity style property, but has + equivalent functionality offered by its proprietary filter + property, though using a different value syntax. StyleSheet will translate + opacity to filter for IE, but it will + not translate filter to opacity for + W3C-compliant browsers. +

+ +

Removing and resetting CSS style rules

+ +

+ When you want to remove a particular rule or style property from affecting + 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. +

+ +
Y.StyleSheet('MyApp').set('.foo', { background: 'auto' });
+
+// is NOT the same as
+
+Y.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 the YUI selector engine. YUI's selector + functionality 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
+Y.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. +

+ +
var sheet = Y.StyleSheet(styleNode);
+
+sheet.disable();
+sheet.set('.foo', { backgroundColor: '#900', color: '#fff' });
+sheet.set('.bar', { borderBottomColor: '#369' });
+sheet.unset('.baz');
+sheet.enable();
+ + +

Static methods

+ +

+ Y.StyleSheet exposes a few static methods. +

+ +
+ + + + + + + + + + + + + + + + + +
MethodUse for
+
Y.StyleSheet.register(instance, name)
+ +
Use to assign a named registry entry for a StyleSheet instance.
+
Y.StyleSheet.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.
+
+ +

+ Y.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           = Y.one('some_element'),
+    changes      = { color : '#684', fontWeight: 'bold', padding: '2em' },
+    currentStyle = el.getStyle('cssText');
+
+el.setStyle('cssText',
+    Y.StyleSheet.toCssText(changes, currentStyle));
+ + +

How Y.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. +

+ +
/* |            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 = document.getElementById('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';
+ + +

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

+ +

+ It must be noted that all reflows are not the same. The scope of a reflow + is greatly affected by what element triggered it. For example, changing a + style of an absolutely positioned element will trigger a very limited + reflow because the browser understands that not much could change + as a result. Stylesheet modifications on the other hand are not tied to an + element, but the page as a whole. The CSS cascade must be recalculated and + applied, resulting in a full page reflow. This means it may be more + efficient to individually update many elements than to change the + stylesheet. +

+ +

Known Issues

+ +

+ Unable to set style values with + !important. +

+ +

+ CSS syntax for declaring that a style value has important + priority is to include the !important flag after the + value. +

+ +
.some-class {
+    color: #000 !important;
+}
+ + +

+ However, the DOM API for modifying stylesheets does not parse out the + !important flag from the assigned value string, and thus + considers the entire string to be an invalid value. +

+ +
el.style.color = "#000 !important"; // Error
+ + +

+ StyleSheet will support !important in the value string in a + future release, but for now the only way to assign an + !important style is by creating a new StyleSheet, passing a + CSS text string to the constructor. +

+ +
var sheet = new Y.StyleSheet();
+sheet.set(".foo", { color: "#000 !important" }); // FAIL
+
+new Y.StyleSheet(".foo { color: #000 !important; }"); // WORKS
+ +
+
+
+ + +
+
+ + + + + + + + + + +