Convert CSS objects to a style tag

Sometimes I have to add CSS styles to the DOM programmatically (if you need a reason: imagine that you are writing a small ui widget that comes with its own style, but should consist of only one * .js file to simplify processing). In this case, I prefer to define a style in my script code with a musical notation of the object instead of a single large line that mixes the rules, properties and markup.

var thumbHoverStyle = { "background-color": "rgba(211, 211, 211, 0.5)", "cursor": "pointer" }; 

vs

 var thumbHoverStyle = "<style> .thumb:hover { background-color: rgba(211, 211, 211, 0.5); cursor: pointer; } </style>"; 

Such a css object can be easily used with the JQuery.css () function , but the problem starts as soon as I want a style a css pseudo-class (in my example: hover). In this case, I cannot use the JQuery .css() function, and I return to inserting the appropriate style tag into my DOM.

 var thumbHoverStyleTag = toStyleTag( { ".thumb:hover": thumbHoverStyle } ); _root.append(thumbHoverStyleTag); 

I googled and stackoverflowed but could not find a utility function that converts my css object to a style tag. In the end, I wrote my own function (and I probably provided it as an answer to this question), but I still want to know if there is a library function for this. What is the most elegant way to do this?

Edit

My implementation in TypeScript:

 function appendPxIfNumber(value: any): string { return (typeof value === "number") ? "" + value + "px" : value; } function toStyleTag(rulesObj: any) { var combinedRules: string = ""; for (var selector in rulesObj) { var cssObject = rulesObj[selector]; var combinedProperties = ""; for (var prop in cssObject) { var value = cssObject[prop]; combinedProperties += `${prop}: ${appendPxIfNumber(value)};` + "\n"; } combinedRules += ` ${selector} {${combinedProperties}}` + "\n"; } return $(`<style>${combinedRules}</style>`); } 

Usage example:

 var styleTag = toStyleTag( { ".thumb": thumbStyle, ".thumb:hover": thumbHoverStyle } ); 
+6
source share
4 answers

Here is a working example that works with an origin style object: I convert JSON to CSS . and determine the purpose to be indicated. Remember that there is no selector that needs to be styled ... So, I added targetSelector .

 var targetSelector='.thumb:hover', styleObj = { "background-color": "rgba(211, 211, 211, 0.5)", "cursor": "pointer" }, // Convert the JSON into CSS styleTagContent = JSON.stringify(styleObj,null,'\t') .replace(/"/g,'') .replace(/,\n/g,';') .replace(/\}/g, ';}') $('<style>'+targetSelector+styleTagContent+'</style>').appendTo('head'); 

Plunk works here to see how it works.

+3
source

The methodology of my toStyleTag() function is that it styleTag over styleTag with for ... in statement and checks if styleTag hasOwnProperty () selector . Then I reduce () the array returned by executing Object.keys () on the styleTag[selector] object, which I concat () accumulator by attaching currentValue (property), and styleTag[selector][currentValue]] (rule) - : This allows styles to become an array of strings that are in the form of property: rule . Now this is the format we need to use insertRule () , which we use to insert the new CSS rule into the current stylesheet. Note that I grab the length of the cssRules to find the index + 1 so that we can insert this new rule at the very end of our stylesheet to make sure it is not overwritten.

 var styleSheet = document.styleSheets[0]; function toStyleTag(styleTag) { for(var selector in styleTag) { if(styleTag.hasOwnProperty(selector)) { let styles = Object.keys(styleTag[selector]).reduce(function(accumulator, currentValue) { return accumulator.concat([currentValue, styleTag[selector][currentValue]].join(':')); }, []); styleSheet.insertRule(selector + '{' + styles.join(';') + '}', styleSheet.cssRules.length); } } } var thumbHoverStyle = { 'background-color': 'rgba(211, 211, 211, 0.5)', 'cursor': 'pointer' }; toStyleTag({ '.thumb:hover': thumbHoverStyle }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="thumb"> <img src="http://placehold.it/350x350"> </div> 
+1
source

I would have a desire:

  • add thumbHoverStyle CSS object to mouseover() ; and
  • replace it with thumbDefaultStyle CSS object with mouseout()

 var thumbStyle = { "width" : "100px", "height" : "100px", "text-align" : "center", "line-height" : "100px", "background-color": "rgb(211, 211, 211)" }; var thumbHoverStyle = { "color" : "rgb(255,255,255)", "background-color": "rgb(255, 0, 0)", "cursor": "pointer" }; var thumbDefaultStyle = { "color" : "rgb(0,0,0)", "background-color": "rgb(211, 211, 211)", "cursor": "default" }; $(document).ready(function(){ $('div').css(thumbStyle); $('input[type="checkbox"]').change(function(){ if ($('input[type="checkbox"]').prop('checked')) { $('div').mouseover(function(){ $(this).css(thumbHoverStyle); }); $('div').mouseout(function(){ $(this).css(thumbDefaultStyle); }); } else { $('div').mouseover(function(){ $(this).css(thumbDefaultStyle); }); $('div').mouseout(function(){ $(this).css(thumbDefaultStyle); }); } }); }); 
 div, button { display: inline-block; margin-right: 24px; vertical-align: top; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div>Hover Me</div> <input type="checkbox" />Activate New Hover Behaviour 
0
source

I wanted me to have another thing, because it is an exciting problem.

Here is the native javascript solution I compiled:

 var thumbStyle = { "width" : "100px", "height" : "100px", "text-align" : "center", "line-height" : "100px", "background-color": "rgb(211, 211, 211)" }; var thumbHoverStyle = { "color" : "rgb(255,255,255)", "background-color": "rgb(255, 0, 0)", "cursor": "pointer" }; var dynamicStyle = document.createElement('style'); document.head.appendChild(dynamicStyle); var dynamicStyleSheet = dynamicStyle.sheet; function addStyles(selector, cssStyleObject) { var properties = Object.keys(cssStyleObject); properties.forEach(function(property){ var value = cssStyleObject[property]; var dynamicRule = selector + ' {' + property + ': ' + value + ';}'; dynamicStyleSheet.insertRule(dynamicRule, dynamicStyleSheet.cssRules.length); }); } // Add styles dynamically by stating a selector and the name of a CSS Style Object addStyles('div', thumbStyle); addStyles('div:hover', thumbHoverStyle); 
 <div>Hover Me</div> 
0
source

Source: https://habr.com/ru/post/1013472/


All Articles