Saltar al contenido

CSS, de a poco

Curso de CSS

Fondos y degradados

Lección 16 de 37 · 6 min

Un degradado es una imagen que el navegador dibuja: no pesa nada, se adapta a cualquier tamaño y se apila con otras capas. Con eso alcanza para rayados, cuadrículas, gráficos de torta y texto pintado.

Degradados lineales

linear-gradient() devuelve una imagen, así que va en background-image, no en background-color. Primero la dirección, después las paradas de color. La dirección es un ángulo (0deg apunta arriba y gira como un reloj) o una palabra clave como to right; si falta, vale to bottom.

degradados.css
.banda {
background-image:
linear-gradient(to right, oklch(0.55 0.2 262), oklch(0.88 0.17 92));
}
.diagonal {
background-image:
linear-gradient(135deg, oklch(0.55 0.2 262), oklch(0.88 0.17 92));
}

El degradado recorre la línea del degradado, que pasa por el centro de la caja. Su largo no es el ancho ni el alto: termina donde una perpendicular toca la esquina más lejana, así los colores de las puntas caen justo en las esquinas. Por eso, en una caja rectangular, la línea de 45° es más larga que el lado.

Cada parada puede llevar una posición. Si dos paradas comparten la misma, no hay mezcla: el color cambia de golpe (un corte duro). Una parada también acepta dos posiciones, que pintan una franja sólida: azul 0 50% es lo mismo que azul 0, azul 50%.

Mové el ángulo y mirá la línea naranja: la flecha es la dirección, las marcas son las paradas y las punteadas muestran hasta qué esquina llega.

gradient
línea de 368px en una caja de 320px

Muestra pintada con un degradado linear, de azul a amarillo, mezclado en srgb.

Espacio de mezcla
muestra.css
.muestra {
/* sin soporte de `in`: mezcla en srgb */
background-image: linear-gradient(135deg, oklch(0.55 0.2 262), oklch(0.88 0.17 92));
background-image: linear-gradient(135deg in srgb, oklch(0.55 0.2 262), oklch(0.88 0.17 92));
}
muestra.html
<div class="bg-linear-135/srgb from-[oklch(0.55_0.2_262)] to-[oklch(0.88_0.17_92)]"></div>

Radiales y cónicos

radial-gradient() sale desde un punto hacia afuera. Acepta forma (circle o ellipse, que es la de por defecto), tamaño y centro con at. El tamaño por defecto es farthest-corner: el último color llega a la esquina más lejana. También existen closest-side, closest-corner y farthest-side, o un largo fijo.

conic-gradient() gira alrededor del centro, como las agujas de un reloj. from dice dónde arranca y las paradas van en grados o porcentajes de la vuelta. Con cortes duros es un gráfico de torta sin una línea de JavaScript.

foco-y-torta.css
.foco {
background-image:
radial-gradient(circle at 30% 20%, oklch(0.95 0.05 90), transparent 60%);
}
/* 45% · 30% · 25%: cada parada empieza donde termina la anterior */
.torta {
border-radius: 50%;
background-image: conic-gradient(
oklch(0.6 0.18 262) 0 45%,
oklch(0.75 0.15 160) 45% 75%,
oklch(0.85 0.15 90) 75% 100%
);
}
A la izquierda, una foto de cerámicas oscurecida con una luz cálida que sale de un punto al 30% del ancho y al 20% del alto: un radial-gradient. A la derecha, un gráfico de torta hecho con conic-gradient: café 45%, mate 30% y té 25%, empezando arriba, en 0deg.

En qué espacio se mezclan

Entre dos paradas el navegador interpola, y el resultado depende del espacio de color. En srgb, azul y amarillo se cruzan en un gris apagado. En oklab el medio mantiene la luminosidad pareja. En oklch el tono gira por el círculo cromático y pasa por el verde. Se elige con in, pegado a la dirección: linear-gradient(90deg in oklch, …).

Si no ponés in, los colores clásicos (hex, rgb(), hsl()) se mezclan en srgb, como siempre; cuando aparece alguno moderno, como oklch(), la especificación manda mezclar en oklab. En oklch también podés elegir el camino del tono: in oklch longer hue da la vuelta larga por el círculo.

El mismo degradado de azul a amarillo mezclado en tres espacios: en srgb el medio es un gris apagado, en oklab la luz se mantiene pareja y en oklch pasa por el verde.

La sintaxis in es Baseline desde junio de 2024 (Chrome 111, Safari 16.2, Firefox 127). Un navegador más viejo descarta la declaración entera, así que conviene escribir antes una versión sin in: el que no entiende la segunda se queda con la primera.

Degradados que se repiten

repeating-linear-gradient(), repeating-radial-gradient() y repeating-conic-gradient() repiten las paradas hasta llenar la caja. Las posiciones van en largos fijos (o grados), no en porcentajes del total. Con cortes duros salen rayas; con paradas suaves, ondas.

Una cinta de obra amarilla y negra cruza en diagonal la foto de una sala blanca. Las rayas son un solo par de franjas de 12px repetido con repeating-linear-gradient.
cinta.css
/* cinta de obra: franjas de 12px a 45° */
.cinta {
background-image: repeating-linear-gradient(
45deg,
oklch(0.85 0.17 90) 0 12px,
oklch(0.25 0 0) 12px 24px
);
}

Varias capas

background-image acepta una lista separada por comas. La primera capa queda arriba y la última abajo, y debajo de todas va background-color. Cada propiedad de fondo también acepta una lista, y el valor en la posición 1 va con la capa 1. Si una lista es más corta, se repite.

  1. Tamañobackground-sizeEl tamaño de un mosaico. 24px 24px es una baldosa; cover y contain escalan una imagen a la caja.
  2. Posiciónbackground-positionDónde arranca el mosaico, como center o right 8px bottom 8px.
  3. Repeticiónbackground-repeatrepeat, no-repeat, repeat-x, y también space y round, que ajustan para que no quede un mosaico cortado.
  4. Anclajebackground-attachmentCon scroll (por defecto) el fondo queda fijo a la caja; con local se mueve con el contenido que se desplaza adentro; con fixed queda fijo a la ventana.

La hoja de abajo no tiene ninguna imagen: los renglones son un degradado con un corte duro de 1px, repetido según el background-size, y el margen es otra capa encima. Desplazá la hoja con local y después con scroll: con local el texto sigue apoyado en sus renglones; con scroll los renglones se quedan quietos y el texto se les corre encima.

Patrón del papel
desplazá la hoja

Medialunas

500 g de harina

250 g de manteca fría

2 huevos y un poco de leche

Almíbar para pintar

Horno a 200°, 15 minutos

Estirar y cortar en triángulos.

Enrollar desde la base.

Leudar una hora, tapadas.

Pintar apenas salen del horno.

capas, de arriba a abajo

  1. margenauto
  2. renglones100% 24px
  3. color del papelcolor
background-attachment
hoja.css
.hoja {
--papel: oklch(0.985 0.012 95);
--renglon: oklch(0.8 0.06 245);
--margen: oklch(0.66 0.17 25);
height: 232px;
overflow-y: auto;
padding: 24px 16px 0 52px;
line-height: 24px;
background-color: var(--papel);
background-image:
linear-gradient(to right, transparent 39px, var(--margen) 39px 40px, transparent 40px),
linear-gradient(to bottom, transparent calc(100% - 1px), var(--renglon) 0);
background-size: auto, 100% 24px;
background-repeat: no-repeat, repeat;
background-attachment: local;
}
@media (prefers-color-scheme: dark) {
.hoja {
--papel: oklch(0.26 0.01 250);
--renglon: oklch(0.42 0.05 245);
--margen: oklch(0.6 0.15 25);
}
}
hoja.html
<div class="[--papel:oklch(0.985_0.012_95)] [--renglon:oklch(0.8_0.06_245)] [--margen:oklch(0.66_0.17_25)] dark:[--papel:oklch(0.26_0.01_250)] dark:[--renglon:oklch(0.42_0.05_245)] dark:[--margen:oklch(0.6_0.15_25)] h-58 overflow-y-auto pt-[24px] pr-4 pl-13 leading-[24px] bg-(--papel) bg-[image:linear-gradient(to_right,transparent_39px,var(--margen)_39px_40px,transparent_40px),linear-gradient(to_bottom,transparent_calc(100%_-_1px),var(--renglon)_0)] bg-size-[auto,100%_24px] bg-[repeat:no-repeat,repeat] bg-local">
…
</div>

El atajo background junta todo en una capa por coma, con el tamaño después de la posición y una barra: background: url(papel.webp) center / cover no-repeat, oklch(0.98 0.01 95). El color solo puede ir en la última capa. local funciona en los navegadores principales; fixed todavía no funciona bien en Safari de iOS.

Hasta dónde llega el fondo

Dos propiedades parecidas que hacen cosas distintas. background-origin dice desde qué caja se posiciona y mide el fondo (por defecto, padding-box). background-clip dice hasta dónde se pinta (por defecto, border-box, o sea también debajo del borde).

Con background-clip: text el fondo se pinta solo dentro de las letras. Para verlo, el color del texto tiene que ser transparente. Si el navegador no lo entiende, ese color: transparent dejaría el texto invisible, así que va dentro de @supports y afuera queda un color sólido de respaldo. Probá cada valor de background-clip y cambiá el origen: la línea naranja marca hasta dónde se pinta el fondo.

background-clip
pinta bajo el borde

La palabra Otoño sobre un degradado que se pinta hasta el border-box y se mide desde el padding-box.

background-origin
apertura.css
.apertura {
--desde: oklch(0.6 0.2 40);
--hasta: oklch(0.42 0.2 300);
padding: 16px;
border: 12px dashed oklch(0.5 0 0 / 35%);
border-radius: 8px;
font-size: 56px;
color: oklch(0.99 0 0);
background-image: linear-gradient(135deg in oklch, var(--desde), var(--hasta));
background-origin: padding-box;
background-clip: border-box;
}
@media (prefers-color-scheme: dark) {
.apertura {
--desde: oklch(0.82 0.14 65);
--hasta: oklch(0.74 0.16 320);
color: oklch(0.2 0 0);
}
}
apertura.html
<h2 class="p-4 border-12 border-dashed border-neutral-500/35 rounded-lg text-[56px] bg-linear-135/oklch from-[oklch(0.6_0.2_40)] to-[oklch(0.42_0.2_300)] dark:from-[oklch(0.82_0.14_65)] dark:to-[oklch(0.74_0.16_320)] bg-origin-padding bg-clip-border text-[oklch(0.99_0_0)] dark:text-[oklch(0.2_0_0)]">Otoño</h2>

text sin prefijo llegó a Chrome en la versión 120 y a Safari en la 14; antes solo andaba -webkit-background-clip: text, que muchos todavía agregan por las dudas. Firefox lo soporta con limitaciones, así que no es Baseline: dejá siempre un color legible de respaldo.

En Tailwind

Tailwind arma los degradados con una clase de dirección y las paradas con from-*, via-* y to-*. El espacio de mezcla va como modificador después de la barra; sin modificador, Tailwind usa oklab. Repetidos y varias capas no tienen clase: van entre corchetes, como bg-[repeating-linear-gradient(45deg,…)].

CSSTailwind
linear-gradient(135deg in oklch, …)bg-linear-135/oklch
radial-gradient(at 30% 20%, …)bg-radial-[at_30%_20%]
conic-gradient(from 90deg, …)bg-conic-90
paradas con corte durofrom-50% to-50%
background-size · attachmentbg-size-[24px_24px] · bg-local
background-clip: textbg-clip-text
titulo.html
<!-- texto con degradado y color de respaldo si no hay soporte -->
<h2 class="bg-linear-135/oklch
from-[oklch(0.6_0.2_40)] to-[oklch(0.42_0.2_300)]
bg-clip-text text-[oklch(0.42_0.2_300)]
supports-[background-clip:text]:text-transparent">
Otoño
</h2>