¿Cómo crear una etiqueta <style> con Javascript?
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
es mejor
¿Funciona con Chrome?
O tal vez
Esto es algo no estándar que debería evitar.
Tres navegadores que funcionan son geniales y, de todos modos, ¿quién usa Chrome?
Intente agregar el style
elemento en head
lugar 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));
}
<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>`)
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>
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 .innerHTML
las que permiten ataques de secuencias de comandos entre sitios.
La type
propiedad no es necesaria.
La mayoría de las respuestas establecen la type
propiedad 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 type
atributo 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/css
si no se especifica; valores distintos de la cadena vacía otext/css
no se utilizan. Nota : Hay muy pocas razones para incluir este atributo en los documentos web modernos.
Agregando el CSS
Para agregar CSS, utilícelo .textContent
ya 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, .innerText
es similar .textContent
pero 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 .textContent
propiedad 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.
Supongo que desea insertar una style
etiqueta en lugar de una link
etiqueta (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.
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;');