Home > Software design >  JS - Create a stylesheet with a name attribute
JS - Create a stylesheet with a name attribute

Time:10-06

I'm trying to create dynamically multiple stylesheets by multiple functions. To identify each stylesheet, I would like to set a name on it ( to be able to remove/disable them from the DOM ) I'm using the simple function see bellow, but I don't understand the result

let createStyle = function(name){
  let head = document.head;
  let style = document.createElement('style');
  name && (style.setAttribute('title', name));
  style.type = 'text/css';
  head.appendChild(style);   
  return style.sheet;
}   

If I'm using one of call see bellow, all is fine and the h1 tag is red.

createStyle("").insertRule('h1 { color: red; }')
OR
createStyle("name").insertRule('h1 { color: red; }').

All is fine the h1 tag is red.

If I'm using the code see bellow, all is fine. I can see both declaration see on chrome dev tools and the h1 tag is green

createStyle("").insertRule('h1 { color: red; }')
createStyle("").insertRule('h1 { color: green; }')

If I'm using the code see bellow, I can see 2 style tags on the head part. But h1 is red and the second declaration doesn't appear on Chrome dev tools.

createStyle("name1").insertRule('h1 { color: red; }')
createStyle("name2").insertRule('h1 { color: green; }')

Any help appreciated to explain me. Thanks in advance.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script>
    let createStyle = function(name){
      let head = document.head;
      let style = document.createElement('style');
      name && (style.setAttribute('title', name));
      style.type = 'text/css';
      head.appendChild(style);   
      return style.sheet;
    }   
    createStyle("name1").insertRule('h1 { color: red; }')
    createStyle("name2").insertRule('h1 { color: green; }')
    
  </script>
</head>
<body>
  <h1>Test</h1>
</body>
</html>

CodePudding user response:

This is because the title attribute on a stylesheet is used to specify alternate style sheets.

There can only be one preferred stylesheet, so providing stylesheets with different title attributes will cause some of them to be ignored.

You probably want to use the id attribute (or use some data attribute like data-name instead).

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script>
    let createStyle = function(name){
      let head = document.head;
      let style = document.createElement('style');
      name && (style.dataset.name = name);
      style.type = 'text/css';
      head.appendChild(style);   
      return style.sheet;
    }   
    createStyle("name1").insertRule('h1 { color: red; }');
    createStyle("name2").insertRule('h1 { color: green; }');
    // select first style element
    console.log(document.querySelector('style[data-name=name1]')); 
    
  </script>
</head>
<body>
  <h1>Test</h1>
</body>
</html>

CodePudding user response:

It seems like your issue is that the browser is struggling with what to take precedence with.

To fix this, you can add the !important tag and it will overwrite all previous styles added, i.e. createStyle("").insertRule('h1 { color: red !important; }');

As for why some things you tried work and some don't:

createStyle("").insertRule('h1 { color: red; }')
OR
createStyle("name").insertRule('h1 { color: red; }').

This works fine because you're simply adding two styles with the same colors.

createStyle("").insertRule('h1 { color: red; }')
createStyle("").insertRule('h1 { color: green; }')

This works because you're overwriting the ruleset you created before I assume.

createStyle("name1").insertRule('h1 { color: red; }')
createStyle("name2").insertRule('h1 { color: green; }')

This does not work because the browser does not know how to handle two rulesets on one object with separate formatting.

  • Related