Hojas de estilo con JavaScript
por Francisco José Súñer Iglesias

Este artículo requiere conocimientos básicos de JavaScript y CSS

Netscape propuso en su tiempo una forma de definir hojas de estilo mediante JavaScript. Aquello fue un fracaso ya que Microsoft no adoptó la especificación y tras la caída de Netscape y el advemiento de la Fundación Mozilla no tuvo continuidad en Firefox.

No obstante, es perfectamente posible manipular los estilos de una web mediante JavaScript y el método getElementById, de esta forma;

document.getElementById('IdElemento').style.color = '#FFAA00';

Es decir, el color del elemento identificado con IdElemento cambiará a #FFAA00. Esto, que es muy útil, sobre todo a la hora de jugar con la visibilidad de los elementos (por ejemplo, las famosas solapas), no nos sirve puesto que lo que pretendemos es definir una hoja de estilo completa, con sus clases y etiquetas personalizadas mediante JavaScritpt puro y duro. ¿Con qué finalidad? ¿No se desaconseja expresamente mezclar cosas y separar el HTML, el JavaScript y los Estilos? En muchas ocasiones encontramos utilidades (menús, editores, generadores de gráficos) escritas en JavaScript que además necesitan de su propia hoja de estilo. La cuestión se convierte en un engorro cuando hay que añadir y mantener ambas por separado, o modificar nuestra propia hoja de estilo con las nuevas clases que puede ser que no se utilicen en toda la web y resulten un peso muerto la mayor parte de las ocasiones. De modo que ¿por qué no incluir la hoja de estilo dentro del archivo con el código de la utilidad?

La ventaja añadida es que resultará más sencillo aún retocar el estilo sin necesidad de modificar varios archivos, simplemente modificando las variables que asignemos a los valores de color o aspecto de los elementos conseguimos modificarlos allá donde aparezcan, sin que esto suponga buscarlos uno a uno por la hoja con los consiguientes olvidos e inconsistencias (si, aún usando el buscar y reemplazar todo), y todo esto sin engordar demasiado el peso total del código de la aplicación + hojas de estilo.

La cuestión está en manipular un poco el modelo de objetos de la página, el famoso DOM (Document Object Model), mediante las funciones createElement y appendChild, para los navegadores estándar, y styleSheet para Internet Explorer (principalmente, por culpa del incombustible IE 6.0).

Pero por lo pronto escribamos la hoja de estilo. La cosa es tan sencilla como asignar a una variable la cadena con los estilos. Así:

var fuente = 'arial, sans-serif;'; var Estilos = '' + '.serie_articulos {' + 'font-family:' + fuente + 'font-size: 11pt;' + 'font-weight: bold; ' + 'font-style: italic; ' + 'padding-bottom: 9px; ' + 'color: #800000;' + 'background-color: transparent; ' + '}' + '.titulo_articulo {' + 'font-family:' + fuente + 'font-size: 12pt;' + 'font-weight: bold;' + 'font-style: italic;' + 'padding-bottom: 7px;' + 'color: #600000;' + 'background-color: transparent;' + '}' + '.autor_articulo {' + 'font-family:' + fuente + 'font-size: 10pt;' + 'font-weight: bold;' + 'padding-bottom: 5px;' + '}';

Es obviamente más laborioso porque hay que añadir las comillas y los signos de concatenación, pero sigue siendo igual de legible que una hoja de estilos estándar. La primera línea con la cadena vacía es un pequeño truco para facilitar aún más la legibilidad. Lo interesante viene con la asignación de la variable fuente, con ello, si en un momento determinado queremos cambiar la tipografía de nuestros estilos basta con modificar esa variable. El ;'; (punto y coma, comilla, punto y coma) con el que acaba la asignación es correcto. Date cuenta que el punto y coma a la izquierda de la comilla cerrará la asignación de la propiedad del estilo y la de la derecha finaliza la sentencia JavaScript.

Volvamos a createElement y appendChild. Con createElement creamos un nuevo elemento DOM, puede ser un párrafo, una capa, lo que se te ocurra, en este caso se tratará de un estilo:

var Hoja = document.createElement ('style');

A continuación definimos los atributos de Hoja, que será, básicamente, el tipo, de texto, e indicando que se trata de estilos CSS.

Hoja.type = 'text/css';

A Hoja le tendremos que dar un contenido, en este caso los estilos que ya hemos asignado a la variable Estilos, pero para ello, y como habitual, tendremos un método estándar y el método que utiliza el Internet Explorer. La forma correcta de hacerlo según el modelo DOM sería:

Hoja.appendChild (document.createTextNode (Estilos));

Es decir, que añadimos al elemento Hoja el texto Estilos.

Para Microsoft eso es poco creativo e implementaron su propia solución:

Hoja.styleSheet.cssText = Estilos;

¿Cómo soslayar el problema de averiguar qué navegador nos está visitando, fácil, preguntado si entiende styleSheet, si es así, se usa el método de Microsoft, y de no ser así, el correcto:

if (Hoja.styleSheet) { Hoja.styleSheet.cssText = Estilos; } else { Hoja.appendChild (document.createTextNode (Estilos)); }

Perfecto, ahora esto tendremos que ubicarlo en algún sitio dentro del código HTML, obviamente, donde van las hojas de estilo, en la cabecera, el famoso HEAD. Además del método getElementById, ya mencionado podemos usar otro similar, getElementsByTagName, con este lo que hacemos es obtener una matriz con todas las etiquetas del mismo tipo, pongamos por caso los párrafos, a las que podemos referenciar así:

var p0 = document.getElementsByTagName ('p') [0]; var p1 = document.getElementsByTagName ('p') [1]; var p2 = document.getElementsByTagName ('p') [2];

Como queremos manipular la cabecera la sentencia será:

var Cabecera = document.getElementsByTagName ('head') [0];

¿Por qué [0]? Porque afortunadamente sólo tenemos una cabecera en una página HTML. De lo contrario habría que recorrer todas las referencias, con la complicación subsiguiente. Bien, ya tenemos referenciado nuestro objeto Cabecera, al que, solo nos falta añadir la hoja de estilo, curiosamente, ahora el método appendChild funciona en todos los casos:

Cabecera.appendChild (Hoja);

Y listo. El código de la utilidad JavaScript ya puede usar los estilos insertados dinámicamente en la cabecera HTML, el código final de ejemplo queda así:

var fuente = 'arial, sans-serif;'; var Estilos = '' + '.serie_articulos {' + 'font-family:' + fuente + 'font-size: 11pt;' + 'font-weight: bold; ' + 'font-style: italic; ' + 'padding-bottom: 9px; ' + 'color: #800000;' + 'background-color: transparent; ' + '}' + '.titulo_articulo {' + 'font-family:' + fuente + 'font-size: 12pt;' + 'font-weight: bold;' + 'font-style: italic;' + 'padding-bottom: 7px;' + 'color: #600000;' + 'background-color: transparent;' + '}' + '.autor_articulo {' + 'font-family:' + fuente + 'font-size: 10pt;' + 'font-weight: bold;' + 'padding-bottom: 5px;' + '}'; var Hoja = document.createElement('style'); Hoja.type = 'text/css'; if (Hoja.styleSheet) { Hoja.styleSheet.cssText = Estilos; } else { Hoja.appendChild(document.createTextNode(Estilos)); } var Cabecera = document.getElementsByTagName('head') [0]; Cabecera.appendChild(Hoja);

Una última cuestión, ¿dónde colocar este código dentro del archivo.js? Puede ir donde mejor os parezca, ya sea en el flujo principal de ejecución y asignación de variables globales o dentro de una función específica, a la que no hay que olvidar llamar la primera, antes de que se ejecute el código de la utilidad.

Revisión del 6 de julio

En vista de que la cosa no queda demasiado clara os propongo el siguiente ejemplo: copiad y pegad este código HTML en un archivo llamado Prueba.html.

<html> <head> <title>Prueba</title> <script src="prueba.js"></script> </head> <body> <p>Ejemplo de hojas de estilo con JavaScript</p> <script> CabeceraArticulo('La cocina', 'Hojas de estilo con JavaScript', 'Francisco José Súñer Iglesias'); </script> </body> </html>

A continuación copiad y pegad este otro código en el archivo Prueba.js.

// Definición de la hoja de estilos // ========================================================= // Variables con formatos genéricos var fuente = 'arial, sans-serif;'; // Variable con la definición de la hoja. var Estilos = '' + 'p {' + 'font-family:' + fuente + 'font-size: 10pt;' + '}' + '.serie_articulos {' + 'font-family:' + fuente + 'font-size: 11pt;' + 'font-weight: bold; ' + 'font-style: italic; ' + 'padding-bottom: 2px; ' + 'color: #800000;' + 'background-color: transparent; ' + '}' + '.titulo_articulo {' + 'font-family:' + fuente + 'font-size: 12pt;' + 'font-weight: bold;' + 'font-style: italic;' + 'padding-bottom: 2px;' + 'color: #600000;' + 'background-color: transparent;' + '}' + '.autor_articulo {' + 'font-family:' + fuente + 'font-size: 10pt;' + 'font-weight: bold;' + 'padding-bottom: 5px;' + '}' + ''; // Creación del elemento Hoja y asignación de propiedades var Hoja = document.createElement('style'); Hoja.type = 'text/css'; if (Hoja.styleSheet) { Hoja.styleSheet.cssText = Estilos; } else { Hoja.appendChild(document.createTextNode(Estilos)); } // Inserción de la hoja en la cabecera HTML var Cabecera = document.getElementsByTagName('head')[0]; Cabecera.appendChild(Hoja); // ========================================================= // Funciones JS // --------------------------------------------------------- function CabeceraArticulo(Serie, Titulo, Autor) { document.write ('<div class="serie_articulos">' + Serie + '</div>' + '<div class="titulo_articulo">' + Titulo + '</div>' + '<div class="autor_articulo">' + Autor + '</div>'); } // --------------------------------------------------------- // Fin del archivo.

Ambos archivos deben estar ubicados en el mismo directorio. Observad que Prueba.html llama al archivo Prueba.js desde la línea:

<script src="prueba.js"></script></p>

con esto, además de cargar el código, se ejecuta automáticamente todo aquel que no está contenido en una función, es decir, en este caso la definición de los estilos. A continuación, desde Prueba.html se ejecuta la función CabeceraArticulo que está contenida en Prueba.js, un breve vistazo basta para comprobar que lo que hace esa función es dibujar tres DIV, conteniendo cada uno de ellos uno de los datos pasados en los parámetros, aplicándoles el estilo previamente definido para cada caso.

Espero que así no haya muchos problemas en entender como funciona, y como usar, esta solución.

Prueba de agudeza visual: En el ejemplo he añadido algo a la hoja de estilo con respecto a la explicación del artículo. Averigua que elemento define.

Ejercicio: Prueba a acotar el código de la definición de estilos dentro de una función y a llamarla cuando la necesites, y no cuando se cargue el archivo (ojo, procura que sea de forma que solo la llames una vez, y no repetidamente a lo largo de la página)


© Francisco José Súńer Iglesias,
3 de julio de 2010

Creado: 3 de julio de 2010
Última actualización: 04 de diciembre de 2011 a las 09:07  Bienvenida  Mapa del Sitio  Enlace permanente