¿Cómo crear una etiqueta <style> con Javascript?

Resuelto asked hace 15 años • 19 respuestas

Estoy buscando una manera de insertar una <style>etiqueta en una página HTML con JavaScript.

La mejor manera que encontré hasta ahora:

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

Esto funciona en Firefox, Opera e Internet Explorer pero no en Google Chrome. También es un poco feo con el <br>frente para IE.

¿Alguien sabe de una manera de crear una <style>etiqueta que

  1. es mejor

  2. ¿Funciona con Chrome?

O tal vez

  1. Esto es algo no estándar que debería evitar.

  2. Tres navegadores que funcionan son geniales y, de todos modos, ¿quién usa Chrome?

 avatar Feb 08 '09 05:02
Aceptado

Intente agregar el styleelemento en headlugar de body.

Esto fue probado en IE (7-9), Firefox, Opera y 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 avatar Feb 07 '2009 22:02 Christoph

<style>Las etiquetas deben colocarse dentro del <head>elemento y cada etiqueta agregada debe agregarse en la parte inferior de la <head>etiqueta.

Usando insertAdjacentHTML para inyectar una etiqueta de estilo en la etiqueta del encabezado del documento :

DOM nativo:

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


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

vsync avatar Feb 22 '2015 19:02 vsync
const style = document.createElement("style")
style.textContent = "h1 { background-color: red; }"
document.head.appendChild(style)

La forma moderna y sencilla

El código anterior es la esencia del mismo; continúa leyendo si quieres saber el razonamiento.

¿Por qué otra respuesta? La respuesta aceptada es antigua e incluye código redundante para navegadores obsoletos como Internet Explorer. Otras respuestas son innecesariamente complejas o utilizan propiedades como .innerHTMLlas que permiten ataques de secuencias de comandos entre sitios.

La typepropiedad no es necesaria.

La mayoría de las respuestas establecen la typepropiedad así: style.type = "text/css". No es necesario configurar esta propiedad a menos que necesite admitir navegadores más antiguos.

Según <style>: El elemento de información de estilo - HTML | MDN , el typeatributo es opcional y por defecto es text/css:

type

Este atributo define el lenguaje de estilo como un tipo MIME (no se debe especificar el juego de caracteres). Este atributo es opcional y su valor predeterminado es text/csssi no se especifica; valores distintos de la cadena vacía o text/cssno se utilizan. Nota : Hay muy pocas razones para incluir este atributo en los documentos web modernos.

Agregando el CSS

Para agregar CSS, utilícelo .textContentya que es más seguro y rápido que los métodos alternativos. Por el contrario .innerHTML, no analiza HTML y, por lo tanto, puede prevenir ataques de secuencias de comandos entre sitios .

Otra propiedad similar, .innerTextes similar .textContentpero tiene en cuenta los estilos CSS y representa sólo el contenido del texto "renderizado". Como no estamos interesados ​​en contenido sólo "renderizado", preferimos .textContent.

¿ Qué hace la configuración .textContent?

Establecer la .textContentpropiedad elimina todos los hijos del nodo (elemento) y los reemplaza con el valor de cadena dado.

¿Dónde colocar el elemento?

El elemento de estilo debe incluirse en el encabezado: "El <style>elemento debe incluirse dentro del <head>documento...". [ <estilo>... | MDN ]

Para obtener el uso principal document.head, ya que ha sido compatible con todos los principales navegadores durante mucho tiempo, por lo que no hay necesidad de otras alternativas.

touchmarine avatar Oct 10 '2021 12:10 touchmarine

Supongo que desea insertar una styleetiqueta en lugar de una linketiqueta (que hace referencia a un CSS externo), y eso es lo que hace el siguiente ejemplo:

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

Además, noté en tu pregunta que estás usando innerHTML. En realidad, esta es una forma no estándar de insertar datos en una página. La mejor práctica es crear un nodo de texto y agregarlo a otro nodo de elemento.

Con respecto a su pregunta final, escuchará a algunas personas decir que su trabajo debería funcionar en todos los navegadores. Todo depende de tu audiencia. Si nadie en tu audiencia usa Chrome, no te preocupes; sin embargo, si busca llegar a la mayor audiencia posible, lo mejor es admitir todos los principales navegadores de categoría A.

Tom avatar Feb 07 '2009 22:02 Tom

createStyleSheet()Aquí hay un script que agrega estilos y métodos de IE addRule()a los navegadores que no los tienen:

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

Puede agregar archivos externos a través de

document.createStyleSheet('foo.css');

y crear reglas dinámicamente a través de

var sheet = document.createStyleSheet();
sheet.addRule('h1', 'background: red;');
Christoph avatar Feb 07 '2009 23:02 Christoph