Selector CSS
# Selector CSS

El selector CSS (Cascading Style Sheet) es el nexo de unión entre la hoja de estilos y los documentos a los que se aplique dicha hoja. Ya sean (x)HTML, XLM, SVG... y con independencia del medio en que se muestre (media type).

Del conocimiento y buen manejo que se haga del selector CSS dependerá la eficiencia de la hoja de estilos y en muchos casos el poder lograr lo deseado sin necesidad de recurrir a otros lenguajes.

Un detalle más que significativo de su importancia del selector en CSS lo da el hecho de que hemos pasado de tener unos 20 selectores en CSS2 a más de 70 en el último documento en discusión.

El selector CSS es el identificador en la hoja de estilos del elemento o elementos del DOM a los que se aplicarán las declaraciones contenidas en la regla de la que forma parte dicho selector.

Como curiosidad, en algunas partes, al elemento del DOM al que aplica el selector CSS se le llama sujeto del selector.

El término selector CSS puede referirse por igual a cualquiera de los cuatro tipo de selectores CSS que existen clasificados por la composición de su nombre:

* a un selector CSS simple
* a un selector CSS compuesto
* a un selector CSS complejo
* a una lista de selectores CSS

## Tipos de selectores CSS por su composición

### Selector CSS simple

Un selector simple es aquel que está formado solo por una única cadena textual, sin ningún combinador. Son selectores simples el selector universal *, el selector por tipo de elemento del DOM div | p | article..., el selector de ID # y de clase ., el de atributo, el de pseudoclase : y el de pseudoelemento :: (notación actual). En la notación antigua o clásica de CSS2 los pseudoelementos también se representan como las pseudoclases :.

Los combinadores son signos intercalados entre selectores simples para acotar o hacer más preciso el alcance del selector. Estos combinadores son el espacio en blanco, los signos + | ~ | > entre otros.

### Selector CSS compuesto

El <quote>Selector compuesto</quote> es una cadena de selectores simples sin combinadores (el espacio en blanco también queda excluido porque es un combinador):

Entre los selectores CSS compuestos también están incluidos los que tienen un selector de pseudoclase CSS en su nombre:

### Selector CSS complejo

El «Selector complejo» es una secuencia o cadena de selectores separados por «combinadores».

### Lista de selectores CSS

Una «lista de selectores» la conforman dos o más selectores de cualquier tipo separados por una coma ,

## Combinadores de selectores CSS

Los combinadores CSS son signos gráficos, o caracteres especiales, o palabras o expresiones reservadas utilizados en el nombre del selector para formar los selectores CSS complejos. Estos selectores CSS aumentan precisión del selector al relacionar varios de ellos en función de que cumplan alguna condición (que es la definida por el combinador).

### Combinador CSS de descendiente: ' ' (espacio en blanco) o '>>'

En el documento sobre los selectores de nivel 4 se introduce el nuevo combinador >> equivalente al espacio en blanco.

El espacio en blanco o el doble >> separando el nombre de dos selectores CSS se utiliza para apuntar a elementos contenidos dentro de otro en el DOM del documento. a b o a >> b selecciona a todos los elementos b contenidos (dentro) de a sin importar la profundidad o los descendientes interpuestos entre 'a' y 'b'.

### Combinador CSS de hijo directo '>'

a > b Solo aplica a los elementos 'b' contenidos directamente en 'a' ('b' es hijo directo de 'a').

### Combinador CSS de hermano posterior '~'

a ~ b El signo '~' en el selector obliga a que 'b' sea hermano de 'a' (estén ambos contenidos directamente en el mismo elemento). No importa que en el html entre ambos haya otros elementos hermanos interpuestos.

El selector CSS del código previo h2 ~ p afecta por igual a los dos párrafos ya que ambos son hermanos posteriores del título (h2): están contenidos directamente en el mismo elemento html, ambos (el título y los párrafos) tienen al article como padre.

### Combinador de hermano posterior adyacente '+'

Representado por el signo '+' selecciona, al igual que el anterior, cada elemento 'b' que sea hermano de un 'a' y además estén adyacentes: 'b' tiene que aparecer en el DOM inmediatamente después de cerrar 'a', no puede haber ningún otro hermano que los separe o se interponga entre ellos.

En el bloque de código anterior si el combinador CSS en vez de ser el de hermano posterior ~ es el de hermano posterior adyacente h2 + p solo el primer párrafo (el que sigue al h2) se vería afectado por la regla CSS.

Observa que al referirme a los combinadores CSS de hermanos incluyó la expresión «hermano posterior» ya que CSS no puede (de momento) remontar el DOM. Esto es, siempre serán elementos 'contenidos en' o 'posteriores a'. Nunca al "contenedor de" o al "precedente de".

### Combinador CSS de namespace '|' y qualified names

La barra vertical '|' se emplea para acotar el sujeto del selector al espacio de nombres (en inglés: namespace) indicado. La especificación tiene su documento (status W3c Recomendation) específico para este tema: "CSS Namespaces Module" y los "nombres CSS calificados".

Nota: La especificación no incluye en este apartado de los combinadores al de namespace.

### Combinador CSS de referencia '/ref/'

A título informativo. El documento sobre los selectores de nivel 4 introduce este selector.

"El combinador /ref/" en el código anterior apunta al input al hacer :hover o :focus en su etiqueta (label). Lo vincula por el atributo 'for'.

### Combinador CSS /deep/ para iluminar las sombras

"El combinador /deep/" es de reciente formulación. Concebido para poder apuntar a los elementos creados o incluidos en el shadow DOM.

Nota: Chrome retiró recientemente el soporte a este combinador.

### Combinador de columna ||

El combinador de columnas || (representado por dos barras verticales), nuevo en el doc Selectores de nivel 4, selecciona las celdas pertenecientes a una columna dada. En caso de que una celda ocupase 2 o más columnas diferentes se verá afectado por cualquiera de estas.

El selector col.selected || td afecta a las celdas C, E, y G.

## Identificando al sujeto del selector CSS

De forma general, se puede decir que el sujeto del selector (o elementos del DOM a los que apunta) es el último selector simple que aparece, en la cadena que lo conforma, antes del corchete de apertura del bloque de declaraciones y de cada coma ',' si es una lista de selectores.

Puntualizo lo "de forma general" debido a que de nuevo ha sido recogido en el documento de trabajo el selector de ancestro o padre que no aplica al elemento sino a su contenedor.

Puedes ampliar este aspecto con el artículo "Cómo se leen los selectores".

## Conformando el nombre del selector CSS

A la hora de dar nombre a los selectores CSS hay una serie de requisitos a tener en cuenta:

* Por conveniencia (acuerdo no formal) se utilizan minúsculas aunque CSS no es "case sensitive". Esto es, no diferencia entre mayúsculas y minúsculas. Por lo tanto para CSS es lo mismo el selector 'div' que 'DIV'. Sin embargo hay lenguajes a los que aplica CSS que sí lo son como el XML tanto en el nombre de los elementos como en el valor de sus atributos.
* Los nombres de los selectores pueden contener solo caracteres de la 'A' a la 'Z' y del '0' al '9' y contener guiones medios '-' o bajos '_' dentro de él.
* El nombre del selector no puede comenzar por un dígito (número), ni por un guion ni por alguno de los caracteres reservados. Es conveniente evitar el uso de símbolos "extraños".
* En caso de que necesites utilizar inexcusablemente alguno de los no permitidos utiliza "codificación CSS" y escápalos usando la barra invertida '\'. Así '.2clase' sería inválido pero '.\2clase' funcionaría. El selector '#foo>a' apuntará a un enlace hijo directo del elemento con id 'foo' pero '#foo\>a' al que tenga en el html el atributo de id igual a 'foo>a'.
* En CSS la barra invertida '\' se asocia con "tres tipos de caracteres de escape".

Estas restricciones de caracteres solo aplican en el ámbito de la hoja de estilos. Hago esta puntualización porque el documento Html y el CSS son dos campos totalmente distintos. Y el no tenerlo claro conduce a falsas polémicas e ideas como negar que "los selectores CSS de ids y class sí pueden comenzar por un número".

## Alcance del selector CSS. La pseudoclase ':scoped'

En proceso de formulación y desarrollo. Se incluye a título informativo.

Algunas aplicaciones pueden acotar el ámbito de aplicación de los selectores CSS a un fragmento del documento o subárbol del DOM. Esta delimitación de alcance se puede hacer por dos métodos: 'scope-contained selectors' y 'scope-filtered selectors'.

Es el equivalente en las hojas de estilos a lo que supone emplear en el html el atributo 'scoped' dentro del elemento <style> usado dentro del body.

Puedes ampliar este aspecto en el artículo "Estilos acotados: «style scoped»".

Nota: Recientemente Chrome retiró su soporte a <quote>scoped</quote> tras habérselo dado durante algún tiempo.

## Combinaciones lógicas y agrupación de selectores CSS

Los selectores se pueden agrupar para simplificar las hojas de estilo cuando varios elementos comparten una serie de declaraciones iguales. Así, en vez de crear varias reglas iguales en las que solo cambia el selector, se crea una única regla con todos los selectores necesarios para apuntar a los distintos elementos.

Las combinaciones y agrupaciones de selectores CSS recogidas en la especificación son:

### Listas de selectores CSS

la conforman dos o más selectores de cualquier tipo separados por una coma ',' a los que aplica el mismo bloque de declaraciones que comparten. Visto en detalle un poco más arriba en este artículo.

### El selector CSS por pseudoclase :matches

La pseudoclase :matches es del tipo funcional. Admite como argumento una lista de selección. Esto es, se indica dentro del paréntesis y separados por comas los casos en los que aplicará el bloque de declaraciones.

Aplicaría a los 'inputs' que cumplan con alguna de las condiciones indicadas: que su valor no sea válido o esté fuera del rango permitido en él.

### El selector CSS por pseudoclase :not

La pseudoclase de negación :not, al contrario que la anterior, apunta a los que no cumplen con los argumentos indicados.

### El selector CSS por pseudoclase :has

La pseudoclase :has es la formulación actual de un viejo conocido: el selector de precedente o padre.

Utilizada para apuntar a los elementos que contengan lo indicado en el argumento (valor dentro del paréntesis). Así el selector a:has(img) solo aplicará a los enlaces que contengan una imagen dentro de él.

El valor del argumento puede ser uno solo o una lista separadas por comas:

El bloque de declaraciones se aplicará a todo 'section' y solo a aquellos que contengan como mínimo un encabezado (hnº) dentro de él.

Al utilizar estos selectores CSS con estas pseudoclases hay que tener presente que:

* No se puede anidar la misma: colocar como argumento de la función (dentro del paréntesis) la misma pseudoclase anula el selector. Es erróneo hacer :not(:not) o :matches(:matches o :has(:has)
* Sí es lícito encadenarlas, ya sea la misma o distintas: :not(:checked):not(:required)
* El documento "selectors level 3" solo permitía incluir en el argumento de :not selectores simples. El último en desarrollo permite anidar estas pseudoclases: el:not(:has(h1)) o el:has(:not(img))

Al momento de conformar el nombre del selector CSS, o lo que es lo mismo, buscar cómo apuntar a los elementos del HTML a los que queremos afectar, podemos hacerlo tomando algún tipo de información de dicho elemento, y en función de ese dato usado también se pueden clasificar los selectores CSS:

## Selectores CSS elementales

### Selector universal '*'

El asterisco '*' representa a cualquier elemento del DOM. Al ser utilizado como selector CSS aplicará a cualquier elemento contenido en el documento.

### Selector CSS por tipo de elemento (nombre de etiqueta o tag)

Selecciona al "sujeto del selector" por el nombre de la etiqueta (tag) del elemento que lo identifica en el html. Ejemplo de estos son div, a, ul

## Selector CSS por valor de atributo

Un atributo es un metadato incluido dentro de la etiqueta de apertura del elemento en el HTML (o XML). Está formado por una expresión clave que indica qué tipo de metadato es (el nombre del atributo), seguido del signo = y el valor del atributo entre comillas o no según lenguaje y doctype del documento. En las hojas de estilos podemos utilizar tanto el nombre del atributo como todo su valor o una parte de él para utilizarlo como selector CSS.

### Selector CSS de Identificador único o id '#'

Conformado anteponiendo la almohadilla '#' al valor del atributo 'id' del elemento.

La especificación explícitamente indica que no pueden existir espacios en blanco en el valor del atributo 'id'. Por lo tanto el atributo 'id' solo admite un único valor y además este valor debe ser único (no compartido) por otros elementos en el mismo documento o "namespace".

Por ello no pueden existir selectores compuestos de dos identificadores únicos: #id1#id2. Pero si por cualquier motivo te encuentras que en el html hay un elemento con "dos id´s" en el mismo atributo (id='un dos') y no puedes subsanar ese error (en el html) aún es posible utilizar dicho valor como selector CSS:

* Con el uso del selector por valor de atributo en cualquiera de sus variantes: [id='un dos'] [id~='dos']
* Escapando el espacio en blanco #un\ dos. "Ver demo".

### Selector CSS de clase '.'

El «Selector de clase» se conforma en CSS anteponiendo un punto '.' al valor que tenga el atributo 'class' del elemento en el html.

Así, el selector .miclase apuntará a todos los elementos del documento al que afecte la hoja de estilos que tengan declarado class="miclase".

El atributo 'class' admite valores múltiples separados por un espacio en blanco. Así que se puede conformar un selector de clase con un solo valor de clase o múltiples.

Si queremos seleccionar un elemento que tiene dos clases en su atributo class="una_clase otra_clase" el selector se conforma con ambos valores (precedidos de su punto '.') sin espacio en blanco de separación entre ambos:

En este último código de ejemplo en caso de colisión de estilos prevalece la segunda regla con independencia del orden por ser más específica

### Selector CSS por nombre y valor de atributo

Además de la forma anterior para conformar los selectores CSS por el valor del atributo de clase o de id, se pueden construir utilizando expresiones CSS encerradas entre corchetes rectos '[algo]' que contengan el nombre del atributo y (opcionalmente) su valor o parte de él.

**[att]**

Representa a cualquier elemento que tenga el atributo con nombre igaula a 'att' cualquiera que sea su valor, incluso con valor vacío.

Este selector CSS selecciona a todos los párrafos que no tengan el atributo 'class' en su etiqueta de apertura. <p>...</p> sí se vería afectado pero no el elemento <p class>...</p> aunque el valor de su clase esté vacío.

**[att=algo]**

Representa cualquier elemento en el que el valor de su atributo 'att' es exactamente la cadena de texto 'algo'. Ni más ni menos.

**[att~=algo]**

Representa un elemento cuyo valor del atributo 'att' está formado por una lista de cadenas textuales separadas por espacios en blanco y una de ellas es exactamente 'algo'

**[att|=algo]**

En este caso el valor del atributo 'att' es exactamente 'algo' o comienza por la cadena 'algo' seguida de un guion medio '-'. Pensado originalmente para identificar los atributos de tipo de lenguaje que comparten el mismo idioma:

p[lang|=es] {color: red;} dibujaría en color rojo todos los párrafos cuyo atributo 'lang' tenga el valor 'es' y además los 'es-*' como "es-arg', 'es-pe'...

En estas expresiones y las siguientes 'att' significa cualquier nombre de atributo, como puede ser 'id', 'class', 'longdesc'. 'title', étc (incluidos los llamados atributos de autor data-*)

### Selector CSS por subcadena coincidente en el valor del atributo

El selector CSS de atributo además de conformase con un valor del atributo, también puede hacerlo utilizando una parte de dicho valor.

**[att*=algo]**

Representa un elemento con el atributo 'att' cuyo valor contiene en él al menos una vez la subcadena 'algo'.

En estos casos si 'algo' es una cadena vacía el selector es nulo, no apunta a nada code>[att=]

Tradicionalmente el valor del atributo se escribía entre comillas simples o dobles. Actualmente puede aparecer entre ellas o sin ellas. Ambas grafías aparecen el la documentación del consorcio y el validador las admite sin marcar error.

Puedes ampliar este apartado en el artículo "Selector CSS por valor de Atributo"

## Pseudoclases y Pseudoelementos

El grupo de selectores CSS conformado por alguna pseudoclase o pseudoelemento es el que mayor crecimiento ha experimentado en el desarrollo de CSS3 (documentos nacidos tras el cierre del nivel 2 de CSS o CSS2.1

En algunos casos la diferencia entre una u otro es difusa y poco intuitiva y su clasificación entre unas u otros no se alcanza a ver. En la actualidad (selectores level 4) se clasifican y agrupan atendiendo a particularidades de lo más variado.

Para ver cómo definía CSS2.1 a unas y otros tienes "la traducción de sidar.org". Resumiendo y para diferenciar unas de otras:

Tradicionalmente el número de pseudoelementos y pseudoclases era muy reducido. Si visitas el enlace anterior a la traducción del SIDAR lo podrás comprobar.

Sin embargo con el paso del tiempo han ido surgiendo necesidades nuevas en este apartado de los selectores CSS y su respuesta y resultado ha sido una larga lista de ellos (de ambos tipos de estos selectores CSS).

En la actualidad, casi todas las diferentes pseudoclases están contenidas y explicadas en el documento que desarrolla los selectores. Casi todas.

Pero los pseudoelementos incluidos en dicho documento son minoría. Tanto algunas pseudoclases como muchos de los pseudoelementos actuales se encuentran repartidos por los distintos documentos del W3c que los desarrollan.

### Pseudoelementos y sus selectores

Podría decirse que los pseudoelementos son parte del documento que no tienen la entidad de elemento o que simplemente no existen en él. Esto es, no están 'contenidos en' o 'marcados con' una etiqueta (tag) que lo identifique y "separe" del resto. Son abstracciones.

Si echas un vistazo al código fuente del documento no los encontrarás en él escritos y marcados.

El selector CSS de pseudoelemento es una herramienta para poder apuntar desde la hoja de estilos a una parte del documento que no tiene entidad propia (categoría de elemento u objeto en el DOM) y que por lo tanto, de no existir el oportuno selector CSS de pseudoelemento, no sería posible declararle estilos específicos.

**Grafía del selector CSS de pseudoelemento**

Tradicionalmente (epecidicación CSS2.1) la forma de escribir el selector de pseudoelemento era anteponer el carácter ortográfico : (dos puntos) a su nombre. Con el desarrollo de CSS3 esta grafía se cambió a duplicar los dos puntos :: para diferenciarlos de los selectores de pseudoclase. Ambas formas son funcionales y reconocidas por los navegadores en sus versiones más actuales.

**Todos los selectores CSS de pseudoelemento**

* ::after "Selectors L3"
* ::attr "Selectors Non Element"
* ::backdrop "Fullscreen"
* ::before "Selectors L3"
* ::choices "CSS UI L3"
* ::first-letter "Selectors L3"
* ::first-line "Selectors L3"
* ::footnote-call "CSS GCPM"
* ::footnote-marker "CSS GCPM"
* ::marker "CSS Lists L3"
* ::nth-fragment "CSS Overflow L3"
* ::read-only "CSS UI L3"
* ::repeat-index "CSS UI L3"
* ::repeat-item "CSS UI L3"
* ::value "CSS UI L3"

### Pseudoclases y sus selectores

El selector de pseudoclase es una herramienta para poder apuntar desde la hoja de estilos a un elemento del DOM sobre la base de alguna información o detalle ajeno al propio elemento o al "árbol del documento".

Esta información a la que se refiere la especificación puede ser de lo más variada y sobre la base de ella los acota y clasifica este tipo de selectores CSS la especificación. Puede ser por el estado en que se encuentre el elemento, por el número que hace al aparece en el DOM, a resultas de alguna acción del usuario...

**Todos los selectores CSS de pseudoclases**

* :active "Selectors L3"
* :active-drop "Selectors L4"
* :ancestor "Shadow Styling"
* :any-link "Selectors L4"
* :blank "CSS Page L3"
* :blank "Selectors L4"
* :checked "Selectors L3"
* :current "Selectors L4"
* :current "Selectors L4"
* :dir "Selectors L4"
* :default "CSS UI L3"
* :disabled "Selectors L3"
* :empty "Selectors L3"
* :enabled "Selectors L3"
* :first "CSS Page L3"
* :first-child "Selectors L3"
* :first-of-type "Selectors L3"
* :focus "Selectors L3"
* :fullscreen "Fullscreen"
* :future "Selectors L4"
* :host "Shadow Styling"
* :host "Shadow Styling"
* :hover "Selectors L3"
* :indeterminate "Selectors L3"
* :in-range "CSS UI L3"
* :invalid "CSS UI L3"
* :invalid-drop "Selectors L4"
* :lang "Selectors L3"
* :last-child "Selectors L3"
* :last-of-type "Selectors L3"
* :left "CSS Page L3"
* :link "Selectors L3"
* :local-link "Selectors L4"
* :local-link "Selectors L4"
* :matches "Selectors L4"
* :not "Selectors L3"
* :nth-child "Selectors L3"
* :nth-column "Selectors L4"
* :nth-last-child "Selectors L3"
* :nth-last-column "Selectors L4"
* :nth-last-match "Selectors L4"
* :nth-last-of-type "Selectors L3"
* :nth-match "Selectors L4"
* :nth-of-type "Selectors L3"
* :only-child "Selectors L3"
* :only-of-type "Selectors L3"
* :optional "CSS UI L3"
* :out-of-range "CSS UI L3"
* :past "Selectors L4"
* :placeholder-shown "Selectors L4"
* :read-only "CSS UI L3"
* :read-write "CSS UI L3"
* :required "CSS UI L3"
* :right "CSS Page L3"
* :root "Selectors L3"
* :scope "Selectors L4"
* :target "Selectors L3"
* :top "Shadow Styling"
* :valid "CSS UI L3"
* :valid-drop "Selectors L4"
* :visited "Selectors L3"
