JavaScriptで<style>タグを作成する方法は?


336

<style>JavaScriptを使用してHTMLページにタグを挿入する方法を探しています。

これまでに見つけた最良の方法:

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. 動作している3つのブラウザーは素晴らしいですが、とにかく誰がChromeを使用していますか?

回答:


663

ではなくにstyle要素を追加してみてください。headbody

これは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
参考までにdocument.head、すべての主要ブラウザでサポートされています。
Rob W

30
@RobW-IE8以前ではサポートされていません。最新のブラウザでサポートされていますが、すべての主要なブラウザでサポートされているわけではありません。
Tim

5
なぜ使用しないのdocument.querySelector("head")ですか?それはソース
allenhwkim

8
@allenhwkim:回答はの導入以前のものquerySelector()です。今日、私はおそらくdocument.headIE9以降で利用可能です
クリストフ

2
アクセスする前に、スタイル要素をヘッドに追加する必要がありましたstyle.styleSheet.cssText。追加される前style.styleSheetはnullでした。
ウィルホーカー

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

これは、奇妙なCMSコンテキストで外部CSSファイルをロードする際に非常に役立ちました。addRule / removeRuleパーツで問題が発生したので、それらを排除しただけで、すべてが正常に動作しました。
Kirkman14 '27 / 09/27

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
(非常に遅くコメント)このような態度は、人々へのリードがためにIE6にロックされているものです「それはすべてがあなたの聴衆に依存します。あなたの聴衆の中に誰もChromeを使用していない場合、それは悩む必要はありません」 IE7とさえIE8が利用可能になった後。「しかし、私が使用しなければならない WebアプリケーションはIE6でのみ動作します」
Stephen P

1
ええ、あなたは正しいですし、私も必ずしもそうすることを主張しているわけではありません(したがって、「可能な限り多くの視聴者にリーチしたい場合は、すべての主要なAグレードのブラウザーをサポートするのが最善です」)。あなたのプラットフォームの聴衆は重要です。
トム・

31

<style>タグは<head>要素内の場所である必要があり、追加した各タグはタグの下部に追加する必要があります<head>

使用insertAdjacentHTMLをドキュメントにスタイルタグを注入するheadタグ

ネイティブ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>


2
これが最善かつ最も簡単な解決策です。ありがとうございます。
Ryzal Yusoff

同意します。これは最善でシンプルですが、CSSの制御が不十分な場合は、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がない-どういう意味ですか?relhreflink
クリストフ・

4
link要素は質問とどのように関係していますか?OPはstyle要素を要求しました。この回答は質問とは関係ありません
vsync

2
@vsync styleは、インラインスタイルを追加するためのものでlinkあり、スタイルシートソースに対しては適切です。これには、ブラウザ間の問題を回避できるという利点があります。
majick

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

デモ: codepenjsfiddle


最新のFirefox、Chromeで完璧に働いた、 IE8で(あるいは、少なくとも私は方法でそれを入力しました)。なぜこれ以上のポイントがないのか、本当にわかりません。
ハリーペコネン2015

これは有効ではないため、これ以上のポイントはありません。<style>タグの外に<head>タグを挿入するのも良いことではありません。スタイルタグは、<head>タグ内にのみ表示されます。これは広く採用されているHTML標準です。インラインスタイリングにはスタイル属性があり、スタイル属性は<body>タグ自体を含む<body>タグ内の任意のタグに適用できます。
不気味な2015

このコードは私にはうまくいきませんでした。私は3つのブラウザーで動作するはるかに短いコードを作成しました。ここに私の回答を掲載します。
デビッドスペクター

スタイルブロックをヘッドに動的に追加したときに、Chromeがスタイルを更新しなかった理由を理解できませんでした。私はこれを試しましたが、魔法のように更新されます。ブラウザでCSSを再レンダリングするトリガーとなるこのコードの実際の違いを調査する必要があります。しかし、大きな感謝!
プログラハンマー

5

このオブジェクト変数は、type属性とすべての単一のID /クラス/要素に一致する1つの単純な遷移ルール​​を含むスタイルタグをヘッドタグに追加します。コンテンツプロパティを自由に変更し、必要な数のルールを挿入してください。コンテンツ内のcssルールが1行にとどまることを確認してください(必要に応じて、新しい行ごとに「エスケープ」します)。

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
私はこのソリューションが好きだったので、自分でモバイルデバイスのボタンサイズを変更しましたが、コンテンツプロパティを1行に収める必要があるのは誤りです。
RufusVS 2018

そうだね。私は知っていて、それを知っていました。しかし、時々、私が思っているように書くのが面倒です。: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

この関数は、次のappendStyleような関数を呼び出すたびにcssを挿入します。
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);

今後は、HTMLコードにCSSルールを簡単に追加できます。

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

私はこれが古風なブラウザを除いてどこでも動作することを期待しています。

2019年にChrome 確実に機能します。


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

CSSの文字列をURLエンコードしてHREF属性を追加するだけで、JavaScriptでこれを作成できます。<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以降で機能します


場合によっては、スタイルブロックを動的にヘッドに挿入しても、スタイルが更新されませんでした。これはうまくいきます!
プログラハンマー

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.