Как создать тег <style> с помощью Javascript?

Я ищу способ вставить <style> в HTML-страницу с JavaScript.

Лучший способ, который я нашел до сих пор:

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

Это работает в Firefox, Opera и Internet Explorer, но не в Google Chrome. Кроме того, немного некрасиво с <br> в передней панели для IE.

Кто-нибудь знает способ создания <style> который

  1. Лучше

  2. Работает с Chrome?

Или, может быть

  1. Это нестандартная вещь, которую я должен избегать

  2. Три рабочих браузера великолепны, и кто все-таки использует Chrome?

Ответ 1

Попробуйте добавить элемент style к head а не к body.

Это было проверено в IE (7-9), Firefox, Opera и Chrome:

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

head.appendChild(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));
}

Ответ 2

Здесь script, который добавляет методы createStyleSheet() и addRule() в стиле IE в браузерах, которые их не имеют:

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;
    })();
}

Вы можете добавить внешние файлы через

document.createStyleSheet('foo.css');

и динамически создавать правила через

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

Ответ 3

Я предполагаю, что вы хотите вставить тег style по сравнению с тегом link (ссылаясь на внешний CSS), так, как показано в следующем примере:

<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>

Кроме того, я заметил в вашем вопросе, что вы используете innerHTML. Это фактически нестандартный способ вставки данных в страницу. Лучшей практикой является создание текста node и добавление его к другому элементу node.

Что касается вашего последнего вопроса, вы услышите, как некоторые люди говорят, что ваша работа должна работать во всех браузерах. Все зависит от вашей аудитории. Если никто в вашей аудитории не использует Chrome, то не потейте; однако, если вы хотите максимально охватить самую большую аудиторию, лучше всего поддерживать все основные браузеры класса A

Ответ 4

Пример, который работает и совместим со всеми браузерами:

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

Ответ 5

Теги <style> должны находиться в пределах элемента <head>, и каждый добавленный тег должен добавляться в конец тега <head>.

Использование insertAdjacentHTML для вставки тега стиля в тег заголовка документа:

Родной DOM:

document.head.insertAdjacentHTML("beforeend", '<style>body{background:red}</style>')

Ответ 6

Зачастую существует необходимость переопределить существующие правила, поэтому добавление новых стилей в HEAD не работает в каждом случае.

Я придумал эту простую функцию, которая суммирует все подходы недействительные "к подходу BODY" и удобнее всего использовать и отлаживать (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);

Демо: codepen, jsfiddle

Ответ 7

Вот вариант для динамического добавления класса

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);
    }
  }
}

Ответ 8

Эта переменная объекта добавит тег стиля к тегу head с атрибутом типа и одним простым правилом перехода внутри, которое соответствует каждому элементу id/class/. Не стесняйтесь изменять свойство content и вводить столько правил, сколько вам нужно. Просто убедитесь, что правила css внутри контента остаются в одной строке (или "удаляют" каждую новую строку, если вы так предпочитаете).

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();

Ответ 9

Все хорошо, но для styleNode.cssText для работы в IE6 с узлом, созданным javascipt, вам нужно добавить узел в документ перед установкой cssText;

Дополнительная информация @http://msdn.microsoft.com/en-us/library/ms533698%28VS.85%29.aspx

Ответ 10

Эта функция будет грамматически внедрять css всякий раз, когда вы вызываете функцию appendStyle следующим образом: appendstyle('css you want to inject'). это работает, вставляя узел style в заголовок документа. это метод, подобный тому, что люди используют для отложенной загрузки javascript. это работает последовательно в большинстве браузеров.

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>

Ответ 11

Вы написали:

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

Почему не это?

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

Отныне вы можете легко добавлять правила CSS в код HTML:

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

... или напрямую в DOM:

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

Я ожидаю, что это будет работать везде, кроме устаревших браузеров.

Определенно работает в Chrome в 2019 году.

Ответ 12

Если проблема, с которой вы столкнулись, представляет собой строку CSS на странице, проще сделать это с помощью элемента <link> чем элемента <style>.

Следующие добавляет p { color: green; } p { color: green; } на странице.

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

Вы можете создать это на JavaScript просто по URL-адресу, кодирующему строку CSS, и добавлению атрибута HREF. Гораздо проще, чем все причуды элементов <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));

Это будет работать в IE 5.5 вверх

Ответ 13

document.head.innerHTML += '
  <style>
    h1 {
      color: red; 
    }
    p {
      color: blue;
    }
  </style>'
<h1>I'm red!</h1>
<p>I'm blue!</p>

Ответ 14

Самый короткий лайнер

// One liner function:
const addCSS = (s)=>((d,e)=>{ e = d.createElement("style");e.innerHTML = s;d.head.appendChild(e)})(document);

// Usage: 
addCSS("body{ background:red; }")