'how to insert css dynamically (not inline) in javascript?

css version:

:root {
  --kiss: url(https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/1f609.svg);
  --wink: url(https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/1f617.svg);
}
[class*="emo_"]:after {
  display: block;
  content:'';
  width:40px;
  height:40px;
  border:1px solid red;
  border-radius:50%
}
.emo_wink:after {
  content: var(--wink);
}
.emo_kiss:after {
  content: var(--kiss);
}
<div class="emo_wink"></div>
<div class="emo_kiss"></div>

js version: I want to use the js version to avoid repetitive codes in css but Im having trouble getting it to work... I can see in the console that the styles are added but it's not rendering...

var emodata = {
  wink: '1f609',
  kiss: '1f617'
}

function emojis(data) {
  for (var key in data) {
    if (data.hasOwnProperty(key)) {
      var url = 'https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/' + data[key] + '.svg';
      document.documentElement.style.setProperty('--' + key, 'url(' + url + ')');
      document.styleSheets[0].insertRule(".emo_" + key + ":after { content: var(--" + key + ") }");
    }
  }
}
emojis(emodata)
[class*="emo_"]:after {
  display: block;
  content:'';
  width:40px;
  height:40px;
  border:1px solid red;
  border-radius:50%
}
<div class="emo_wink"></div>
<div class="emo_kiss"></div>
Another question: Is there a huge difference in performance and speed if I use the js version? thanks!


Solution 1:[1]

You can create a style element in javascript and append it to the head element and then append the classes accordingly.

var emodata = {

  wink: '1f609',

  kiss: '1f617'

}

function emojis(data) {
  var style = document.createElement('style');

style.type = 'text/css';
  document.querySelector('head').appendChild(style)

  for (var key in data) {

    if (data.hasOwnProperty(key)) {

      var url = 'https://cdnjs.cloudflare.com/ajax/libs/twemoji/14.0.2/svg/' + data[key] + '.svg';

      document.documentElement.style.setProperty('--' + key, 'url(' + url + ')');
      style.innerHTML+=`.emo_${key}:after{
          content: var(--${key});
      }`

    }

  }

}

emojis(emodata)
[class*="emo_"]:after {

  display: block;

  content:'';

  width:40px;

  height:40px;

  border:1px solid red;

  border-radius:50%

}
<div class="emo_wink"></div>

<div class="emo_kiss"></div>

You could also use sass to do it without javascript

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Tanay