web-dev-qa-db-fra.com

Comment créer une balise <style> avec Javascript?

Je cherche un moyen d'insérer une balise <style> dans une page HTML avec JavaScript.

Le meilleur moyen que j'ai trouvé jusqu'à présent:

var divNode = document.createElement("div");
divNode.innerHTML = "<br><style>h1 { background: red; }</style>";
document.body.appendChild(divNode);

Cela fonctionne dans Firefox, Opera et Internet Explorer, mais pas dans Google Chrome. Aussi, c'est un peu moche avec le <br> devant IE.

Est-ce que quelqu'un connaît un moyen de créer une balise <style> qui

  1. Est plus gentil

  2. Fonctionne avec Chrome?

Ou peut-être

  1. Ceci est une chose non standard que je devrais éviter

  2. Trois navigateurs sont efficaces et qui utilise Chrome de toute façon?

282
Arend

Essayez d’ajouter l’élément style à la head au lieu de la body.

Cela a été testé dans IE (7-9), Firefox, Opera et Chrome:

var css = 'h1 { background: red; }',
    head = document.head || document.getElementsByTagName('head')[0],
    style = document.createElement('style');

style.type = 'text/css';
if (style.styleSheet){
  // This is required for IE8 and below.
  style.styleSheet.cssText = css;
} else {
  style.appendChild(document.createTextNode(css));
}

head.appendChild(style);
559
Christoph

Voici un script qui ajoute les méthodes createStyleSheet() et addRule() de style IE aux navigateurs qui n'en ont pas:

if(typeof document.createStyleSheet === 'undefined') {
    document.createStyleSheet = (function() {
        function createStyleSheet(href) {
            if(typeof href !== 'undefined') {
                var element = document.createElement('link');
                element.type = 'text/css';
                element.rel = 'stylesheet';
                element.href = href;
            }
            else {
                var element = document.createElement('style');
                element.type = 'text/css';
            }

            document.getElementsByTagName('head')[0].appendChild(element);
            var sheet = document.styleSheets[document.styleSheets.length - 1];

            if(typeof sheet.addRule === 'undefined')
                sheet.addRule = addRule;

            if(typeof sheet.removeRule === 'undefined')
                sheet.removeRule = sheet.deleteRule;

            return sheet;
        }

        function addRule(selectorText, cssText, index) {
            if(typeof index === 'undefined')
                index = this.cssRules.length;

            this.insertRule(selectorText + ' {' + cssText + '}', index);
        }

        return createStyleSheet;
    })();
}

Vous pouvez ajouter des fichiers externes via

document.createStyleSheet('foo.css');

et créer dynamiquement des règles via

var sheet = document.createStyleSheet();
sheet.addRule('h1', 'background: red;');
32
Christoph

Je suppose que vous souhaitez insérer une balise style par rapport à une balise link (faisant référence à un fichier CSS externe). C'est ce que l'exemple suivant fait:

<html>
 <head>
  <title>Example Page</title>
 </head>
 <body>
  <span>
   This is styled dynamically via JavaScript.
  </span>
 </body>
 <script type="text/javascript">
   var styleNode = document.createElement('style');
   styleNode.type = "text/css";
   // browser detection (based on prototype.js)
   if(!!(window.attachEvent && !window.opera)) {
        styleNode.styleSheet.cssText = 'span { color: rgb(255, 0, 0); }';
   } else {
        var styleText = document.createTextNode('span { color: rgb(255, 0, 0); } ');
        styleNode.appendChild(styleText);
   }
   document.getElementsByTagName('head')[0].appendChild(styleNode);
 </script>
</html>

De plus, j'ai remarqué dans votre question que vous utilisez innerHTML. Il s’agit en fait d’une méthode non standard d’insertion de données dans une page. La meilleure pratique consiste à créer un nœud de texte et à l'ajouter à un autre nœud d'élément.

En ce qui concerne votre dernière question, vous allez entendre certaines personnes dire que votre travail devrait fonctionner sur tous les navigateurs. Tout dépend de votre public. Si personne dans votre audience n'utilise Chrome, ne vous en faites pas! Toutefois, si vous souhaitez atteindre le plus grand public possible, il est préférable de prendre en charge tous les principaux navigateurs de classe A.

29
Tom

Un exemple qui fonctionne et qui est compatible avec tous les navigateurs:

var ss = document.createElement("link");
ss.type = "text/css";
ss.rel = "stylesheet";
ss.href = "style.css";
document.getElementsByTagName("head")[0].appendChild(ss);
21
belaz

Pour ceux qui utilisent déjà jQuery , vous pouvez utiliser ce one-liner:

$('<style>'+ styles +'</style>').appendTo(document.head);
15
vsync

Souvent, il est nécessaire de remplacer les règles existantes, aussi l’ajout de nouveaux styles au HEAD ne fonctionne pas dans tous les cas.

Je suis venu avec cette fonction simple qui résume toutes les approches non valide "ajouter au corps" et est juste plus pratique à utiliser et à déboguer (IE8 +).

window.injectCSS = (function(doc){
    // wrapper for all injected styles and temp el to create them
    var wrap = doc.createElement('div');
    var temp = doc.createElement('div');
    // rules like "a {color: red}" etc.
    return function (cssRules) {
        // append wrapper to the body on the first call
        if (!wrap.id) {
            wrap.id = 'injected-css';
            wrap.style.display = 'none';
            doc.body.appendChild(wrap);
        }
        // <br> for IE: http://goo.gl/vLY4x7
        temp.innerHTML = '<br><style>'+ cssRules +'</style>';
        wrap.appendChild( temp.children[1] );
    };
})(document);

Démo: codepen , jsfiddle

6
Garlaro

Voici une variante pour ajouter dynamiquement une classe 

function setClassStyle(class_name, css) {
  var style_sheet = document.createElement('style');
  if (style_sheet) {
    style_sheet.setAttribute('type', 'text/css');
    var cstr = '.' + class_name + ' {' + css + '}';
    var rules = document.createTextNode(cstr);
    if(style_sheet.styleSheet){// IE
      style_sheet.styleSheet.cssText = rules.nodeValue;
    } else {
      style_sheet.appendChild(rules);
    }
    var head = document.getElementsByTagName('head')[0];
    if (head) {
      head.appendChild(style_sheet);
    }
  }
}
5
Michael

Tout va bien, mais pour que styleNode.cssText fonctionne dans IE6 avec un nœud créé par javascipt, vous devez ajouter le nœud au document avant de définir le cssText;

informations complémentaires @ http://msdn.Microsoft.com/en-us/library/ms533698%28VS.85%29.aspx

4
Tony

Cette variable d'objet ajoutera une balise de style à la balise head avec l'attribut type et une règle de transition simple à l'intérieur qui correspond à chaque id/classe/élément. N'hésitez pas à modifier content property et à injecter autant de règles que nécessaire. Assurez-vous simplement que les règles css à l'intérieur de content restent dans une ligne (ou «échappez» à chaque nouvelle ligne, si vous préférez). 

var script = {

  type: 'text/css', style: document.createElement('style'), 
  content: "* { transition: all 220ms cubic-bezier(0.390, 0.575, 0.565, 1.000); }",
  append: function() {

    this.style.type = this.type;
    this.style.appendChild(document.createTextNode(this.content));
    document.head.appendChild(this.style);

}}; script.append();
4
Spooky

Cette fonction injectera grammaticalement les fichiers CSS chaque fois que vous appelez la fonction appendStyle comme suit: appendstyle('css you want to inject'). Cela fonctionne en injectant un nœud style dans l'en-tête du document. Il s'agit d'une technique similaire à celle utilisée par les utilisateurs pour charger paresseusement le javascript. cela fonctionne de manière constante dans la plupart des navigateurs.

appendStyle = function (content) {
      style = document.createElement('STYLE');
      style.type = 'text/css';
      style.appendChild(document.createTextNode(content));
      document.head.appendChild(style);

    }
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>

  <h1>this is injected css</h1>
  <p>heloo, this is stuff, hkasjdhakhd</p>
  <button onclick='appendStyle("body {background-color:#ff0000;} h1{font-family:Helvetica, sans-serif;font-variant:small-caps;letter-spacing:3px;color:#ff0000;background-color:#000000;} p {font-family:Georgia, serif;font-size:14px;font-style:normal;font-weight:normal;color:#000000;background-color:#ffff00;}")'>press me to inject css!</button>
</body>

</html>
Vous pouvez également charger des fichiers CSS externes en utilisant l'extrait de code suivant:

appendExternalStyle = function (content) {
      link = document.createElement('LINK');
      link.rel = 'stylesheet';
      link.href = content;
      link.type = 'text/css'; 
      document.head.appendChild(link);

    }
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>html{font-family: sans-serif; 
font-display: swap;}</style>
</head>
<body>

  <h1>this is injected css</h1>
  <p>heloo, this is stuff, hkasjdhakhd</p>
  <button onclick='appendExternalStyle("data:text/css;base64,OjotbW96LXNlbGVjdGlvbntjb2xvcjojZmZmIWltcG9ydGFudDtiYWNrZ3JvdW5kOiMwMDB9OjpzZWxlY3Rpb257Y29sb3I6I2ZmZiFpbXBvcnRhbnQ7YmFja2dyb3VuZDojMDAwfWgxe2ZvbnQtc2l6ZToyZW19Ym9keSxodG1se2NvbG9yOnJnYmEoMCwwLDAsLjc1KTtmb250LXNpemU6MTZweDtmb250LWZhbWlseTpMYXRvLEhlbHZldGljYSBOZXVlLEhlbHZldGljYSxzYW5zLXNlcmlmO2xpbmUtaGVpZ2h0OjEuNjd9YnV0dG9uLGlucHV0e292ZXJmbG93OnZpc2libGV9YnV0dG9uLHNlbGVjdHstd2Via2l0LXRyYW5zaXRpb24tZHVyYXRpb246LjFzO3RyYW5zaXRpb24tZHVyYXRpb246LjFzfQ==")'>press me to inject css!</button>
</body>

</html>

3
Joel Ellis
var list = document.querySelector("head");
list.innerHTML += '<style>
                      h3.header-6.basket-item--header 
                      span.cusplus {
                         color:#c00; 
                      }.
                      cusname{
                         color:grey;font-size:14px;
                      }
                  </style>';

200% de code de travail, exemple ci-dessus

0
Kabirr singh sahni

Tu as écrit:

var divNode = document.createElement("div");
divNode.innerHTML = "<br><style>h1 { background: red; }</style>";
document.body.appendChild(divNode);

Pourquoi pas ça?

var styleNode = document.createElement("style");
document.head.appendChild(styleNode);

Désormais, vous pouvez facilement ajouter des règles CSS au code HTML:

styleNode.innerHTML = "h1 { background: red; }\n";
styleNode.innerHTML += "h2 { background: green; }\n";

... ou directement au DOM:

styleNode.sheet.insertRule("h1 { background: red; }");
styleNode.sheet.insertRule("h2 { background: green; }");

J'espère que cela fonctionnera partout sauf pour les navigateurs archaïques.

Fonctionne certainement en Chrome en 2019.

0
7vujy0f0hy

Si le problème que vous rencontrez consiste à injecter une chaîne de CSS dans une page, il est plus facile de le faire avec l'élément <link> que l'élément <style>.

Ce qui suit ajoute la règle p { color: green; } à la page.

<link rel="stylesheet" type="text/css" href="data:text/css;charset=UTF-8,p%20%7B%20color%3A%20green%3B%20%7D" />

Vous pouvez créer ceci en JavaScript simplement en encodant votre chaîne de code CSS par l'URL et en lui ajoutant l'attribut HREF. Beaucoup plus simple que toutes les bizarreries d’éléments <style> ou d’accès direct aux feuilles de style.

let linkElement: HTMLLinkElement = this.document.createElement('link');
linkElement.setAttribute('rel', 'stylesheet');
linkElement.setAttribute('type', 'text/css');
linkElement.setAttribute('href', 'data:text/css;charset=UTF-8,' + encodeURIComponent(myStringOfstyles));

Cela fonctionnera à partir de IE 5.5

0
moefinley
0
Vinod Poorma