Як створити тег <style> за допомогою Javascript?


336

Я шукаю спосіб вставити <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?

Відповіді:


663

Спробуйте додати 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));
}

19
FYI, document.headпідтримується у всіх основних браузерах.
— Роб Ш

30
@RobW - Не підтримується в IE8 та нижче. Він підтримується в сучасних браузерах, але не у всіх основних.
— Тім

5
чому б не просто використовувати document.querySelector("head")? Це подія, яку підтримує IE8 від джерела
— allenhwkim

8
@allenhwkim: відповідь передує введенню querySelector(); Сьогодні я, мабуть, пішов би з document.head, доступний з IE9
— Крістоф

2
Мені довелося додати елемент стилю до голови перед тим, як отримати доступ style.styleSheet.cssText. До того, як це було додано, style.styleSheetбуло недійсним.
— Буде Хоукер

38

Ось сценарій, який додає стиль IE createStyleSheet()та addRule()методи браузерам, у яких їх немає:

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

Це мені дуже допомогло при спробі завантажити зовнішній файл CSS у дивному контексті CMS. У мене виникли проблеми з частиною addRule / removeRule, тому я просто усунув їх, і все працює добре.
— Kirkman14

33

Я припускаю, що ви хочете вставити 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. Це насправді нестандартний спосіб вставлення даних у сторінку. Найкраща практика - створити текстовий вузол і додати його до іншого вузла елемента.

Що стосується вашого останнього запитання, ви почуєте, як деякі люди говорять, що ваша робота повинна працювати у всіх браузерах. Все залежить від вашої аудиторії. Якщо ніхто у вашій аудиторії не використовує Chrome, тоді не потійте його; Однак, якщо ви хочете охопити якомога більше аудиторії, то краще підтримати всі основні браузери A класу


1
Це в основному те саме, що і моє рішення; жоден з них не працює в IE!
— Крістоф

Додавання текстового вузла не працює в IE. Але введення елемента стилю в голову змушує моє рішення працювати в Chrome! :-)

1
для IE, використовуйтеstyleNode.styleSheet.cssText = ...
— Крістоф

7
(Дуже пізній коментар) "Все залежить від вашої аудиторії. Якщо ніхто з вашої аудиторії не користується Chrome, то не потійте його" Це ставлення - це те, що призводить до того, що люди заблоковані в IE6 роками після того, як IE7 і навіть IE8 є доступними . "Але веб-додаток, який я маю використовувати, працює лише в IE6"
— Stephen P

1
Так, ти маєш рацію, і я не обов'язково виступаю за те, щоб це робити (отже, і ціле: "якщо ти хочеш досягти якомога більшої аудиторії, то найкраще підтримати всі основні браузери A класу"), але знаючи аудиторія для вашої платформи важлива.
— Том

31

<style>теги повинні бути місцями в межах <head>елемента, а кожен доданий тег повинен бути доданий внизу <head>тегу.

Використання insertAdjacentHTML , щоб ввести тег стилю в документ голови тег :

Рідний DOM:

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


jQuery :

$('<style>').text("body{background:red}").appendTo(document.head)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


Погодьтеся, це найкраще і просто, але стежте за погано введеним CSS, якщо ви не контролюєте це!
— Нескінченний

24

Приклад, який працює і відповідає всім браузерам:

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

7
неправильний елемент: styleне має relабо hrefатрибута - ти мав на увазі link?
— Крістоф

4
що стосується linkелемента до питання? ОП попросили styleелемента. Ця відповідь не має нічого спільного з питанням
— vsync

2
@vsync style- це додавання вбудованих стилів, linkє правильним для джерел таблиць стилів, і це має перевагу уникнути проблем із перехресними веб-переглядачами.
— травень

7

Часто виникає необхідність змінити існуючі правила, тому додавання нових стилів до 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


Ідеально працював в останніх Firefox, Chrome і в ie8 (або, принаймні, так, як я його набрав). Я дійсно не знаю, чому це не має більше балів.
— Гаррі Пеконен

У цьому немає більше балів, оскільки це не вірно, ні добре вводити <style>тег за межами <head>тегу. Тег стилів не повинен з’являтися ніде більше, крім <head>тегу. Це широко прийнятий стандарт html. Є атрибут стилю для вбудованого стилю, а атрибут стилю може бути застосований до будь-якого тегу в <body>тезі, включаючи <body>тег його самостійно.
— Моторошний

Цей код для мене не працював. Я створив якийсь набагато коротший код, який працює в трьох браузерах, і я опублікую тут свою відповідь.
— Девід Спектор

Я не міг зрозуміти, чому Chrome не оновлює мої стилі, коли я динамічно додав блок стилів до голови. Я спробував це і магічно оновив. Мені потрібно дослідити, в чому насправді різниця тут у цьому коді, який запускає браузер для повторного відображення css. Але, велике спасибі!
— prograhammer

5

Ця змінна об’єкт додасть тег стилю до тегу head з атрибутом типу та одним простим правилом переходу всередині, що відповідає кожному окремому id / class / елементу. Не соромтеся змінювати властивість вмісту та вводити стільки правил, скільки вам потрібно. Просто переконайтеся, що правила 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();

1
Мені це рішення сподобалось, тому я використовував його сам, щоб змінити розміри кнопок на мобільних пристроях, але неправильно, що властивість вмісту має бути в одному рядку: просто об'єднайте кілька рядків (через кілька рядків) з оператором +.
— RufusVS

Правда. Я знаю і це знав. Але іноді мені просто лінь писати так, як мені належить. : D Ура.
— Моторошний

5

Ось варіант для динамічного додавання класу

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


4

Ця функція буде вводити 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>Lorem Ipsum</h1>
  <p>dolar sit amet</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>

Ви також можете ледаче завантажувати зовнішні файли CSS, використовуючи такий фрагмент:

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>Lorem Ipsum</h1>
  <p>dolar sit amet</p>
  <button onclick='appendExternalStyle("data:text/css;base64,OjotbW96LXNlbGVjdGlvbntjb2xvcjojZmZmIWltcG9ydGFudDtiYWNrZ3JvdW5kOiMwMDB9OjpzZWxlY3Rpb257Y29sb3I6I2ZmZiFpbXBvcnRhbnQ7YmFja2dyb3VuZDojMDAwfWgxe2ZvbnQtc2l6ZToyZW19Ym9keSxodG1se2NvbG9yOnJnYmEoMCwwLDAsLjc1KTtmb250LXNpemU6MTZweDtmb250LWZhbWlseTpMYXRvLEhlbHZldGljYSBOZXVlLEhlbHZldGljYSxzYW5zLXNlcmlmO2xpbmUtaGVpZ2h0OjEuNjd9YnV0dG9uLGlucHV0e292ZXJmbG93OnZpc2libGV9YnV0dG9uLHNlbGVjdHstd2Via2l0LXRyYW5zaXRpb24tZHVyYXRpb246LjFzO3RyYW5zaXRpb24tZHVyYXRpb246LjFzfQ==")'>press me to inject css!</button>
</body>

</html>


Це приблизно той підхід, який я розробив самостійно. Короткий і милий, працює в останніх браузерах Firefox, Microsoft Edge та Chrome. Звичайно, в Internet Explorer занадто багато помилок JavaScript, щоб переживати про включення його у сумісність браузера.
— Девід Спектор

3

Ти написав:

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 році.


3

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

На сьогодні найпростішим рішенням. Все, що вам потрібно зробити, це ввести те саме, що і те, як ви зазвичай оголошували styleтеги, між підмурками


1
Привіт і ласкаво просимо на сайт. Хоча цей код може вирішити дану проблему, ви також повинні включити пояснення, як і чому він працює.
— Radiodef

1

Якщо проблема, з якою ви стикаєтеся, вводить рядок CSS на сторінку, зробити це з <link>елементом простіше, ніж<style> елементом.

Далі додається 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 вище


Динамічне введення блоку стилів у голову в деяких випадках не оновлювало стиль. Це працює, хоча!
— програмамер

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.