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에서는 작동하지만 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
참고 document.head로 모든 주요 브라우저에서 지원됩니다.
Rob W

30
@RobW-IE8 이하에서는 지원되지 않습니다. 최신 브라우저에서는 지원되지만 모든 주요 브라우저에서는 지원되지 않습니다.
Tim

5
왜 그냥 사용하지 document.querySelector("head")않습니까? 그것은 소스에
allenhwkim

8
@allenhwkim : 대답은 소개보다 앞선다 querySelector(); 오늘은 document.headIE9부터 사용할 수 있습니다
Christoph

2
액세스하기 전에 스타일 요소를 머리에 추가해야했습니다 style.styleSheet.cssText. 추가되기 전에는 style.styleSheetnull이었습니다.
Will Hawker

38

IE 스타일 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;');

이것은 이상한 CMS 컨텍스트에서 외부 CSS 파일을로드하려고 할 때 매우 도움이되었습니다. 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에서 작동하지 않습니다!
Christoph

IE에서는 텍스트 노드를 추가 할 수 없습니다. 그러나 스타일 요소를 머리에 넣으면 Chrome에서 솔루션이 작동합니다! :-)

1
IE의 경우styleNode.styleSheet.cssText = ...
Christoph

7
(매우 늦게 의견) "모든 것은 청중에 달려 있습니다. 청중 중 아무도 크롬을 사용하지 않는다면 땀을 흘리지 마십시오."이러한 태도는 사람들이 IE7 이후 IE6 이후 몇 년 동안 IE6에 갇히게 합니다. . "하지만 웹 응용 프로그램 은 IE6 에서만 작동합니다"
Stephen P

1
그렇습니다, 당신 말이 맞아요. 필자가 그렇게하도록 옹호하는 것은 아닙니다. (따라서 전체 : "가장 많은 잠재 고객에게 다가 가려면 모든 주요 A 급 브라우저를 지원하는 것이 가장 좋습니다") 플랫폼의 잠재 고객이 중요합니다.
Tom

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있습니까?
Christoph

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

데모 : codepen , jsfiddle


최신 Firefox, Chrome ie8 (또는 적어도 내가 입력 한 방식)에서 완벽하게 작동했습니다 . 나는 이것이 왜 더 많은 포인트가 없는지 정말로 모른다.
Harry Pehkonen

유효하지 않기 때문에 더 이상 포인트가 없습니다 . <style>태그 외부에 <head>태그 를 삽입하는 것도 좋지 않습니다 . 스타일 태그는 다른 곳에는 없지만 <head>태그 내에 나타납니다 . 그것은 html 표준으로 널리 채택되었습니다. 인라인 스타일링을위한 스타일 속성이 있으며 스타일 속성은 태그 자체를 <body>포함하여 <body>태그 내의 모든 태그에 적용 할 수 있습니다 .
Spooky

이 코드는 나를 위해 작동하지 않았습니다. 나는 세 개의 브라우저에서 작동하는 훨씬 더 짧은 코드를 만들었고 여기에 내 대답을 게시 할 것입니다.
David Spector

스타일 블록을 머리에 동적으로 추가했을 때 Chrome에서 스타일이 업데이트되지 않은 이유를 알 수 없었습니다. 나는 이것을 시도했고 마술처럼 그것을 업데이트했다. 브라우저에서 CSS를 다시 렌더링하도록 트리거하는이 코드의 차이점이 무엇인지 조사해야합니다. 그러나 큰 감사합니다!
prograhammer

5

이 객체 변수는 유형 속성과 모든 단일 id / class / element와 일치하는 하나의 간단한 전환 규칙을 사용하여 스타일 태그를 헤드 태그에 추가합니다. 콘텐츠 속성 을 수정 하고 필요한만큼 규칙을 삽입하십시오. 콘텐츠 내의 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 건배.
Spooky

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 오류가있어서 브라우저 호환성에 더 이상 포함되지 않을 수도 있습니다.
David Spector

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

나는 이것이 구식 브라우저를 제외한 모든 곳에서 작동 할 것으로 기대합니다.

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 이상에서 작동합니다


스타일 블록을 머리에 동적으로 주입해도 스타일이 업데이트되지 않는 경우가있었습니다. 그래도 작동합니다!
prograhammer

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.