Styles and Stylesheet Manipulation


/ Published in: JavaScript
Save to your folder(s)

Useful functions to get around browser incompatibilities when working with stylesheets.
If you find any errors, please leave a comment.


Copy this code and paste it in your HTML
  1. //****************************************************************
  2. //*************************** Styles *****************************
  3. //****************************************************************
  4.  
  5. //IE doesn't support access to pseudoElement styles, so we won't use them at all (we'll pass null to
  6. // window.getComputedStyle())
  7.  
  8. //get the computed styles of an element
  9. function getStylesOf(elem)
  10. {
  11. var s = window.getComputedStyle ? window.getComputedStyle(elem, null) : elem.currentStyle;
  12. var float = s.cssFloat || s.styleFloat || s.float;
  13. s.cssFloat = s.styleFloat = s.float = float;
  14. return s;
  15. }
  16.  
  17. //set/get float style for an element
  18. //the property isn't named "float", as would be obvious
  19. //`float` argument is optional
  20. function floatStyle(elem, float)
  21. {
  22. var s = elem.style;
  23. if(float == "none" || float == "left" || float == "right")
  24. {
  25. if("cssFloat" in s) s.cssFloat = float; //all but IE
  26. if("styleFloat" in s) s.styleFloat = float; //IE and Opera
  27. if("float" in s) s.float = float; //Safari and Chrome
  28. }
  29. return s.cssFloat || s.styleFloat || s.float;
  30. }
  31.  
  32. //****************************************************************
  33. //******************** Alternate Stylesheets *********************
  34. //****************************************************************
  35.  
  36. //enables the stylesheet with the specified title; disables all other stylesheets that have a title
  37. function setActiveStyleSheet(toTitle)
  38. {
  39. var sse = getStyleSheetElements();
  40. var ss = null;
  41. for(var i=0; i<sse.length; i++)
  42. {
  43. if(sse[i].title == toTitle)
  44. {
  45. ss = sse[i];
  46. break;
  47. }
  48. }
  49. if(!ss) return false; //not found
  50. enableStyleSheet(ss);
  51. //disable all other stylesheets that have a title
  52. for(i=0; i<sse.length; i++)
  53. {
  54. if(sse[i] != ss && sse[i].title != "") disableStyleSheet(sse[i]);
  55. }
  56. return true;
  57. }
  58.  
  59. //returns the active stylesheet (element)
  60. function getActiveStyleSheet()
  61. {
  62. var sse = getStyleSheetElements();
  63. for(var i=0; i<sse.length; i++)
  64. {
  65. if(sse[i].title && !sse[i].disabled) return sse[i];
  66. }
  67. return null;
  68. }
  69.  
  70. //****************************************************************
  71. //****************** Enable/Disable Stylesheet *******************
  72. //****************************************************************
  73.  
  74. //sheet can be either an index or a stylesheet object
  75. function disableStyleSheet(sheet)
  76. {
  77. if(sheet instanceof Object) var ss = sheet; //sheet is an object
  78. else var ss = getStyleSheetElements()[sheet]; //sheet is an index
  79. ss.disabled = true;
  80. }
  81.  
  82. //sheet can be either an index or a stylesheet object
  83. function enableStyleSheet(sheet)
  84. {
  85. if(sheet instanceof Object) var ss = sheet; //sheet is an object
  86. else var ss = getStyleSheetElements()[sheet]; //sheet is an index
  87.  
  88. //note: in all but Firefox, the stylesheet must have been explicitly disabled before it can be enabled
  89. // (e.g., if it was an alternate stylesheet, it wasn't enabled to begin with but wasn't explicitly disabled either
  90. // for some reason)
  91.  
  92. ss.disabled = true; //in case it hasn't yet been explicitly disabled
  93. ss.disabled = false;
  94. }
  95.  
  96. //****************************************************************
  97. //*********************** Get Stylesheet *************************
  98. //****************************************************************
  99.  
  100. //Safari doesn't count alternate stylesheets that aren't enabled, so we have to find them manually
  101. //this function only returns the DOM elements; not the actual stylesheets
  102. function getStyleSheetElements()
  103. {
  104. var stylesheets = [];
  105. var elems = document.getElementsByTagName("head")[0].childNodes;
  106. for(var i=0; i<elems.length; i++)
  107. {
  108. if(elems[i].nodeType == 1) //it's an element node
  109. {
  110. if(elems[i].tagName.toLowerCase() == "style" ||
  111. (elems[i].tagName.toLowerCase() == "link" && /(^|\s)stylesheet(\s|$)/i.test(elems[i].rel)) )
  112. {
  113. stylesheets.push(elems[i]);
  114. }
  115. }
  116. }
  117. return stylesheets;
  118. }
  119.  
  120. //get the stylesheet, or null if it doesn't exist or can't be accessed
  121. function getStyleSheet(sheetIndex)
  122. {
  123. var ss = getStyleSheetElements();
  124. if(ss.length == document.styleSheets.length)
  125. {
  126. if(sheetIndex < ss.length) return document.styleSheets[sheetIndex];
  127. return null; //not found; sheetIndex is too large
  128. }
  129. else //Safari (it doesn't count stylesheets that aren't enabled)
  130. {
  131. var iSafari = 0;
  132. for(var i=0; i<ss.length && iSafari<document.styleSheets.length; i++)
  133. {
  134. //if(ss[i].disabled !== false) //ss[i].disabled for an alternate stylesheet is initially false even though it's not enabled
  135. if(ss[i].href != document.styleSheets[iSafari].href) //stylesheet not enabled
  136. {
  137. if(i == sheetIndex) return null; //Safari can't access this stylesheet
  138. }
  139. else
  140. {
  141. if(i == sheetIndex) return document.styleSheets[iSafari];
  142. iSafari++;
  143. }
  144. }
  145. return null; //not found; sheetIndex is too large
  146. }
  147. }
  148.  
  149. //get the stylesheet with specified title, or null if it doesn't exist or can't be accessed
  150. function getStyleSheetByTitle(sheetTitle)
  151. {
  152. var ss = getStyleSheetElements();
  153. if(ss.length == document.styleSheets.length)
  154. {
  155. for(var i=0; i<ss.length; i++)
  156. {
  157. if(ss[i].title == sheetTitle) return document.styleSheets[i];
  158. }
  159. return null; //not found
  160. }
  161. else //Safari (it doesn't count stylesheets that aren't enabled)
  162. {
  163. var iSafari = 0;
  164. for(var i=0; i<ss.length; i++)
  165. {
  166. //if(ss[i].disabled !== false) //ss[i].disabled for an alternate stylesheet is initially false even though it's not enabled
  167. if(ss[i].href != document.styleSheets[iSafari].href) //stylesheet not enabled
  168. {
  169. if(ss[i].title == sheetTitle) return null; //Safari can't access this stylesheet
  170. }
  171. else
  172. {
  173. if(ss[i].title == sheetTitle) return document.styleSheets[iSafari];
  174. iSafari++;
  175. }
  176. }
  177. return null; //not found
  178. }
  179. }
  180.  
  181. //****************************************************************
  182. //*************************** Rules ******************************
  183. //****************************************************************
  184.  
  185. //browser bugs/incompatibilities galore; use at your own risk
  186. //note: IE splits up selectors at the commas, so a single rule may be split into multiple rules
  187. //note: .cssRules includes @import rules, but in IE they're in .imports instead
  188. //sheet can be either an index or a stylesheet object
  189. function getStyleSheetRules(sheet)
  190. {
  191. if(sheet instanceof Object) var ss = sheet; //sheet is an object
  192. else var ss = getStyleSheet(sheet); //sheet is an index
  193. if(!ss) return null;
  194. return ss.cssRules || ss.rules;
  195. }
  196. //rules can be modified like this:
  197. //var rules = getStyleSheetRules(0); //get the rules in the first stylesheet
  198. //rules[0].style.height = "25px"; //in the first rule, set the height
  199.  
  200. //add a rule to the end of a stylesheet
  201. //note: IE's method (and consequently this function) puts the rule at the end of the stylesheet; you can't position it
  202. // where you want
  203. //sheet can be either an index or a stylesheet object
  204. function appendStyleSheetRule(sheet, selector, properties)
  205. {
  206. if(sheet instanceof Object) var ss = sheet; //sheet is an object
  207. else var ss = getStyleSheet(sheet); //sheet is an index
  208. if(!ss) return false;
  209. if(ss.insertRule) ss.insertRule(selector+" { "+properties+" }", ss.cssRules.length);
  210. else ss.addRule(selector, properties); //IE
  211. return true;
  212. }
  213.  
  214. //sheet can be either an index or a stylesheet object
  215. function deleteStyleSheetRule(sheet, ruleIndex)
  216. {
  217. if(sheet instanceof Object) var ss = sheet; //sheet is an object
  218. else var ss = getStyleSheet(sheet); //sheet is an index
  219. if(!ss) return false;
  220. if(ss.deleteRule) ss.deleteRule(ruleIndex);
  221. else ss.removeRule(ruleIndex); //IE
  222. return true;
  223. }
  224.  
  225. //****************************************************************
  226. //************************** CSS Text ****************************
  227. //****************************************************************
  228.  
  229. //to get the selector text of a rule: ruleObject.selectorText
  230. //to get the properties text of a rule: ruleObject.style.cssText
  231. //to get the properties text of an inline element: elem.style.cssText
  232.  
  233. //gets the full text of a rule (including selector)
  234. function getRuleText(ruleObject)
  235. {
  236. if(!ruleObject) return "";
  237. if(ruleObject.cssText) return ruleObject.cssText;
  238. return ruleObject.selectorText+" { "+ruleObject.style.cssText+" }";
  239. }
  240.  
  241. //gets the full text of a stylesheet
  242. //sheet can be either an index or a stylesheet object
  243. function getStyleSheetText(sheet)
  244. {
  245. if(sheet instanceof Object) var ss = sheet; //sheet is an object
  246. else var ss = getStyleSheet(sheet); //sheet is an index
  247. if(!ss) return "";
  248. if(ss.cssText) return ss.cssText; //IE
  249. var txt = "";
  250. var rules = getStyleSheetRules(ss);
  251. for(var i=0; i<rules.length; i++)
  252. {
  253. txt += getRuleText(rules[i])+" ";
  254. }
  255. return txt;
  256. }

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.