Selectores adyacentes en CSS
En el texto anterior a este artículo hablaba sobre la rareza de las reglas de CSS. Es verdad, algunas reglas que fabricamos son realmente complejas, raras, inusuales o simplemente, una belleza a los ojos del programador. Esto último, fue sólo un comentario aparte para los que realmente entienden la belleza de construir reglas.
CSS es sin duda algo más que: ponerle color a las tipografías, hover a los enlaces. Es todo un mundo de opciones para gobernar los elementos de una página. La clave está en comprender primero, cómo funciona CSS, cuáles son los valores básicos que un navegador interpreta y luego, la otra cara del asunto: los selectores. Existen varios tipos de selectores, y hoy hablaremos del que, curiosamente, tomó protagonismo ayer: los selectores adyacentes directos.
Selector adyacente directo
Muchos desarrolladores cuando empiezan con CSS utilizan sólo un puñado de selectores, por no decir dos o tres selectores. Los principiantes, sólo se cruzarán por su trayecto con selectores de tipo:
p { color: red; }
O bien con un selector de descendencia o un selector de clase, como por ejemplo éste:
div p { color: red; }
p.texto { color: #666; }
Estos selectores son, en la gran mayoría de casos los más utilizados. Pero en muchos, observaremos que son demasiado específicos con lo que queremos hacer. En el primer ejemplo (p { color: red; }) obtendremos un resultado bastante radical: todos los párrafos del sitio, indistintamente donde se encuentren tendrán color rojo. En el segundo, sin embargo, obtendremos párrafos de color rojo cuando se encuentren encerrados dentro de un <div>. Entonces, cuando queramos hacer un párrafo de color negro, dentro de este documento, vamos a tener que escribir o bien una regla menos específica o bien una clase más, escribiendo la regla en CSS y en el documento HTML poniéndole la correspondiente clase, por ende, más código escrito, más reglas para memorizar en un futuro.
Los desarrolladores un poco más experimentados, digamos, un término medio, sólo se cruzarán con unas pocas reglas más. En mi experiencia, a pesar de que muchos usan las reglas sin tener idea de lo que hace, otros desarrolladores utilizan selectores del tipo padre/hija, clase e identificador. En gran parte, los desarrolladores medios comprenden el funcionamiento a medias de CSS, pero no tienen idea de especificidad, herencia, atributos y de selectores de clase e identificador. Está claro: logran cosas que los principiantes no, pero terminan armando algo que es imposible luego de controlar: las reglas se pisan una y otra vez, terminando luego de forzar muchas reglas y creando cada vez más clases e identificadores.
Los desarrolladores expertos o bien experimentados logran comprender más allá del fin de la utilización de atributos en una regla de CSS. Comprenden la verdadera naturaleza del documento, puede ver su árbol de elementos y también saben el nivel de complejidad que necesitarán para crear una o varias hojas de estilo, las cuales tendrán un set de reglas de las cuales, dependiendo una situación u otras, actuarán. Esto les da un poder de control superior al resto. Mientras el resto de los desarrolladores no experimentados son demasiados específicos; terminando de escribir reglas para todos los casos, elementos y posibles problemas, los desarrolladores experimentados sólo escriben los casos mínimos, aprovechando las bondades del árbol de elementos de un documento web, los diferentes selectores, la especificidad, la herencia y cómputos.
Esta es la magia de CSS, el poder controlar todos los valores, inclusos aquellos que no están especificados, que pueden salir ya sea por acción de un usuario o por un evento. Pero no me enrollaré ahora con los principios básicos, volvamos a los selectores adyacentes.
Los selectores adyacentes, permiten seleccionar un elemento vecino dentro del árbol de elementos de un documento. Si en un documento CSS tenemos:
p { color: red; }
Todos los <p> de este documento de HTML serán de color rojo, como el ejemplo (marcado en negrita):
<div>
<h1>Este es un título</h1>
<p>Párrafo uno del documento…</p>
<p>Párrafo dos del documento…</p>
</div>
Pero en cambio, si tenemos esta regla de CSS con un selector adyacente, como éste:
h1 + p { color: red; }
En el HTML sólo el primer párrafo será de color rojo, mientras que el segundo tendrá el color por defecto que se encuentre especificado en el objeto <body>.
Entonces, resumiendo: este tipo de selector únicamente trabaja con otros elementos que sean de secuencia, como si se tratara de vecinos. Este patrón puede repetirse, mientras se cumpla la regla, por ejemplo:
p + p { color: red; }
Todos los <p>, que sigan después de <p> serán de color rojo, el primero de la línea, no.
<div>
<h1>Este es un título</h1>
<p>Párrafo uno del documento…</p>
<p>Párrafo dos del documento…</p>
<p>Párrafo tres del documento…</p>
</div>
En el último ejemplo, los últimos dos párrafos (el dos y el tres) serán de color rojo, mientras que el primero tendrá el color por defecto, especificado o no en el <body>.
Simple como eso.
Aplicaciones
Este tipo de selectores son realmente poderosos en algunas situaciones, por ejemplo, cuando trabajamos con tablas. Puede ser realmente útil, de hecho, en Tractis los utilizamos para listados, ya que nos permite dar un formato más inteligente sin tener que escribir reglas y repetirlas en cada fila.
Un ejemplo con tablas sería coloreando sólo una columna, mientras que las demás mantendrán un color por defecto. Hace unos meses planteé la posibilidad con Arnau de hacer esto sin necesidad de escribir reglas. Al principio pensé que lo mejor era utilizar elementos <colgroup> o <col> en mis tablas, pero Arnau me alertó de los problemas que traía semejante opción. Así que, opté por utilizar un selector adyacente directo y escribir una regla como esta:
table.listados tr td:first-child + td + td + td { background: #ffffcc; }
Esta regla se aplicará en una tabla identificada como «listados» en cualquier página. Sólo será aplicable en la tercera celda de cada fila que se cree en la tabla. Con esto me ahorro de escribir una regla demasiado específica en CSS y, en cada celda donde quiera aplicarla el atributo class="colorcelda" por ejemplo.
Como estas celdas son generadas en base por el sistema, si aplico clases específicas a cada celda podría hacer creer el tamaño de mi documento, se repetiría class="colorcelda" cada vez que se genere una fila.
En cambio, si aplico un selector adyacente, aprovecho la naturaleza del documento y las propiedades de selección del mismo, sólo seleccionando aquellos elementos cuando cumplan una condición: que se encuentren adyacentes. Mi tabla debería verse así luego de aplicar el ejemplo antes mencionado:
| Marca | Velocidad | Consumo | Autonomía | Precio |
|---|---|---|---|---|
| Ford Ka | 180 Km/h | 1l/100Km | 300km | 11.530€ |
| Fiat Palio | 193 Km/h | 1l/130Km | 420km | 14.530€ |
| Audi A3 | 210 Km/h | 1l/75Km | 370km | 19.230€ |
| Los valores utilizados en esta tabla son ficticios. | ||||
Como estas aplicaciones, encontrarán muchas, por ejemplo los títulos en páginas que contengan artículos. El título tendrá un margin-bottom: 0px si va acompañado de un subtítulo, pero si no tiene subtítulo podría tener un margin-bottom: 20px.
Compatibilidad
Quizás esta es la parte de la que no me gusta hablar. La realidad indica que, si eres un esclavo del sistema, éste tipo de selectores será inútil en tu vida. Internet Explorer 6 no soporta este selector, así de claro y directo. Aún empezando, Internet Explorer 7 soporta este selector.
El resto de navegadores avanzados (Safari, Opera, Firefox, etc.), como de costumbre, sí.
Dicho y hecho, los selectores adyacentes son más que útiles y, muy fáciles de aprender y poner en práctica.
Hasta la próxima charla.
29 Respuestas a la entrada “Selectores adyacentes en CSS”
Escrito por aNieto2k
Marzo 14th, 2007 at 10:40 pm
Lamentablemente vivimos en un mundo dirigido por el “sistema” y hasta que las cosas cambien estos selectores son una utopía en el mundo laboral.
Muy buen artículo.
Saludos.
Escrito por Yuki
Marzo 14th, 2007 at 10:44 pm
Gracias por la explicación
Escrito por Fran
Marzo 14th, 2007 at 11:27 pm
Muy buen artículo, en serio. Lastima que la potencia de CSS se vea limitada por un único fabricante.
Escrito por Juan
Marzo 15th, 2007 at 3:57 am
Extrañaba leer este tipo de cosas en tu blog, parece que las vacaciones vinieron muy bien
Escrito por Pau
Marzo 15th, 2007 at 8:28 am
Me gusta tu blog y me alegra que vuevlas a postear.
A mi me encanta usar todo tipo de selectores y de hecho los que usamos la libreria jQuery ya estamos un poco acostumbrados a usarlos ya que es la manera ideal de seleccionar los items que quieres sin ponerle una id o una classe a cada puto tag de tu página.
El problema el de siempre, que no son compatibles con ie.
Yo recomiendo a todo el que quiera experimentar con ellos que se baje la libreria jquery ya que para seleccionar ítems usa selectores css (y xpath) http://docs.jquery.com/Selectors.
Saludos
Escrito por Roger
Marzo 15th, 2007 at 10:33 am
He encontrado muy interesante tu artículo. Solo he echado de menos al final un apartado tipo : “para saber mas”… ( libros o sites donde encontrar documentacion )
Escrito por rehtse
Marzo 15th, 2007 at 11:48 am
Gracias, gracias, gracias…
Tenía un poco abandonado el tema del CSS y ahora me doy cuenta de que necesito aprender mas.
De verdad, gracias
Escrito por mini-d
Marzo 15th, 2007 at 12:38 pm
Roger, no hay muchos libros que hablen en profundidad de esto, porque pertenecen a la especificación CSS 2 y CSS 3. En los libros, salvo el de Eric Meyer, encontrarás todas las cosas acerca de selectores, cascada, especificidad, etc.
Escrito por El Cuidador del zoo
Marzo 15th, 2007 at 1:25 pm
En mi pagina me volvi loco para cambiar el titulo por una imagen y esto no lo entiendo muy bien.
Saludos
Escrito por mariano
Marzo 15th, 2007 at 3:44 pm
epa… volvió a escribir el mejor MINID
Escrito por szy
Marzo 15th, 2007 at 7:50 pm
Mientras no haya un soporte unánime de esos selectores no hay nada que hacer. Y me parece una tontería volver a los tiempos de crear código específico para Explorer y Netscape (sustitúyase por Firefox en la actualidad). Como IE7 sigue sin soportar gran parte de los selectores CSS2 (de CSS3 mejor no hablamos) seguiremos anclados en la estupidez otros 5 años más.
Escrito por Diego
Marzo 15th, 2007 at 9:06 pm
Grosso
pero esto explica porque es que nunca habia oido hablar de este selector…
Escrito por hologium
Marzo 15th, 2007 at 11:05 pm
Diego.. creo que el último ejemplo que has puesto colorearía TODAS las columnas A PARTIR de la tercera (inclusive). Es decir.. «Consumo», «Autonomía» y «Precio».
Estoy probando en Firefox.
saludos
Escrito por mercu
Marzo 15th, 2007 at 11:05 pm
Luego dicen que la programacion no es arte.
Escrito por lydie
Marzo 16th, 2007 at 1:38 am
gracias muy interesante
Escrito por Federico
Marzo 16th, 2007 at 2:26 pm
Que bueno que volvió el minid que habla de estándares. Falta que hables de “chachacha” y volvemos a los buenos viejos tiempos. Un Abrazo.
Escrito por mini-d
Marzo 16th, 2007 at 3:55 pm
Hologium, tenías razón. Luego de hablar con Arnau, debí romper la secuencia. Si no siempre se cumplen los casos de 3 tds juntas. Con first-child lo hace.
Escrito por Federico
Marzo 18th, 2007 at 12:16 am
¿Acaso no se supone que IE7 incluye soporte para selectores de adyacentes?
Escrito por mini-d
Marzo 18th, 2007 at 3:06 am
En efecto, IE7 soporta esto. Pero bueno, digo, si eres esclavo del sistema, este selector no te sirve.
Escrito por total 13
Marzo 18th, 2007 at 9:07 pm
Muy buena explicación, y tambien me uno a los congratulados por la vuelta de este tema al blog, aunque sea puntual. Una putada que con el dichoso IE no funcionen, ya que ahorraría un monton de clases en plan “primerparrafo” y demás.
Escrito por Eugenia
Marzo 19th, 2007 at 1:02 am
Genial, esto me da la pauta de seguir perfeccionandome!
Te leo desde hace mucho, nice blog!
Escrito por Aw!
Marzo 19th, 2007 at 11:15 pm
Hola, muy bién explicado.. Lo malo es que quién no es esclavo del sistema cuando Ie6 tiene tan tremendo campo abarcado? Es decir… cómo no ser esclavo del sistema?
Escrito por mini-d
Marzo 20th, 2007 at 1:24 am
Bueno, es cuestión de remar en contra corriente hasta encontrar otra corriente que te lleve sola. Desarrollar sólo para IE es facilitarle a los usuarios a que no mejoren sus condiciones. Lo bueno sería que, el que quiera usar un navegador sólo-texto lo haga, pero que no espere otros resultados. Es por eso que, este tipo de reglas se aplican para cosas que sólo los usuarios con navegadores avanzados pueden leer.
El resto, degrada.
Escrito por Aw!
Marzo 21st, 2007 at 11:36 pm
Ah! no había entendido bien por dónde ibas… competamente de acuerdo ^__^
Escrito por albertofs
Marzo 22nd, 2007 at 1:43 pm
Con anieto al 100%
Escrito por Juani
Marzo 23rd, 2007 at 12:58 am
Muy Bueno el artículo pero…. ¿cómo se podría trasladar a un plano comercial? Ej: El cliente quiere que su sitio web se vea igual tanto en el IE como en el resto de los navegadores. Lamentablemente en esos casos si usamos este tipo de selectores, tendríamos que utilizar JavaScript o similares para imitar el comportamiento en el IE.
Escrito por Jhon
Marzo 23rd, 2007 at 5:19 pm
Muy buen articulo. muchas gracias!! ahh mira tu email que te emvie algo sobre css
Escrito por © Pioja
Abril 13th, 2007 at 1:28 pm
» Enserio se agradece la explicacion, llevo un año diseñando y me encanta trabajar con css, pero siempre me enrollo con los “selectores demasiado específicos” y termino creando un sin fin de reglas y aplastandolas hasta
descontrolarme, gracias a personas como vos se puede seguir mejorando..
Desde Asunción, Paraguay
Escrito por findCSS, otra librería de selección CSS | aNieto2K
Abril 20th, 2007 at 9:50 am
[...] Via Digg, he descubierto findCSS una librería similar a cssQuery (la gran conocida en este sector), que se trata de una librería javascript que nos permite realizar búsquedas de nuestros elementos mediante el uso de selectores CSS. Hace unos días Diego comentaba lo satisfecho que se queda uno despues de parir un chorro de selectores CSS medianemente complejo, mediante findCSS todo podremos sentirnos asi [...]
Escribe tu comentario