Bagaimana cara membuat tag <style> dengan Javascript?

336

Saya mencari cara untuk memasukkan <style>tag ke halaman HTML dengan JavaScript.

Cara terbaik yang saya temukan sejauh ini:

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

Ini berfungsi di Firefox, Opera dan Internet Explorer tetapi tidak di Google Chrome. Juga agak jelek dengan <br>di depan untuk IE.

Adakah yang tahu cara membuat <style>tag itu

  1. Lebih baik

  2. Bekerja dengan Chrome?

Atau mungkin

  1. Ini adalah hal yang tidak standar yang harus saya hindari

  2. Tiga browser yang berfungsi hebat dan siapa yang menggunakan Chrome?

Ameena sana
sumber

Jawaban:

663

Coba tambahkan styleelemen ke headbukan body.

Ini diuji di IE (7-9), Firefox, Opera dan 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));
}
Christoph
sumber
19
FYI, document.headdidukung di semua browser utama.
Rob W
30
@RobW - Tidak didukung di IE8 dan di bawah. Ini didukung di browser modern, tetapi tidak semua yang utama.
Tim
5
kenapa tidak pakai saja document.querySelector("head")? Acara ini didukung oleh IE8 oleh sumber
allenhwkim
8
@allenhwkim: jawabannya sebelum pengenalan querySelector(); hari ini, saya mungkin akan ikut document.head, tersedia sejak IE9
Christoph
2
Saya harus menambahkan elemen style ke kepala sebelum mengakses style.styleSheet.cssText. Sebelum itu ditambahkan style.styleSheetadalah nol.
Will Hawker
38

Berikut ini skrip yang menambahkan IE-style createStyleSheet()dan addRule()metode ke browser yang tidak memilikinya:

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

Anda dapat menambahkan file eksternal melalui

document.createStyleSheet('foo.css');

dan secara dinamis membuat aturan melalui

var sheet = document.createStyleSheet();
sheet.addRule('h1', 'background: red;');
Christoph
sumber
Ini sangat membantu saya dalam mencoba memuat file CSS eksternal dalam konteks CMS yang aneh. Saya memang mengalami beberapa masalah dengan bagian addRule / removeRule, jadi saya hanya menghilangkannya, dan semuanya bekerja dengan baik.
Kirkman14
33

Saya berasumsi bahwa Anda ingin menyisipkan styletag versus linktag (mereferensikan CSS eksternal), jadi itulah yang dilakukan contoh berikut:

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

Juga, saya perhatikan dalam pertanyaan Anda yang Anda gunakan innerHTML. Ini sebenarnya cara non-standar untuk memasukkan data ke halaman. Praktik terbaik adalah membuat simpul teks dan menambahkannya ke simpul elemen lain.

Sehubungan dengan pertanyaan terakhir Anda, Anda akan mendengar beberapa orang mengatakan bahwa pekerjaan Anda harus bekerja di semua browser. Itu semua tergantung pada audiens Anda. Jika tidak ada seorang pun di audiens Anda yang menggunakan Chrome, maka jangan khawatir; namun, jika Anda ingin menjangkau pemirsa sebesar mungkin, maka yang terbaik adalah mendukung semua browser kelas A utama

Tom
sumber
1
Ini pada dasarnya sama dengan solusi saya; tak satu pun dari mereka bekerja di IE!
Christoph
Menambahkan simpul teks tidak berfungsi di IE. Tetapi menempatkan elemen gaya di kepala membuat solusi saya berfungsi di Chrome! :-)
1
untuk IE, gunakanstyleNode.styleSheet.cssText = ...
Christoph
7
(Sangat terlambat komentar) "Itu semua tergantung pada audiens Anda. Jika tidak ada seorang pun di audiens Anda menggunakan Chrome, maka jangan berkeringat" Sikap ini adalah apa yang menyebabkan orang-orang terkunci ke IE6 selama bertahun - tahun setelah IE7 dan bahkan IE8 tersedia . "Tetapi aplikasi web yang harus saya gunakan hanya berfungsi di IE6"
Stephen P
1
Yap, Anda benar dan saya tidak perlu menganjurkan melakukan hal itu (maka keseluruhannya: "jika Anda ingin menjangkau pemirsa sebesar mungkin, maka yang terbaik adalah mendukung semua peramban kelas-A utama") tetapi mengetahui audiens untuk platform Anda adalah penting.
Tom
31

<style>tag harus ditempatkan di dalam <head>elemen, dan setiap tag yang ditambahkan harus ditambahkan ke bagian bawah <head>tag.

Menggunakan insertAdjacentHTML untuk menyuntikkan tag gaya ke tag kepala dokumen :

DOM asli:

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>

vsync
sumber
Setuju, ini yang terbaik dan sederhana tetapi hati-hati terhadap css yang disuntikkan dengan buruk jika Anda tidak bisa mengendalikannya!
Tanpa akhir
24

Contoh yang berfungsi dan sesuai dengan semua browser:

var ss = document.createElement("link");
ss.type = "text/css";
ss.rel = "stylesheet";
ss.href = "style.css";
document.getElementsByTagName("head")[0].appendChild(ss);
belaz
sumber
7
elemen yang salah: styletidak memiliki relatau hrefatribut - maksud Anda link?
Christoph
4
apa hubungannya linkelemen dengan pertanyaan? OP meminta styleelemen. Jawaban ini tidak ada hubungannya dengan pertanyaan
vsync
2
@vsync styleadalah untuk menambahkan gaya sebaris, linkbenar untuk sumber stylesheet dan ini memiliki keuntungan menghindari masalah lintas-peramban.
Majick
7

Seringkali ada kebutuhan untuk mengesampingkan aturan yang ada, jadi menambahkan gaya baru ke HEAD tidak berfungsi dalam setiap kasus.

Saya datang dengan fungsi sederhana ini yang merangkum semua pendekatan "append to the BODY" yang tidak valid dan hanya lebih nyaman untuk digunakan dan debug (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);

Demo: codepen , jsfiddle

Garlaro
sumber
Bekerja dengan sempurna di Firefox, Chrome, dan ie8 terbaru (atau setidaknya cara saya mengetiknya). Saya benar-benar tidak tahu mengapa ini tidak memiliki poin lebih banyak.
Harry Pehkonen
Ini tidak memiliki poin lagi, karena itu tidak valid, juga bukan hal yang baik untuk menyuntikkan <style>tag di luar <head>tag. Tag gaya harus muncul di tempat lain selain di dalam <head>tag. Itu standar html yang diadopsi secara luas. Ada atribut style untuk style inline dan atribut style dapat diterapkan ke tag apa pun di dalam <body>tag, termasuk <body>tag itu sendiri.
Seram
Kode ini tidak berfungsi untuk saya. Saya membuat beberapa kode yang jauh lebih pendek yang bekerja di tiga browser dan akan memposting jawaban saya di sini.
David Spector
Saya tidak tahu mengapa Chrome tidak memperbarui gaya saya ketika saya menambahkan blok gaya ke kepala secara dinamis. Saya mencoba ini dan secara ajaib memperbarui. Saya perlu menyelidiki apa sebenarnya perbedaan di sini dalam kode ini yang memicu browser untuk merender ulang css. Tapi terima kasih banyak!
Pemrogram
5

Variabel objek ini akan menambahkan tag gaya ke tag kepala dengan atribut tipe dan satu aturan transisi sederhana di dalam yang cocok dengan setiap id / kelas / elemen. Jangan ragu untuk memodifikasi properti konten dan menyuntikkan sebanyak mungkin aturan yang Anda butuhkan. Pastikan saja aturan css di dalam konten tetap berada dalam satu baris (atau 'lepas' setiap baris baru, jika Anda mau).

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();
Menyeramkan
sumber
1
Saya menyukai solusi ini, jadi saya menggunakannya sendiri untuk mengubah ukuran tombol pada perangkat seluler, tetapi tidak benar bahwa properti konten harus berada di satu baris: Cukup gabungkan beberapa string (lebih dari beberapa baris) dengan operator +.
RufusVS
Benar. Saya tahu dan saya tahu itu. Tetapi, kadang-kadang, saya terlalu malas untuk menulis seperti yang seharusnya. : D Cheers.
Spooky
5

Berikut adalah varian untuk menambahkan kelas secara dinamis

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);
    }
  }
}
Michael
sumber
4

Fungsi ini akan menyuntikkan css setiap kali Anda memanggil fungsi appendStyleseperti ini:
appendStyle('css you want to inject')

Ini berfungsi dengan menyuntikkan stylesimpul ke kepala dokumen. Ini adalah teknik yang mirip dengan apa yang biasa digunakan untuk memuat JavaScript. Ini bekerja secara konsisten di sebagian besar browser modern.

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>

Anda juga dapat malas memuat file CSS eksternal dengan menggunakan cuplikan berikut:

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>

Joel Ellis
sumber
Ini kira-kira pendekatan yang saya kembangkan secara mandiri. Singkat dan manis dan berfungsi di peramban Firefox, Microsoft Edge, dan Chrome terbaru. Tentu saja, ada terlalu banyak kesalahan JavaScript di Internet Explorer untuk dikhawatirkan termasuk dalam kompatibilitas browser lagi.
David Spector
3

Kau menulis:

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

Kenapa tidak ini?

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

Karenanya, Anda dapat menambahkan aturan CSS dengan mudah ke kode HTML:

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

... atau langsung ke DOM:

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

Saya berharap ini bekerja di mana saja kecuali browser kuno.

Pasti berfungsi di Chrome pada tahun 2019.

7vujy0f0hy
sumber
3

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

Sejauh ini solusi paling mudah. Yang harus Anda lakukan adalah mengetikkan sama seperti bagaimana Anda biasanya mendeklarasikan styletag, di antara backticks

Kabirr singh sahni
sumber
1
Hai dan selamat datang di situs ini. Meskipun kode ini dapat menyelesaikan masalah yang diberikan, Anda juga harus menyertakan penjelasan tentang bagaimana dan mengapa ia bekerja.
Radiodef
1

Jika masalah yang Anda hadapi adalah menyuntikkan string CSS ke halaman, lebih mudah melakukan ini dengan <link>elemen daripada <style>elemen.

Berikut ini menambahkan p { color: green; }aturan ke halaman.

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

Anda dapat membuat ini dalam JavaScript hanya dengan URL yang menyandikan string CSS Anda dan menambahkannya HREFatribut. Jauh lebih sederhana daripada semua kebiasaan <style>elemen atau secara langsung mengakses stylesheet.

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

Ini akan bekerja di IE 5.5 ke atas

moefinley
sumber
Menyuntikkan blok gaya secara dinamis ke kepala tidak memperbarui styling dalam beberapa kasus. Ini berhasil!
prograhammer
-1
this link may helpful to you: 

http://jonraasch.com/blog/javascript-style-node

Vinod Poorma
sumber
Tolong jangan gunakan blok teks / kode yang sudah diformat untuk paragraf pendek. Menghubungkan jawaban dengan cara ini juga tidak berguna. Silakan meringkas situs web terlebih dahulu.
FryingggPannn