Uso avanzado de colores y selectores¶
Veremos a continuación algunas opciones de CSS algo avanzadas, como selectores más específicos, o uso avanzado de colores con transparencias y degradados.
1. Selectores avanzados¶
Vamos a dar una vuelta más de tuerca a lo que son los selectores CSS. En un documento anterior hemos visto que fundamentalmente se utilizan cuatro tipos: de etiqueta, descendente, de clase y de id. Pero existen algunos otros que pueden sernos útiles
El selector de hijos es similar al descendente, pero aplica el estilo sólo a etiquetas que cuelguen directamente de la contenedora. Por ejemplo, para aplicar un estilo a negritas que están en párrafos (sin etiquetas intermedias), pondremos:
p > strong { ... }
El selector adyacente se utiliza para aplicar un estilo a un elemento que sea hermano adyacente de otro (es decir, a continuación de otro). Por ejemplo, para cursivas que vayan detrás de negritas (no dentro de ellas) usamos:
strong + em { ... }
Alternativamente, el selector de hermanos es menos restrictivo que el anterior: se aplica a los elementos de un tipo que vayan después de uno dado (sin que necesariamente sea inmediatamente después). Por ejemplo, este selector afecta a los párrafos que vayan después de un h1:
h1 ~ p { ... }
El selector de atributos se utiliza para aplicar el estilo a las etiquetas que tengan un atributo con un cierto valor. Ponemos la etiqueta, y luego entre corchetes el atributo y el valor que debe tener, entre comillas. Por ejemplo, si queremos aplicar un estilo a todos los enlaces que vayan a la página de la Universidad de Alicante, pondríamos algo como:
a[href="https://www.ua.es"] { ... }
Sobre este último selector existen algunas variantes interesantes, que comentamos a continuación:
a[href]
a secas se aplicaría a todos los enlaces que tengan atributohref
- `a[href="ua"] se aplica a los enlaces cuya URL contenga el texto ua*
- `a[href^="https://"] se aplica a enlaces cuya URL comiente por https://
a[href$=".com" i]
se aplica a enlaces cuya URL termine en .com, sin distinguir mayúsculas o minúsculas (la i permite esto último).- `a[class~="btn"] se aplica si el elemento tiene una lista de valores en class, y uno de ellos es btn
1.1. Las pseudoclases¶
Ya hemos visto anteriormente que en algunos selectores podemos emplear pseudoclases para concretar un estado particular del elemento. Se identifican con el prefijo :
; así, el selector a:hover
se aplica a los enlaces cuando estamos pasando el ratón por encima de ellos. Existen otras pseudo-clases que podemos aplicar en diferentes elementos para referirnos a estados o subelementos concretos. Vamos a verlas a continuación agrupadas por categorías.
1.1.1. Pseudoclases de enlaces¶
Aunque ya las hemos visto en algún documento anterior, podemos emplear las siguientes pseudoclases para referirnos al estado de los enlaces de un documento:
:link
: para enlaces aún no visitados:visited
: para enlaces ya visitados
La siguiente regla define el color de texto para enlaces no visitados:
a:link
{
color: red;
}
1.1.2. Pseudoclases de ratón¶
Según el movimiento del ratón en la página, podemos definir estas pseudoclases:
:hover
: el ratón pasa por encima del elemento indicado (enlace, párrafo, etc):active
: hacemos clic con el ratón encima del elemento indicado
Esta regla pone el color de fondo de los párrafos a amarillo cuando hacemos clic sobre ellos:
p:active
{
background-color: yellow;
}
1.1.3. Pseudoclases de formularios¶
Algunas pseudoclases se aplican sobre estados o controles de formularios:
:focus
: se aplica sobre el elemento que tiene el foco:checked
: se aplica sobre casillas de checkbox cuando se marcan. También se aplica sobre botones de radio cuando se elige esa opción, y sobre listas.:enabled
: se aplica sobre los elementos activados:disabled
: se aplica sobre elementos desactivados (sobre los que el usuario no puede interactuar):read-only
: para elementos marcados como de sólo lectura
La siguiente regla pone el borde de color verde sobre el elemento que tenga el foco
input:focus
{
border: 1px solid green;
}
También existen pseudoclases específicas para la validación de los campos:
:required
: para elementos que sea obligatorio rellenar:optional
: para elementos que no sea obligatorio rellenar (es decir, no tienen el atributorequired
):invalid
: cuando el elemento no cumple las reglas de validación que se le aplican:valid
: cuando el elemento cumple las reglas de validación:out-of-range
: cuando el valor del elemento excede del límite que se le ha aplicado (valores numéricos fuera de rango):in-range
: para valores numéricos dentro del rango
Esta regla pone el borde rojo en los campos que no sean válidos:
input:invalid
{
border: 1px solid red;
}
1.1.4. Pseudoclases para selección por condiciones¶
Veremos a continuación algunas pseudoclases que nos pueden servir para aplicar estilos a elementos dependiendo del tipo que sean.
:not
: se aplica a los elementos que no cumplan la condición indicada. Por ejemplo, para expresar que nos referimos a divs que no sean de clase principal, pondríamosdiv:not(.principal)
.:has
: selecciona el elemento si sus hijos cumplen una serie de criterios. Por ejemplo, esta regla se aplica sobre el enlace sólo si contiene una imagen:
a:has(>img) { ... }
:is
: recibe como argumentos una lista de selectores, y aplica los estilos a cualquier elemento que encaje con uno de esos selectores.:where
también recibe como argumentos una lista de selectores y aplica los estilos a cualquier elemento que encaje con uno de ellos. Puede parecer idéntica a:is
, pero se diferencian en la especificidad: mientras que is respeta la especifidad de cada selector, where las iguala todas.
Para entender mejor la diferencia entre estas dos pseudoclases veamos este ejemplo:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>Ejemplo :is vs :where</title>
<style>
/* RESET con :where -> especificidad 0 */
:where(h1, h2, h3) {
margin: 0;
color: gray;
}
/* Estilo con :is -> mantiene especificidad */
article :is(h1, h2, h3) {
color: darkblue;
}
/* Una regla de clase normal */
.especial {
color: red;
}
</style>
</head>
<body>
<h1>Título fuera de article</h1>
<article>
<h2>Subtítulo dentro de article</h2>
<h2 class="especial">Subtítulo dentro de article con clase</h2>
</article>
</body>
</html>
Al aplicar la regla where
, todos los encabezados se ponen a color gris sin margen (es una especie de reseteo). Luego, sobre el primer encabezado h2
del artículo se aplica el is
, y lo pone de color azul oscuro (manteniendo el margen 0 dejado por where
). Finalmente, sobre el segundo encabezado del artículo se aplica la regla de selector especial
, al ser más específica, dejándolo de color rojo (y con el margen 0 del reseteo de where
).
Como vemos, la cláusula where
es útil para resetear a valores por defecto, y luego con is
o selectores de clase específicos podemos afinar mejor el estilo de ciertos elementos concretos.
1.1.5. Pseudoclases para selección por DOM¶
También disponemos de varias pseudoclases para elegir elementos según la posición que ocupan en la jerarquía:
:first-child
: para aplicar un estilo a la primera etiqueta de la que estamos tratando. Por ejemplo,div > p:first-child
sólo se aplicará a los párrafos que sean los primeros hijos de un div.:first-of-type
: para identificar el primer elemento que sea de un tipo dentro de una secuencia. Por ejemplo,div > p:first-of-type
se aplicará al primer párrafo de un div, aunque haya otras cosas antes.:nth-child(x)
: podemos indicar estilos concretos para elementos concretos de una secuencia. Por ejemplo,li:nth-child(even)
aplica los estilos a los items pares de una secuencia, yli:nth-child(odd)
aplicaría a los impares. El selectorli:nth-child(4)
aplica el estilo al cuarto item en la lista, y el selectorli:nth-child(4n)
lo aplica cada cuatro elementos.:last-child
,:last-of-type
,nth-of-type(x)
,nth-last-child(x)
ynth-last-of-type(x)
se usan de forma análoga a las anteriores, para empezar a revisar desde el final (últimos elementos).
Podéis aprender más sobre pseudo-clases y sus usos en webs como ésta.
Ejercicio 1
Dado el siguiente contenido HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prueba</title>
</head>
<body>
<section id="inicio">
<h2>Inicio</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae, aliquam!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing.</p>
</section>
<section id="contenido">
<h2>Contenido</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae, aliquam!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing.</p>
</section>
<section id="fin">
<h2>Fin</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae, aliquam!</p>
<p>Lorem ipsum dolor sit amet consectetur, adipisicing elit.</p>
<p>Lorem ipsum dolor sit amet consectetur adipisicing.</p>
</section>
<section id="tabla">
<table>
<tr>
<td>Lorem, ipsum dolor.</td>
<td>Ab, deserunt officia!</td>
<td>Amet, temporibus molestiae.</td>
<td>Facere, corrupti praesentium?</td>
</tr>
<tr>
<td>Lorem, ipsum dolor.</td>
<td>Similique, voluptates suscipit!</td>
<td>Commodi, asperiores sunt?</td>
<td>Veniam, voluptatibus unde.</td>
</tr>
<tr>
<td>Lorem, ipsum dolor.</td>
<td>Soluta, perferendis fuga.</td>
<td>At, similique sunt?</td>
<td>Asperiores, unde atque?</td>
</tr>
<tr>
<td>Lorem, ipsum dolor.</td>
<td>Corrupti, saepe quo.</td>
<td>Voluptates, tempore eius!</td>
<td>Consequatur, laboriosam vero?</td>
</tr>
<tr>
<td>Lorem, ipsum dolor.</td>
<td>Officiis, illum dolorem.</td>
<td>Obcaecati, alias qui!</td>
<td>Necessitatibus, sunt deserunt.</td>
</tr>
</table>
</section>
</body>
</html>
Queremos que las filas pares de la tabla se muestren con un fondo gris, y que el primer párrafo de cada sección tenga letra cursiva. Además, queremos que la tabla ocupe el 100% del ancho disponible, con un borde negro de 1 píxel de grosor y colapsado. Indica qué reglas CSS deberíamos aplicar para conseguirlo.
1.2. Pseudoelementos¶
Los pseudoelementos hacen referencia a elementos que realmente no existen como tales en la página, pero a los que se puede referenciar desde CSS. Por ejemplo, la primera letra de una palabra, o la primera línea de un párrafo. Estos pseudoelementos se representan con el prefijo ::
. Aquí nombramos los más importantes o habituales:
::before
y::after
: permiten insertar código antes o después del contenido real de un elemento, respectivamente. Por ejemplo, de este modo añadiríamos el texto---
antes del contenido de un encabezado 1 de clase titulo.
h1.titulo::before
{
content: "---";
color: black; /* Color del texto añadido */
}
::first-letter
y::first-line
hacen referencia a la primera letra o primera línea, respectivamente, del elemento aludido. Por ejemplo, esta regla pone de color rojo la primera línea de los párrafos.
p::first-line
{
color: red;
}
1.3. Combinando selectores¶
Los selectores y opciones vistos antes se pueden combinar de varias formas, creando en ocasiones estructuras algo complejas de identificar. En cualquier caso, el orden que debemos aplicar siempre es el siguiente:
selector#id.clase:pseudoclase::pseudoelemento[atributo] { ... }
2. Uso avanzado de colores¶
Como ya hemos visto anteriormente, hasta CSS2 teníamos básicamente tres formas de especificar el color de un elemento en una página: con un nombre de color simple (red
, yellow
...), con su código de colores en RGB decimal (tres cifras de 0 a 255 para cada componente rojo, verde y azul, por ejemplo: rgb (12, 116, 52)
), y con su código de colores RGB en hexadecimal (siguiendo la misma filosofía del anterior, pero con formato hexadecimal, por ejemplo: #FF2E34
).
CSS3 incorpora novedades interesantes en este conjunto de formatos de color, como es la inclusión del nivel de transparencia u opacidad de un elemento, o el uso de degradados.
2.1. Transparencia¶
Con CSS3 podemos definir el grado de transparencia u opacidad que va a tener el color de un elemento (tanto color de texto como color de fondo), añadiendo un cuarto elemento a los tres colores RGB, pasando a ser un formato (la A viene de alpha, nombre con el que suele hacerse referencia a la transparencia).
Este cuarto elemento es un número decimal que va desde el 0 (totalmente transparente) hasta el 1 (totalmente opaco). Si decidimos usar la transparencia, entonces deberemos especificar el color usando la función rgba
de esta forma:
h1
{
background-color: rgba(12, 116, 52, 0.5);
}
donde los tres primeros números expresan la cantidad de rojo, verde y azul, como antes, y el cuarto número es la transparencia.
Una alternativa diferente es utilizar la propiedad opacity
en el CSS, con valores también entre 0 y 1:
p
{
background-color: rgb(12, 116, 52);
opacity: 0.5;
}
La diferencia con lo anterior es que, usando opacity, la opacidad afecta al elemento y a todos los subelementos que contenga, incluyendo el texto (que podría ser entonces parcialmente transparente sin nosotros quererlo).
2.2. Degradados¶
Un degradado es una transición progresiva desde un color a otro. En el caso de CSS, existen tres tipos de degradados: lineales, radiales y cónicos.
2.2.1. Degradados lineales¶
Un degradado lineal es un efecto por el que pasamos gradualmente de un color a otro, siguiendo un eje horizontal, vertical o en cualquier otra dirección. Con CSS3 podemos conseguir este efecto con la función linear-gradient
. Entre paréntesis (sin dejar espacio antes del paréntesis), indicaremos ciertos valores:
- La dirección del degradado, que podemos indicarla de tres formas distintas:
- Indicando hacia qué lado ir: to top, to bottom, to left o to right
- Indicando desde qué extremo partir: top left, top right, bottom left o bottom right
- Indicando un ángulo en grados (deg), donde 0deg apunta hacia arriba y 90deg hacia la derecha.
- Por defecto, si no se indica, es de arriba a abajo.
- Dos o más colores (separados por comas), que serán los colores hacia los que se va a ir cambiando gradualmente (de uno al siguiente). Junto a cada color, se puede indicar un porcentaje, que expresa en qué punto del recorrido se tendrá ese color
Por ejemplo, el siguiente degradado va hacia la derecha, parte del blanco, pasa por un rojo a mitad de camino, y termina en un negro.
div
{
background-image: linear-gradient(90deg, #FFFFFF, #FF0000 50%, #000000);
}
Obtendríamos este resultado:
Existen otras muchas variantes de uso de degradados lineales, y algunas incompatibilidades con algunos formatos dependiendo del navegador, pero este ejemplo nos puede servir de muestra de lo que se puede hacer.
2.2.2. Degradados radiales¶
Un degradado radial es otro tipo de degradado donde se pasa de un color en un punto concreto de un determinado elemento (por defecto, el centro del mismo) y se va cambiando gradualmente hacia otro color, en todas direcciones a partir de ese punto. Este degradado se obtiene con la función radial-gradient
.
El siguiente ejemplo crea un degradado radial de forma circular hasta el lado más cercano, y pasa del negro al blanco.
div
{
background-image: radial-gradient(circle closest-side, black, white);
}
y obtendríamos algo como esto:
Si lo aplicamos al lado más lejano (farthest-side), obtenemos esto otro:
Algunos parámetros útiles de configuración:
- La forma del degradado puede ser circular (
circle
) o elíptica (ellipse
, valor por defecto). Se puede especificar también un tamaño en píxeles. - El punto de finalización puede ser el lado más cercano (
closest-side
), el más lejano (farthest-side
) y también el extremo más cercano (closest-corner
) o más lejano (farthest-corner
, valor por defecto). - También podemos indicar el punto inicial de aplicación, con la palabra
at
seguido del punto de anclaje elegido (center
,top
,bottom right
...) - Después vienen los colores a utilizar, indicando opcionalmente en cada uno el porcentaje o punto donde aplicarlo.
Otros ejemplos:
/* Gradiente elíptico */
background-image: radial-gradient(ellipse, gold 50%, red 55%, black 75%);
/* Gradiente circular de 400px anclado a la izquierda */
background-image: radial-gradient(circle 400px at left, gold 50%, red 55%, black 75%);
2.2.3. Gradientes cónicos¶
Los gradientes cónicos son similares a los radiales, y provocan un degradado en forma de cono visto desde arriba. Para indicar desde dónde aplicar el degradado usaremos la palabra from
seguida de un ángulo en grados, que indica desde qué dirección empiezan a cambiarse los colores (por defecto 0º, que corresponde con el sentido hacia arriba). A partir de ahí, los colores se distribuyen en sentido horario. Luego indicamos dónde queremos colocar el centro del gradiente (usando at
) y los colores implicados. Aquí vemos algunos ejemplos:
background-image: conic-gradient(from 45deg, blue, red);
Podemos emplear la función repeating-conic-gradient
para repetir sucesivamente la secuencia indicada:
background-image: repeating-conic-gradient(blue 10%, yellow 20%, red 30%);
2.3. Otros modelos de color¶
Además del modelo RGB (o RGBA, en el caso de añadir el canal de transparencia), en versiones recientes de CSS se han añadido otras formas de definir el color de los elementos.
2.3.1. Modelo HSL¶
El modelo HSL (Hue, Saturation, Lightness, o Tono, Saturación y Brillo) es otro modelo que define los colores en base a otros parámetros diferentes, que resultan a menudo más intuitivos a la hora de crear colores o paletas de colores.
Se define usando la función hsl
de CSS, donde podemos emplear tres parámetros:
- Su tono (H), que define el tipo de color que usaremos (tono rojo, verde...). Toma valores en torno a una cirfunferencia de 0 a 360º, donde el 0 es el tono rojo, 120 verde y 240 azul, y en medio van todas las tonalidades intermedias entre estos tres colores.
- La saturación (S), que define cuánta cantidad de ese color queremos. Toma un valor porcentual de 0 a 100% (o de 0 a 1), siendo 0 un tono gris (sin color) y 100 el color vivo y puro.
- La luminosidad (L) del color elegido. También toma un valor porcentual, siendo 0 ninguna luminosidad (negro) y 100 toda la luminosidad (blanco)
- Adicionalmente, se le puede añadir también una transparencia (canal alpha), empleando en este caso la función
hsla
en lugar de la anterior.
Veamos algunos ejemplos:
/* Azul intenso */
color: hsl(200, 100%, 50%)
/* Rosa claro */
color: hsl(0, 100%, 75%)
/* Verde translúcido */
color: hsla(120, 100%, 50%, 0.3)
2.3.2. Otras funciones modernas¶
Existen también otras funciones modernas en CSS que definen el color en base a ciertos parámetros. Su principal utilidad radica en poder definir el color de una forma más sencilla, o de una forma más exacta con el color real, ya que, a menudo, el color que vemos en un dispositivo, o en la vida real, no coincide exactamente con el que estamos plasmando en nuestro CSS al crear una página similar.
- La función
hwb
(hue, whiteness, blackness), define el color en base al tono (entre 0 y 360, similar a HSL), el nivel de claridad (porcentaje) y el de oscuridad (otro porcentaje). También podemos indicar un nivel de transparencia tras el símbolo/
. Los valores se representan separados por espacios.
/* Rojo puro (sin blancos ni negros) */
color: hwb(0 0% 0%);
/* Rosa pálido (algo de blanco) */
color: hwb(0 30% 0%);
/* Azul marino translúcido */
color: hwb(240 0% 60% / 0.5);
/* Gris (cualquier color con 50% de blanco y 50% de negro) */
color: hwb(200 50% 50%);
- Las funciones
lab
ylch
se refieren al espacio de color perceptual. LCA define la luminosidad (L, porcentual), el nivel de rojo-verde (A, negativo hacia verde, positivo hacia rojo), y el nivel de azul-amarillo (B, negativo hacia azul, positivo hacia amarillo). En el caso de LCH, la L sigue siendo la luminosidad, la C es el chroma (saturación, de 0 en adelante) y la H el tono, siendo similar entonces al modelo HSL (aunque perceptualmente uniforme). En ambos casos se puede añadir un componente de transparencia.
/* Rojo-amarillento medio */
color: lab(50% 80 70);
/* Naranja vivo medio */
color: lch(50% 80 40);
- Posteriormente surgieron las funciones
oklab
yoklch
que mejoran la precisión perceptual de las anteriores, y son más adecuadas para pantallas modernas. - Finalmente, la función
color
permite mostrar colores en espacios diferentes al sRGB tradicional de la web. Esto es útil también para pantallas recientes, como monitores HDR, que son capaces de mostrar más colores de los que permite sRGB. En la sintaxis general debemos indicar el modelo de color a usar (por ejemplo,srgb
,display-p3
,a98-rgb
...), los canales configurados y, opcionalmente, el nivel de transparencia.
/* Rojo puro en sRGB */
color: color(srgb 1 0 0);
/* Rojo puro en Display-P3 */
color: color(display-p3 1 0 0);
/* Verde translúcido en Rec.2020 */
color: color(rec2020 0 1 0 / 0.5);