Saltar al contenido
colores.css · devschool

Colores y fondos en CSS

Lección 5 de 25 · 12 min de lectura · Actualizado el

En esta lección
  1. Dos propiedades clave
  2. Formas de escribir un color
  3. Transparencia
  4. currentColor: reutilizar el color del texto
  5. Contraste y accesibilidad
  6. Crear una paleta de colores
  7. Fondos, en breve
  8. Errores frecuentes
  9. Resumen

El color es lo primero que se percibe de una web: transmite la marca, guía la mirada hacia los botones importantes y separa unas zonas de otras. En esta lección aprenderás todas las formas de escribir un color en CSS (nombres, hexadecimal, rgb, hsl y la moderna oklch), a usar transparencias y la palabra clave currentColor, a comprobar que el texto se lee bien y a construir una paleta coherente.

Dos propiedades clave

p {
  color: #1b2d34;            /* color del texto */
  background-color: #f5f5f5; /* color de fondo */
}

color cambia el texto (y, como verás, sirve de referencia para bordes e iconos). background-color pinta el fondo de la caja. Además, muchas otras propiedades aceptan un color: border-color, outline-color, text-decoration-color, accent-color, box-shadow…

color se hereda: si se lo pones a <body>, todo el texto de la página lo toma. background-color no se hereda, pero como por defecto los fondos son transparentes, se ve el del padre.

Formas de escribir un color

Por nombre

Hay unos 140 nombres en inglés: red, white, tomato, navy, rebeccapurple… Útiles para pruebas rápidas, pero en un proyecto real se usan poco: no hay suficientes y no puedes ajustarlos.

color: tomato;
background-color: whitesmoke;

Dos palabras especiales sí se usan mucho: transparent (totalmente transparente) y currentColor, que verás más abajo.

Hexadecimal

La forma más común. # seguido de 6 caracteres: dos para el rojo, dos para el verde y dos para el azul, del 00 (nada) al ff (máximo, 255 en decimal).

color: #ff0000;  /* rojo */
color: #000000;  /* negro */
color: #ffffff;  /* blanco */
color: #2d6cdf;  /* un azul */
color: #fff;     /* forma corta de #ffffff */
color: #2d6cdf80; /* 8 cifras: las dos últimas son la opacidad (80 = 50 %) */

La forma corta de tres cifras funciona cuando cada pareja tiene dos caracteres iguales: #fa0 es #ffaa00. Con 4 u 8 cifras, la última parte es el canal alfa (la opacidad).

Es la forma que te darán los diseñadores y las herramientas de diseño, pero es difícil de “leer”: mirando #2d6cdf no sabes cómo sería una versión más clara.

rgb()

Los mismos tres canales que el hexadecimal, pero en decimal, del 0 al 255:

color: rgb(45 108 223);
color: rgb(45 108 223 / 0.5);   /* con 50 % de opacidad */
color: rgb(45 108 223 / 50%);   /* lo mismo */

Es la sintaxis moderna: valores separados por espacios y la opacidad tras una barra. Verás mucho también la antigua, con comas, y la función rgba():

color: rgb(45, 108, 223);           /* antigua, sigue funcionando */
color: rgba(45, 108, 223, 0.5);     /* antigua, con opacidad */

Hoy rgb() y rgba() son equivalentes: las dos admiten opacidad.

hsl()

Describe el color como lo pensamos las personas:

  • Tono (hue): el ángulo en la rueda de color, de 0 a 360. 0 es rojo, 120 verde, 240 azul.
  • Saturación: 0 % es gris; 100 %, el color más vivo.
  • Luminosidad: 0 % es negro; 100 %, blanco; 50 %, el color “puro”.
color: hsl(220 70% 50%);  /* azul */
color: hsl(220 70% 30%);  /* el mismo azul, más oscuro */
color: hsl(220 70% 90%);  /* el mismo azul, muy claro */
color: hsl(220 70% 50% / 0.5);  /* con opacidad */

Es la más fácil para crear variantes de un mismo color: dejas el tono fijo y mueves la luminosidad. Para hacer el color complementario, sumas 180 al tono.

oklch(): el color moderno

hsl tiene un defecto: su “luminosidad” no coincide con lo que percibe el ojo. Un amarillo y un azul con hsl(... 50%) tienen la misma luminosidad en teoría, pero el amarillo parece muchísimo más claro. Si generas una paleta con hsl, unos colores quedan chillones y otros apagados.

oklch() resuelve esto. Sus tres valores son:

  • L (luminosidad percibida): de 0 (negro) a 1 (blanco), o en porcentaje.
  • C (croma, la intensidad): de 0 (gris) a aproximadamente 0.4.
  • H (tono): ángulo de 0 a 360, como en hsl, aunque los ángulos no coinciden exactamente.
.aviso   { background: oklch(0.65 0.18 30); }   /* naranja rojizo */
.info    { background: oklch(0.65 0.18 250); }  /* azul con la misma claridad percibida */
.exito   { background: oklch(0.65 0.18 145); }  /* verde, también igual de claro */
.suave   { background: oklch(0.95 0.03 250); }  /* azul muy claro */
.semi    { background: oklch(0.65 0.18 250 / 0.5); }

Con la misma L, todos los colores parecen igual de claros, así que el contraste con el texto es predecible. Además, oklch puede representar colores más vivos que las pantallas modernas son capaces de mostrar. Funciona en todos los navegadores actuales.

Comparación rápida

FormatoEjemploVentajasInconvenientes
NombretomatoRápido para pruebasPocos colores, sin control
Hexadecimal#2d6cdfEl más extendido, cortoDifícil de ajustar a mano
rgb()rgb(45 108 223)Claro con la transparenciaTampoco es intuitivo
hsl()hsl(220 70% 50%)Fácil hacer variantesLa luminosidad no es realista
oklch()oklch(0.6 0.15 255)Claridad percibida uniforme, paletas coherentesMenos conocido, valores menos familiares

No hace falta elegir uno para siempre: el navegador los entiende todos y puedes mezclarlos. Una práctica habitual es copiar los hexadecimales del diseño y usar hsl u oklch para crear variantes.

Transparencia

Hay dos maneras, y no son iguales:

.a { background: rgb(0 0 0 / 0.5); } /* solo el fondo es transparente */
.b { opacity: 0.5; }                 /* TODO el elemento, texto incluido */

Con el color con alfa, el texto de dentro sigue nítido. Con opacity, se vuelve translúcido todo: fondo, texto, bordes e hijos. La diferencia se explica con más detalle en degradados, bordes y sombras.

Cualquier formato admite alfa: #00000080, rgb(0 0 0 / 0.5), hsl(0 0% 0% / 0.5), oklch(0 0 0 / 0.5). Y transparent equivale a un negro con opacidad 0.

Un uso muy práctico de la transparencia es crear colores que se adaptan al fondo:

.separador {
  border-top: 1px solid rgb(0 0 0 / 0.1);  /* línea sutil en cualquier fondo claro */
}
.etiqueta {
  background: rgb(45 108 223 / 0.12);   /* un azul muy suave */
  color: #2d6cdf;
}

currentColor: reutilizar el color del texto

currentColor es una palabra clave que vale el color de texto actual del elemento. Parece poca cosa, pero ahorra muchas repeticiones:

.boton-borde {
  color: #2d6cdf;
  border: 2px solid currentColor;   /* el borde, del mismo azul */
}

.boton-borde:hover {
  color: #8e44ad;                   /* cambias un solo valor... */
}                                   /* ...y el borde cambia también */

Es especialmente útil con los iconos SVG: si el icono usa fill="currentColor", toma el color del texto que lo rodea y cambia solo al pasar el ratón por el enlace.

<a class="enlace" href="/carrito/">
  <svg width="16" height="16" viewBox="0 0 16 16" aria-hidden="true">
    <circle cx="8" cy="8" r="6" fill="currentColor" />
  </svg>
  Carrito
</a>
.enlace       { color: #1b2d34; }
.enlace:hover { color: #2d6cdf; }  /* el texto y el icono cambian a la vez */

De hecho, currentColor es el valor por defecto de border-color y outline-color: si escribes border: 2px solid sin color, el borde sale del color del texto.

Contraste y accesibilidad

El texto debe leerse bien sobre su fondo. Un gris claro sobre blanco queda elegante, pero muchas personas no lo leen: gente mayor, con baja visión o que mira el móvil a pleno sol.

La relación de contraste

Las pautas de accesibilidad WCAG miden el contraste entre dos colores con un número que va de 1:1 (el mismo color) a 21:1 (negro sobre blanco). Los mínimos recomendados son:

NivelTexto normalTexto grande (24 px, o 18,66 px en negrita)
AA (el mínimo habitual)4,5:13:1
AAA (el mejor)7:14,5:1

Algunos ejemplos reales sobre fondo blanco:

Color del textoContraste¿Cumple AA para texto normal?
#1b2d34 (casi negro azulado)14,27:1Sí
#2d6cdf (azul)4,86:1Sí, por poco
#767676 (gris medio)4,54:1Sí, es el gris más claro que cumple
#7777774,48:1No, se queda a las puertas
#999999 (gris claro)2,85:1No
#ffd166 (amarillo)1,44:1No, ilegible

Fíjate en que el amarillo, que queda genial como fondo, es imposible de leer como texto sobre blanco. En cambio, #1b2d34 sobre ese amarillo da 9,9:1: perfecto para un botón amarillo con texto oscuro.

Cómo comprobarlo

  • Las herramientas de desarrollo del navegador: al inspeccionar un texto y hacer clic en su color, muestran la relación de contraste y si cumple AA o AAA.
  • Comprobadores en línea como WebAIM Contrast Checker: pegas los dos colores y te da el resultado.
  • La auditoría de Lighthouse (en Chrome) marca los textos con contraste insuficiente.

Cuidado: no transmitas información solo con el color. Un campo con error marcado solo en rojo no lo distingue quien tiene daltonismo (alrededor del 8 % de los hombres). Añade un icono o un texto.

Crear una paleta de colores

Una web profesional no usa colores sueltos elegidos al azar. Usa una paleta pequeña y la repite con coherencia:

PapelPara quéEjemplo
PrincipalMarca, botones, enlacesAzul #2d6cdf
AcentoLlamar la atención puntualmenteNaranja #e76f51
NeutrosTexto, fondos, bordes (varios tonos de gris)#1b2d34, #667085, #dde3ee, #f3f5f9
EstadosÉxito, aviso, error, informaciónVerde, amarillo, rojo, azul

Consejos para montarla:

  1. Pocos colores. Uno principal, uno de acento y una escala de grises bastan para empezar.
  2. Escalas de claridad. De cada color, varias versiones: muy clara para fondos, media para botones, oscura para texto. Con oklch basta con variar la L:
.azul-50  { background: oklch(0.97 0.02 255); }  /* fondos suaves */
.azul-200 { background: oklch(0.85 0.07 255); }
.azul-500 { background: oklch(0.60 0.16 255); }  /* botones */
.azul-800 { background: oklch(0.35 0.10 255); }  /* texto sobre fondos claros */
  1. Grises con un toque de color. Un gris ligeramente azulado (#1b2d34 en vez de #222) queda más cuidado y combina con el color principal.
  2. Regla 60-30-10. Aproximadamente, un 60 % de color neutro (fondo), un 30 % de color secundario y un 10 % de acento. Si todo es llamativo, nada destaca.
  3. Comprueba el contraste de cada combinación de texto y fondo que vayas a usar.

Para no repetir estos valores en todo el CSS, lo habitual es guardarlos en variables (--principal, --texto…). Así cambiar la paleta, o crear un modo oscuro, es cuestión de unas pocas líneas. Lo tienes en variables CSS.

Fondos, en breve

Además de un color, el fondo de un elemento puede ser un degradado o una imagen:

.cabecera {
  background: linear-gradient(to right, #2d6cdf, #8e44ad);  /* degradado */
}

.portada {
  background: #1b2d34 url("img/portada.jpg") center / cover no-repeat;  /* imagen */
}

Todos los detalles (tamaño, posición, repetición, varios fondos, degradados radiales y cónicos) están en degradados, bordes y sombras.

Errores frecuentes

  • Hexadecimal sin #. color: 2d6cdf; no funciona.
  • Mezclar sintaxis. rgb(45, 108 223) (comas y espacios a la vez) es inválido. Usa solo espacios (moderna) o solo comas (antigua).
  • Usar opacity para un fondo translúcido. El texto también se vuelve translúcido. Usa un color con alfa.
  • Poco contraste. Grises claros sobre blanco o texto blanco sobre amarillo. Compruébalo siempre.
  • Solo color para dar información. Añade iconos o texto.
  • Demasiados colores. Una paleta pequeña se ve más profesional.
  • Repetir el mismo hexadecimal en 30 reglas. Guárdalo en una variable.

Resumen

ConceptoEjemploCuándo usarlo
NombretomatoPruebas rápidas
Hexadecimal#2d6cdf, #2d6cdf80Copiar colores de un diseño
rgb()rgb(45 108 223 / 0.5)Colores con transparencia
hsl()hsl(220 70% 30%)Variantes de un mismo color
oklch()oklch(0.6 0.15 255)Paletas coherentes y modernas
transparentbackground: transparentQuitar un fondo
currentColorborder: 2px solid currentColorBordes e iconos del color del texto
Contraste4,5:1 como mínimoSiempre que haya texto sobre un fondo

Ahora que dominas el color, pasa a sacarle partido en fondos, degradados y sombras en degradados, bordes y sombras.

Pruébalo tú

Cambia el código y pulsa Ejecutar (o Ctrl + Enter).

colores.html
Resultado

Pon a prueba lo que has aprendido

[CSS] ¿Qué color es #ff0000?

[CSS] ¿Qué diferencia hay entre opacity: 0.5 y background: rgb(0 0 0 / 0.5)?

[CSS] Al pasar el ratón por el botón, ¿de qué color queda el borde?
.boton {
  color: #2d6cdf;
  border: 2px solid currentColor;
}
.boton:hover {
  color: #8e44ad;
}

[CSS] Según las pautas WCAG (nivel AA), ¿qué contraste mínimo necesita el texto normal sobre su fondo?

¿Te ha quedado claro? Márcala y verás tu progreso en el explorador.