Estilos dinamicos - manipulando CSS con JavaScript
- Artículo anterior—Creando y Modificando HTML
- Siguiente artículo—Manejando eventos en JavaScript
- Tabla de contenidos
Introducción
En este punto de la sección de JavaScript del curso, ya hemos cubierto los conceptos básicos del uso real de JavaScript, mirado cómo manejar elementos usando el árbol DOM, y visto cómo manipularlos una vez que los hemos localizado correctamente.
En este artículo echaremos un vistazo a cómo actualizar dinámicamente el estilo aplicado a los elementos mediante la manipulación de las plantillas CSS en tiempo de ejecución utilizando JavaScript. Para esto utilizaremos el mismo tipo de técnicas que ya hemos visto, pero tendremos que tener en mente una serie de consideraciones especiales cuando trabajemos con las plantillas CSS. Todo esto quedará cubierto mediante las siguientes secciones:
- Accediendo a las hojas de estilos
- Propiedades de las hojas de estilos
- Añadiendo y eliminando reglas
- Cambiando elementos Style
- Nombres de clases de elementos
- Resúmen
- Ejercicios
Accediendo a las hojas de estilos
El navegador proporciona una interfaz para interactuar con las hojas de estilos —
en nuestro código JavaScript podemos acceder a una lista de nuestras hojas de estilos mediante
el uso de document.styleSheets
. document.styleSheets
nos devolverá una
lista de todas las hojas de estilo aplicadas a una página, incluyendo hojas de estilos externas
referenciadas mediante un elemento link
, y hojas de estilos internas que residan
dentro de elementos style
. Si nuestros elementos style
tienen el
atributo id
, entonces podremos referenciarlos rápidamente mediante
document.getElementById(element_id)
.
Además podemos añadir nuevas hojas de estilo a la página — podemos usar la función
document.createElement
para crear un nuevo elemento style
. Esto es
interesante cuando queremos dar a los visitantes de nuestra página la opción de cambiar los
estilos de nuestra página dinámicamente, utilizando quizás algún botón. A continuación se presenta
un pequeño ejemplo de cómo se podría crear una nueva hoja de estilos:
var hoja = document.createElement('style')
hoja.innerHTML = "div {border: 2px solid black; background-color: blue;}";
document.body.appendChild(hoja);
Eliminar una hoja de estilos es también bastante simple. Primero tenemos que obtener la hoja
de estilos que queremos eliminar. Podemos hacer esto usando document.getElementById
,
como se muestra en un pequeño ejemplo anterior. Para eliminar la hoja de estilos, podemos usar la función
del árbol DOM parent.removeChild(element)
, donde element
es el objeto hoja de estilos que queremos eliminar, y parent
es el nodo padre de nuestra
hoja de estilos. Como hemos visto antes, para eliminar la hoja de estilos (hoja_a_eliminar
)
primero tenemos que obtener la referencia a su padre — var padre = hoja_a_eliminar.parentNode
— después tenemos que llamar a removeChild
con el parámetro de hoja_a_eliminar
-
padre.removeChild(hoja_a_eliminar)
var hoja_a_eliminar = document.getElementById('idHojaEstilos');
var padre = hoja_a_eliminar.parentNode;
padre.removeChild(hoja_a_eliminar);
El ejemplo de acceso a las hojas de estilos demuestra tanto el acceso a todas las hojas de estilos como la adicción y eliminación de nuevas hojas de estilos a la página.
Propiedades de las hojas de estilos
El objeto stylesheet
está disponible a través de JavaScript, y nos permite acceder a información
acerca de las hojas de estilos referenciadas desde la página actual, por ejemplo, si la hoja de estilos está
desactivada, su localización, y la lista de reglas de CSS que contiene. Para una lista completa de las propiedades
del objeto stylesheet
(y otras cosas además), se puede revisar la
documentación W3C sobre las hojas de estilo
del árbol DOM.
Consideremos un ejemplo (por ahora) teórico — digamos que tenemos un sitio web donde mostramos una serie de artículos técnicos. Nosotros deseamos poner el foco en algunos de esos artículos con un bonito carrusel, pero tenemos el problema de los usuarios que no tienen activado JavaScript por algún motivo. Recordando las lecciones aprendidas en los principios de un JavaScript discreto, queremos que la funcionalidad del sitio web continúe funcionando incluso para esos usuarios, pero deseamos estilizar nuestro sitio web diferente para esos usuarios, de tal forma que su experiencia de usuario sea placentera, aún sin el carrusel.
Lo que podemos necesitar es una hoja de estilos que sólamente estará activa si JavaScript lo está.
Estamos de suerte — el interfaz del árbol DOM para las hojas de estilo nos da acceso al atributo
disabled
, que nos permite activar o desactivar las hojas de estilos.
Muchas de las propiedades del objeto stylesheet
son de sólo lectura,
pero algunas, como disabled
, no.
Además podemos usar las propiedades de las hojas de estilos para ayudarnos a diferenciar entre múltiples
hojas de estilos en la página. La propiedad src
nos ayuda a identificar hojas de estilos externas,
pero no nos ayuda a referenciar elementos de estilo internos. Una forma mejor, que nos permite tener referencias
a hojas de estilos individuales, tanto internas como externas, es usar la propiedad title
. Si
recorremos document.styleSheets
podemos ver las diferentes hojas de estilos que hemos
incluido en la página. El siguiente ejemplo nos muestra como podemos hacer ese recorrido:
function getStyleSheet(tituloUnico) {
for(var i=0; i<document.styleSheets.length; i++) {
var hojaEstilos = document.styleSheets[i];
if(hojaEstilos.title == tituloUnico) {
return hojaEstilos;
}
}
}
Para cada objeto stylesheet
recuperado del array styleSheets
podemos acceder a
su propiedad title
para comprobar si es el título que estamos buscando. Se puede ver un ejemplo
funcional de esto en el ejemplo sobre añadir y eliminar reglas,
que discutiremos en la próxima sección.
Cambiar entre diferentes hojas de estilos basado en la preferencia de usuario es una facilidad bastante
común entre los sitios web — utilizando lo que hemos presentado hasta aquí, podemos tener múltiples
hojas de estilos y activar solamente aquella que el usuario actual desee ver. Podemos ver eso en un ejemplo
real — inicialmente el texto tiene estilo, pero cuando cambiamos el atributo disabled
a true
, nuestra CSS queda desactivada. Podemos tener activa nuestra CSS de nuevo poniendo
disabled
a false
. Esto se puede comprobar en el
ejemplo de propiedades de las hojas de estilos, para un rápido vistazo de como se puede usar todo esto.
Añadiendo y eliminando reglas
¿Recordamos el ejemplo teórico de un sitio web que discutimos más arriba? Recordemos que ese sitio tenía una lista de artículos; algunos eran sobre CSS, otros eran sobre HTML, y otros sobre JavaScript. En nuestra página web mostramos todos los artículos, pero nuestro usuario sólo desea ver los artículos sobre CSS. ¿Cómo podemos hacer esto? Porque todos los artículos se están mostrando ya, y no queremos tener que pedir al servidor una página específica conteniendo justo los artículos sobre CSS — eso es una pérdida de tiempo.
Para solucionar este problema, podemos usar JavaScript para recorrer todos los artículos y hacer que solamente los artículos sobre CSS sean visible (discutiremos sobre cómo hacer esto mas tarde), ó añadir una regla a una de nuestras hojas de estilo que hará que sólo los artículos sobre CSS sean visibles. Utilizar CSS será más rápido que recorrer todos los elementos uno a uno.
El objeto stylesheet
dispone de dos funciones para ayudarnos con este problema. La primera
es la función insertRule
, algo así como esto:
stylesheet.insertRule(regla, indice)
regla
es una cadena conteniendo la regla que queremos añadir a la hoja de estilos.
indice
especifica dentro de la lista de reglas de la hoja de estilos, dónde hay que
que poner esa regla. A continuación un ejemplo:
hojaEstilos.insertRule(".have-border { border: 1px solid black;}", 0);
Existe un ejemplo donde se demuestra el uso de la función insertRule
. En ese ejemplo existe
una lista de todas las reglas en una hoja de estilos. Cuando presionamos el botón, añade una regla con el
índice 2 que hace que el texto se vuelva rojo, añadiendo la propiedad color: red
a la regla
p { ... }
rule. Se puede echar un vistazo a esto en el
ejemplo sobre añadir y eliminar reglas.
Si deseamos eliminar esa regla, podemos llamar a la función stylesheet.deleteRule(indice)
,
donde indice
es el índice de la regla que queremos quitar.
En el ejemplo de este artículo, podemos crear una regla que cambie display a none
para todo el
HTML y los artículos de JavaScript — podemos ver esto en acción en el
ejemplo del carrusel.
Advertencia: IE no implementa las reglas de acuerdo con el estandar. En vez del atributo
cssRules
él utiliza rules
. IE además usa removeRule
en vez de
deleteRule
y addRule(selector, regla, indice)
en vez de insertRule
.
Cambiando elementos Style
En este punto ya deberiamos entender como editar las páginas de estilos asociadas a una página, y crear y modificar las reglas CSS en ella. ¿Y que pasa si lo que queremos es modificar un elemento específico dentro del árbol DOM?. Utilizando el API del árbol DOM podemos acceder a un elemento específico de la página. Si echamos la vista atrás, en el ejemplo del carrusel, la funcionalidad se define de tal forma que cuando nosotros hacemos click sobre un artículo, el artículo se resalta mientras que el texto del artículo se muestra debajo.
A través del árbol DOM, podemos acceder al objeto style
que define el estilo de un elemento. Este
objeto style
se define como CSSStyleDeclaration; se puede ver una explicación detallada
de esto en la documentación W3C
del interfaz CSSStyleDeclaration
. El objeto style
no funciona como otras propiedades
definidas en los elementos HTML. Es diferente, mientras element.href
ó element.id
devuelven cadenas, element.style
devuelve un objeto. Esto significa que no se puede establecer
un estilo simplemente asignando una cadena a element.style
.
El objeto style
tiene atributos que se corresponden con las diferentes propiedades CSS que
podemos establecer. Por ejemplo, style.color
devuelve el color de un elemento. Si llamamos a
element.style.color = "red";
podemos aplicar ese cambio de estilo dinámicamente. A continuacion hay
una función que establece el color de un elemento a rojo cuando le pasamos el id
del elemento.
function colorElementRed(id) {
var element = document.getElementById(id);
element.style.color = "red";
}
También podemos utilizar setAttribute(key, value)
para establecer el estilo de
un elemento. Por ejemplo, podemos cambiar a rojo el color de un elemento invocando a
element.setAttribute('style','color: red');
, pero debemos ser precavidos, porque esto borrará
cualquier cambio anterior que hayamos hecho al objeto style
Cuando establecemos el estilo de un elemento de esta forma, es lo mismo que si lo estuvieramos asignando
en la declaracion del atributo style
en el elemento html
. El estilo sólo se se aplicará
si la importancia y la especificación de la regla es mayor que la de otras reglas aplicadas al elemento
(la especificación se explica en un artículo anterior, la herencia y la cascada en CSS.
Algunos de nosotros ya estaremos preguntandonos que ocurre cuando la propiedad CSS a la que pretendemos dar
valor tiene nombre compuesto. La sintaxis aquí es diferente, porque, por ejemplo, si escribimos
element.style.font-size
, JavaScript entenderá que debe restar size
de
element.style.font
, que no es lo que deseamos que ocurra. Para evitar que esto ocurra, todas las
propiedades CSS se escriben como en el siguiente ejemplo, donde escribimos element.style.fontSize
para acceder al tamaño de la fuente:
function changeElement(id) {
var element = document.getElementById(id);
element.style.color = "red";
element.style.fontSize = "15px";
element.style.backgroundColor = "#FFFFFF";
}
¿Recordamos los objetos stylesheet?. Bien, styleSheet.cssRules
nos dará una lista de todos
los objetos style
representando todas las reglas CSS contenidas en la página de estilos. Se puede
modificar estos objetos style
como el objeto style
de otros elementos. En este caso,
mñas que aplicar cambios sobre un elemento específico de la página, los cambios afectarán a todos los elementos
que se vean afectados por esa regla.
En el ejemplo que viene a continuación, la función que aumenta el tamaño de la letra utiliza el objeto
style
y la función que hace el tamaño más pequeño utiliza setAttribute
. Si nosotros
cambiamos el color del texto a rojo, y entonces llamamos a setAttribute
mediante el botón
apropiado, veremos como nuestros cambios se sobreescriben. Se puede ver en el ejemplo de cambio de estilos.
Nombres de clases de elementos
Otra forma de alterar el estilo de un elemento es cambiando su atributo class
. class
es una palabra reservada en JavaScript, asi que para acceder al atributo class
de un elemento
tenemos que usar element.className
. Se pueden concatenar cadenas a className
si deseamos
añadir una clase a un elemento, o podemos sobreescribir className
y asignarle una clase nueva.
Esto lo podemos ver en el ejemplo sobre nombres de clases.
Resúmen
Conocer como cambiar dinámicamente los estilos aplicados a nuestras páginas es muy útil para construir modernas, ricas e interactivas páginas web; el conocimiento presentado en este artículo es justo la base de técnicas más avazandas como animaciones JavaScript. Así, debemos tener cuidado de usar las modificaciones de estilos con responsabilidad, y no utilizarlas excesivamente. También, como se dice más arriba, las modificaciones de estilos pueden mejorar el rendimiento, mostrando y ocultando contenido que puede ayudar a no tener que invocar al servidor bajo ciertas circunstancias.
Ejercicios
- ¿Cual es la diferencia entre
setAttribute
y establecer el estilo a través del objeto CSSStyleDeclaration? - Enumera dos formas de conseguir que todas las imágenes tengan un borde verde cuando un usuario haga click sobre un botón.
- ¿Cambiando el objeto CSSStyleDeclaration de un elemento se cambia siempre el estilo del elemento? ¿Porqué?
- Enumera dos formas de acceder a una hoja de estilo específica.
- Antículo anterior—Creando y Modificando HTML
- Siguiente artículo—Manejando eventos en JavaScript
- Tabla de contenidos
Sobre el autor
Greg Schechter es bastante joven en la industria tecnológica sobre webs — él es actualmente un estudiante de informática (computer science) en la University of Illinois in Urbana Champaign. El es muy entusiasta en entrar en la industria de aplicaciones webs, donde él espera construir sitios web prácticos y ricos para usuarios en todos el mundo. Se puede encontrar mas detalles de Greg en GregTheBusker.com.
This article is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported license.
Comments