Revision: 13664
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at May 1, 2009 11:30 by dom111
Initial Code
/** * JSS * * Nested CSS via JavaScript **/ var JSS = function(o, options) { // set up the base options this.options = { minified: true, apply: true } // set up the data hash this.data = {}; // m() // // Merges properties of s into o and returns o // this.m = function(o, s) { for (var p in s) { o[p] = s[p]; } return o; } // parse() // // Parses the object o and stores the information in this.data{} // this.parse = function(o, p) { if (typeof o != 'object') { throw new Error('CSS::parse: No valid CSS object passed.'); } if (!p) { p = ''; } for (var prop in o) { if (typeof o[prop] == 'object') { var rule = getPrefix(p) + prop; if (!this.data[rule]) { this.data[rule] = []; } this.parse(o[prop], this.getPrefix(p) + prop); } else { this.data[p][this.data[p].length] = (this.options.minified) ? prop + ':' + this.minify(o[prop]) + ';' : ' ' + prop + ': ' + o[prop] + ';\n'; } } } // build() // // Builds the information stored in this.data{} into valid CSS text // this.build = function() { var css = ''; for (var rule in this.data) { if (this.data[rule] != []) { css += (this.options.minified) ? rule + '{' : rule + ' {\n'; css += this.data[rule].join(''); css += (this.options.minified) ? '}' : '}\n\n'; } } return css; } // getPrefix() // // Shortcut to return the prefix for stacking // this.getPrefix = function(p) { if (p) { return p + ' '; } else { return ''; } } // minify() // // Minifies the string passed // this.minify = function(s) { // html/css colour names that can be replaced by shorter hex codes var colours = [ [ /black/, '#000' ], [ /white/, '#fff' ], [ /fuchsia/, '#f0f' ], [ /yellow/, '#ff0' ] ]; // loop through taking out any long colour names for (var i = colours.length - 1; i >= 0; i--){ s = s.replace(colours[i][0], colours[i][1]); } // if we've got any 6 char hex codes if (s.match(/#[0-9a-f]{6}/)) { // see if we can shrink them var matches = s.match(/#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])/); if ((matches[1] == matches[2]) && (matches[3] == matches[4]) && (matches[5] == matches[6])) { s = s.replace(matches[0], '#' + matches[1] + matches[3] + matches[5]); } } return s; } // addToPage() // // Applies the generated stylesheet to the page // this.addToPage = function(s) { // create a style element var style = document.createElement('style'); // set it to a text/css block style.setAttribute('type', 'text/css'); // append the style to the body if (style.styleSheet) { // in IE style.styleSheet.cssText = s; } else { // in the other browsers style.appendChild(document.createTextNode(s)); } // put it in the document document.getElementsByTagName('head')[0].appendChild(style); } // set the options this.options = this.m(this.options, options || {}); // start parsing the object this.parse(o); if (this.options.apply) { // if we're supposed to apply the stylesheet, do it! this.addToPage(this.build()); } else { // just return the text return this.build(); } }
Initial URL
http://www.dom111.co.uk/blog/coding/jss-nested-css-using-javascript/94
Initial Description
Ever wanted nested stylesheets? I have! Now you can have them! If you code your stylesheets as JSON and parse them using JSS 0.1. You could have the following: JSS({ 'html': { 'body': { background: '#fff', 'div#header': { height: '100px', background: '#00f' }, 'div#footer': { height: '40px', 'span#copyright': { color: '#0f0' }, 'span#testing': { color: 'black', background: '#eeccff' } } }, width: '800px' } }); Turned into: html { width: 800px; } html body { background: #fff; } html body div#header { height: 100px; background: #00f; } html body div#footer { height: 40px; } html body div#footer span#copyright { color: #0f0; } html body div#footer span#testing { color: black; background: #eeccff; } Check out the blog post for a demo and a zip file containing the demo, full version and minified version.
Initial Title
JSS 0.1 - Nested CSS using Javascript
Initial Tags
css, javascript
Initial Language
JavaScript