¿Cómo se agrega CSS con Javascript?

154

¿Cómo se agregan reglas CSS (por ejemplo strong { color: red }) mediante el uso de Javascript?

nickf
fuente
misma pregunta (la respuesta es crossbrowser jQuery) stackoverflow.com/a/266110/341744
ninMonkey
18
@monkey: Esa es una solución bastante pobre, y en realidad no hace lo que se le pidió aquí. por ejemplo: qué sucede si <strong>se agrega un nuevo elemento al documento.
nickf

Respuestas:

115

También puede hacerlo utilizando las interfaces CSS de nivel 2 DOM ( MDN ):

var sheet = window.document.styleSheets[0];
sheet.insertRule('strong { color: red; }', sheet.cssRules.length);

... en todos menos (naturalmente) IE8 y anteriores, que utilizan su propia redacción marginalmente diferente:

sheet.addRule('strong', 'color: red;', -1);

Hay una ventaja teórica en esto en comparación con el método createElement-set-innerHTML, en que no tiene que preocuparse por poner caracteres HTML especiales en innerHTML, pero en la práctica los elementos de estilo son CDATA en HTML heredado y '<' y '&' rara vez se usan en hojas de estilo de todos modos.

Necesita una hoja de estilo en su lugar antes de que pueda comenzar a agregarla de esta manera. Puede ser cualquier hoja de estilo activa existente: externa, incrustada o vacía, no importa. Si no hay uno, la única forma estándar de crearlo en este momento es con createElement.

bobince
fuente
"color" .. oh si, ¡Uy! afortunadamente eso fue solo un ejemplo. Sospeché que podría haber un método DOM para esto, ¡gracias! +1
nickf
14
la hoja proviene sheet = window.document.styleSheets[0] (debe tener al menos un <style type = "text / css"> </style> allí).
AJP
1
Gracias, todos los ejemplos que Google muestra primero son tan grandes cuando todo lo que necesitaba era actualizar mi memoria en estas dos líneas.
ElDoRado1239
1
Sé que ha pasado mucho tiempo, pero cuando probé la primera, lleguéSecurityError: The operation is insecure.
user10089632
3
@ user10089632 la hoja de estilo a la que está accediendo debe servirse desde el mismo host que el documento principal para que esto funcione.
bobince
225

El enfoque simple y directo es crear y agregar un nuevo stylenodo al documento.

// Your CSS as text
var styles = `
    .qwebirc-qui .ircwindow div { 
        font-family: Georgia,Cambria,"Times New Roman",Times,serif;
        margin: 26px auto 0 auto;
        max-width: 650px;
    }
    .qwebirc-qui .lines {
        font-size: 18px;
        line-height: 1.58;
        letter-spacing: -.004em;
    }

    .qwebirc-qui .nicklist a {
        margin: 6px;
    }
`

var styleSheet = document.createElement("style")
styleSheet.type = "text/css"
styleSheet.innerText = styles
document.head.appendChild(styleSheet)
Ben Blank
fuente
12
¿No debería adjuntarse a la cabeza del documento en lugar del cuerpo?
bobince 01 de
3
@bobince: de acuerdo con las especificaciones HTML, absolutamente, pero todos los navegadores las reconocen en cualquier lugar. document.bodyTambién es más corto de escribir y más rápido de ejecutar que document.getElementsByTagName("head")[0]y evita los problemas de navegador cruzado de insertRule / addRule.
Ben Blank el
44
La solución debe ser seguida por un largo "duhhhh". No puedo creer que no lo haya pensado.
George Mauer
8
En todos los navegadores recientes solo puede usar document.head.appendChild.
Gajus
2
¡Esta solución es mucho mejor! Imagine que tiene más de una hoja de estilo: con la solución @bobince, su segundo CSS agregado podría sobrescribirse por el segundo / tercero / etc. hoja de estilo en la página. Al document.body.appendChild(css);usarlo, asegúrese de que el nuevo CSS siempre sea la última regla.
AvL
27

La solución de Ben Blank no funcionaría en IE8 para mí.

Sin embargo, esto funcionó en IE8

function addCss(cssCode) {
var styleElement = document.createElement("style");
  styleElement.type = "text/css";
  if (styleElement.styleSheet) {
    styleElement.styleSheet.cssText = cssCode;
  } else {
    styleElement.appendChild(document.createTextNode(cssCode));
  }
  document.getElementsByTagName("head")[0].appendChild(styleElement);
}
Chris Herring
fuente
12
El viejo IE siempre hace la vida más fácil
Alex W
2
Debe agregar el elemento a la configuración head anterior.cssText , o IE6-8 se bloqueará si cssCodecontiene un @ -directivo, como @importo @font-face, consulte la Actualización de phpied.com/dynamic-script-and-style-elements-in-ie y stackoverflow .com / a / 7952904
Han Seoul-Oh,
24

Aquí hay una versión ligeramente actualizada de la solución de Chris Herring , teniendo en cuenta que también puede usarla innerHTMLen lugar de crear un nuevo nodo de texto:

function insertCss( code ) {
    var style = document.createElement('style');
    style.type = 'text/css';

    if (style.styleSheet) {
        // IE
        style.styleSheet.cssText = code;
    } else {
        // Other browsers
        style.innerHTML = code;
    }

    document.getElementsByTagName("head")[0].appendChild( style );
}
Fornido
fuente
3
Debe agregar el elemento a la configuración head anterior.cssText , o IE6-8 se bloqueará si codecontiene un @ -directivo, como @importo @font-face, consulte la Actualización de phpied.com/dynamic-script-and-style-elements-in-ie y stackoverflow .com / a / 7952904
Han Seoul-Oh,
5

El más corto One Liner

// One liner function:
const addCSS = s =>(d=>{d.head.appendChild(d.createElement("style")).innerHTML=s})(document);

// Usage: 
addCSS("body{ background:red; }")

pollos
fuente
3

Puede agregar clases o atributos de estilo elemento por elemento.

Por ejemplo:

<a name="myelement" onclick="this.style.color='#FF0';">text</a>

Dónde podría hacer this.style.background, this.style.font-size, etc. También puede aplicar un estilo usando este mismo método ala

this.className='classname';

Si desea hacer esto en una función de JavaScript, puede usar getElementByID en lugar de 'this'.

mingala
fuente
55
JavaScript en línea usando controladores de eventos es una muy mala idea. Debería separar su contenido de su funcionalidad y enlazar controladores de eventos en JavaScript, preferiblemente en un archivo externo.
Coronel Sponsz
3

Este sencillo ejemplo de add <style>in head of html

var sheet = document.createElement('style');
sheet.innerHTML = "table th{padding-bottom: 0 !important;padding-top: 0 !important;}\n"
+ "table ul {    margin-top: 0 !important;    margin-bottom: 0 !important;}\n"
+ "table td{padding-bottom: 0 !important;padding-top: 0 !important;}\n"
+ ".messages.error{display:none !important;}\n"
+ ".messages.status{display:none !important;} ";

document.body.appendChild(sheet); // append in body
document.head.appendChild(sheet); // append in head

Estilo dinámico de origen : manipulación de CSS con JavaScript

DarckBlezzer
fuente
3

Recientemente, YUI agregó una utilidad específicamente para esto. Ver stylesheet.js aquí.

Russell Leggett
fuente
Actualmente estoy usando YUI para mi trabajo y estaba tratando de descubrir cómo editar hojas de estilo externas de reglas CSS existentes. No sabía sobre esta utilidad, ¡parece perfecto! Gracias Russell
Jaime
2

Esta es mi solución para agregar una regla css al final de la última lista de hojas de estilo:

var css = new function()
{
    function addStyleSheet()
    {
        let head = document.head;
        let style = document.createElement("style");

        head.appendChild(style);
    }

    this.insert = function(rule)
    {
        if(document.styleSheets.length == 0) { addStyleSheet(); }

        let sheet = document.styleSheets[document.styleSheets.length - 1];
        let rules = sheet.rules;

        sheet.insertRule(rule, rules.length);
    }
}

css.insert("body { background-color: red }");
Martin Wantke
fuente
1

Otra opción es usar JQuery para almacenar la propiedad de estilo en línea del elemento, agregarla y luego actualizar la propiedad de estilo del elemento con los nuevos valores. Como sigue:

function appendCSSToElement(element, CssProperties)
        {
            var existingCSS = $(element).attr("style");

             if(existingCSS == undefined) existingCSS = "";

            $.each(CssProperties, function(key,value)
            {
                existingCSS += " " + key + ": " + value + ";";
            });

            $(element).attr("style", existingCSS);

            return $(element);
        }

Y luego ejecútelo con los nuevos atributos CSS como un objeto.

appendCSSToElement("#ElementID", { "color": "white", "background-color": "green", "font-weight": "bold" });

Este puede no ser necesariamente el método más eficiente (estoy abierto a sugerencias sobre cómo mejorar esto. :)), pero definitivamente funciona.

XtraSimplicity
fuente
1

Aquí hay una plantilla de muestra para ayudarlo a comenzar

Requiere 0 bibliotecas y usa solo javascript para inyectar tanto HTML como CSS.

La función fue prestada del usuario @Husky arriba

Útil si desea ejecutar un script de tampermonkey y desea agregar una superposición de alternar en un sitio web (por ejemplo, una aplicación de notas, por ejemplo)

// INJECTING THE HTML
document.querySelector('body').innerHTML += '<div id="injection">Hello World</div>';

// CSS INJECTION FUNCTION
///programming/707565/how-do-you-add-css-with-javascript
function insertCss( code ) {
    var style = document.createElement('style');
    style.type = 'text/css';
    if (style.styleSheet) {
        // IE
        style.styleSheet.cssText = code;
    } else {
        // Other browsers
        style.innerHTML = code;
    }
    document.getElementsByTagName("head")[0].appendChild( style );
}

// INJECT THE CSS INTO FUNCTION
// Write the css as you normally would... but treat it as strings and concatenate for multilines
insertCss(
  "#injection {color :red; font-size: 30px;}" +
  "body {background-color: lightblue;}"
)

Vincent Tang
fuente
1

Si sabe que <style>existe al menos una etiqueta en la página, use esta función:

CSS=function(i){document.getElementsByTagName('style')[0].innerHTML+=i};

uso:

CSS("div{background:#00F}");

fuente
0

Aquí está mi función de propósito general que parametriza el selector CSS y las reglas, y opcionalmente toma un nombre de archivo css (distingue entre mayúsculas y minúsculas) si desea agregar a una hoja en particular (de lo contrario, si no proporciona un nombre de archivo CSS, se creará un nuevo elemento de estilo y lo agregará al encabezado existente. Creará como máximo un nuevo elemento de estilo y lo reutilizará en futuras llamadas a funciones). Funciona con FF, Chrome e IE9 + (quizás también antes, sin probar).

function addCssRules(selector, rules, /*Optional*/ sheetName) {
    // We want the last sheet so that rules are not overridden.
    var styleSheet = document.styleSheets[document.styleSheets.length - 1];
    if (sheetName) {
        for (var i in document.styleSheets) {
            if (document.styleSheets[i].href && document.styleSheets[i].href.indexOf(sheetName) > -1) {
                styleSheet = document.styleSheets[i];
                break;
            }
        }
    }
    if (typeof styleSheet === 'undefined' || styleSheet === null) {
        var styleElement = document.createElement("style");
        styleElement.type = "text/css";
        document.head.appendChild(styleElement);
        styleSheet = styleElement.sheet;
    }

    if (styleSheet) {
        if (styleSheet.insertRule)
            styleSheet.insertRule(selector + ' {' + rules + '}', styleSheet.cssRules.length);
        else if (styleSheet.addRule)
            styleSheet.addRule(selector, rules);
    }
}
Jon
fuente
-1

utilizar .cssen Jquery como$('strong').css('background','red');

$('strong').css('background','red');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<strong> Example
</strong> 

Zain Ali
fuente
1
javascript, OP no dice nada sobre jQuery
agapitocandemor