Posted By

dom111 on 05/01/09


Tagged

css javascript nested


Versions (?)

Who likes this?

1 person have marked this snippet as a favorite

necmettin


JSS 0.1 - Nested CSS using Javascript


 / Published in: JavaScript
 

URL: http://www.dom111.co.uk/blog/coding/jss-nested-css-using-javascript/94

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.

  1. /**
  2.  * JSS
  3.  *
  4.  * Nested CSS via JavaScript
  5.  **/
  6. var JSS = function(o, options) {
  7. // set up the base options
  8. this.options = {
  9. minified: true,
  10. apply: true
  11. }
  12.  
  13. // set up the data hash
  14. this.data = {};
  15.  
  16. // m()
  17. //
  18. // Merges properties of s into o and returns o
  19. //
  20. this.m = function(o, s) {
  21. for (var p in s) {
  22. o[p] = s[p];
  23. }
  24.  
  25. return o;
  26. }
  27.  
  28. // parse()
  29. //
  30. // Parses the object o and stores the information in this.data{}
  31. //
  32. this.parse = function(o, p) {
  33. if (typeof o != 'object') {
  34. throw new Error('CSS::parse: No valid CSS object passed.');
  35. }
  36.  
  37. if (!p) {
  38. p = '';
  39. }
  40.  
  41. for (var prop in o) {
  42. if (typeof o[prop] == 'object') {
  43. var rule = getPrefix(p) + prop;
  44. if (!this.data[rule]) {
  45. this.data[rule] = [];
  46. }
  47.  
  48. this.parse(o[prop], this.getPrefix(p) + prop);
  49.  
  50. } else {
  51. this.data[p][this.data[p].length] = (this.options.minified) ? prop + ':' + this.minify(o[prop]) + ';' : ' ' + prop + ': ' + o[prop] + ';\n';
  52. }
  53. }
  54. }
  55.  
  56. // build()
  57. //
  58. // Builds the information stored in this.data{} into valid CSS text
  59. //
  60. this.build = function() {
  61. var css = '';
  62.  
  63. for (var rule in this.data) {
  64. if (this.data[rule] != []) {
  65. css += (this.options.minified) ? rule + '{' : rule + ' {\n';
  66.  
  67. css += this.data[rule].join('');
  68.  
  69. css += (this.options.minified) ? '}' : '}\n\n';
  70. }
  71. }
  72.  
  73. return css;
  74. }
  75.  
  76. // getPrefix()
  77. //
  78. // Shortcut to return the prefix for stacking
  79. //
  80. this.getPrefix = function(p) {
  81. if (p) {
  82. return p + ' ';
  83.  
  84. } else {
  85. return '';
  86. }
  87. }
  88.  
  89. // minify()
  90. //
  91. // Minifies the string passed
  92. //
  93. this.minify = function(s) {
  94. // html/css colour names that can be replaced by shorter hex codes
  95. var colours = [
  96. [
  97. /black/,
  98. '#000'
  99. ],
  100. [
  101. /white/,
  102. '#fff'
  103. ],
  104. [
  105. /fuchsia/,
  106. '#f0f'
  107. ],
  108. [
  109. /yellow/,
  110. '#ff0'
  111. ]
  112. ];
  113.  
  114. // loop through taking out any long colour names
  115. for (var i = colours.length - 1; i >= 0; i--){
  116. s = s.replace(colours[i][0], colours[i][1]);
  117. }
  118.  
  119. // if we've got any 6 char hex codes
  120. if (s.match(/#[0-9a-f]{6}/)) {
  121. // see if we can shrink them
  122. var matches = s.match(/#([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])([0-9a-f])/);
  123.  
  124. if ((matches[1] == matches[2]) && (matches[3] == matches[4]) && (matches[5] == matches[6])) {
  125. s = s.replace(matches[0], '#' + matches[1] + matches[3] + matches[5]);
  126. }
  127. }
  128.  
  129. return s;
  130. }
  131.  
  132. // addToPage()
  133. //
  134. // Applies the generated stylesheet to the page
  135. //
  136. this.addToPage = function(s) {
  137. // create a style element
  138. var style = document.createElement('style');
  139. // set it to a text/css block
  140. style.setAttribute('type', 'text/css');
  141.  
  142. // append the style to the body
  143. if (style.styleSheet) {
  144. // in IE
  145. style.styleSheet.cssText = s;
  146.  
  147. } else {
  148. // in the other browsers
  149. style.appendChild(document.createTextNode(s));
  150. }
  151.  
  152. // put it in the document
  153. document.getElementsByTagName('head')[0].appendChild(style);
  154. }
  155.  
  156. // set the options
  157. this.options = this.m(this.options, options || {});
  158.  
  159. // start parsing the object
  160. this.parse(o);
  161.  
  162. if (this.options.apply) {
  163. // if we're supposed to apply the stylesheet, do it!
  164. this.addToPage(this.build());
  165.  
  166. } else {
  167. // just return the text
  168. return this.build();
  169. }
  170. }

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: JonyGreen on December 7, 2015

you can try this free online service to minify js and compress css, so it will reduce the size of web page.

You need to login to post a comment.