Esto es un extra. Con lo anterior ya sabes maquetar una web correcta, accesible y responsive. Este capítulo no enseña nada imprescindible: enseña el remate, lo que hace que una página pase de “bien hecha” a “parece diseñada”. Justo por eso la regla aquí es la mesura: estas herramientas, mal usadas, ensucian más que aportan. Menos suele ser más.
Hay cuatro cosas que marcan casi toda la diferencia entre una web plana y una con cara y ojos: sombras (profundidad), degradados (color con volumen), transiciones (que las cosas se muevan suave) y una fuente propia (personalidad). Vamos una a una.
Sombras: box-shadow#
Una sombra despega un elemento del fondo y sugiere que está “por encima”. La
propiedad es box-shadow y sus valores son: desplazamiento horizontal, vertical,
desenfoque y color.
.card {
/* despl. X 0, Y 2px, desenfoque 10px, tinta de marca al 8% de opacidad */
box-shadow: 0 2px 10px rgba(28, 27, 34, 0.08);
}La clave está en la sutileza. Una sombra que funciona usa poca opacidad
(ese 0.08), un desplazamiento vertical corto y la tinta de marca en vez de negro
puro: parece que la tarjeta flota un poco. Una sombra grande, opaca y negra parece
un marco oscuro pegado al elemento; es el error más típico. Si dudas, quédate corto.
box-shadow actúa sobre la caja. Para el texto existe text-shadow, que funciona igual
pero se aplica directamente a las letras:
h1 {
/* sombra suave debajo de las letras, para que el título se despegue del fondo */
text-shadow: 0 1px 4px rgba(28, 27, 34, 0.2);
}Los mismos cuatro valores que una box-shadow básica —desplazamiento horizontal,
vertical, desenfoque y color—, solo que aquí no existe el quinto valor opcional de
box-shadow, el spread, que engorda o adelgaza la sombra. Úsalo con mucha
moderación: en títulos grandes sobre fondos con imagen puede dar legibilidad; en texto
de cuerpo, casi siempre estorba.
Degradados y fondos: linear-gradient#
Un degradado es una transición suave entre colores que genera el navegador: no
es una imagen, no pesa nada y escala sin pixelarse. Se usa como valor de
background:
.avatar {
/* degradado a 135°, de un rojo de marca a otro más oscuro */
background: linear-gradient(135deg, #b8336a, #7d2247);
}El primer valor (135deg) es la dirección. Después, dos o más colores. Para que
quede bien, casi siempre son tonos de la misma familia (aquí, dos rojos de
marca), no colores opuestos que chillan. Con background también puedes poner una
imagen de fondo y controlar cómo se ajusta con background-size: cover:
.hero {
/* imagen centrada, recorta lo que sobra para cubrir el contenedor */
background: url(foto-equipo.jpg) center / cover no-repeat;
}Esa línea es una forma abreviada que junta varias propiedades en una: antes de la
barra / va la posición (center, la imagen centrada) y después el tamaño (cover);
no-repeat evita que se repita en mosaico. cover dice al navegador “escala la imagen
hasta que cubra toda la caja, recortando lo que sobra”. Es el valor que más se usa en
cabeceras y fondos: la imagen nunca deja bordes en blanco, aunque la caja tenga
proporciones distintas a la foto. Para empezar, un degradado
discreto rinde igual de bien y pesa cero; pero cuando quieras fondo con foto, ya sabes cómo.
Transiciones: que el cambio se deslice#
Hasta ahora, un :hover cambia las cosas de golpe. Una transition hace que
el cambio entre dos estados se deslice durante un tiempo:
.card {
/* anima estos cambios en lugar de saltar de golpe (va en el estado normal) */
transition:
/* anima el transform durante 0.2s con curva suave */
transform 0.2s ease,
/* anima la sombra durante 0.2s */
box-shadow 0.2s ease;
}
.card:hover {
/* se eleva 4px */
transform: translateY(-4px);
/* sombra más amplia: parece más despegada */
box-shadow: 0 10px 24px rgba(28, 27, 34, 0.12);
}La transition va en el estado normal (no en el :hover) y nombra qué
propiedades animar y en cuánto tiempo. Aquí, al pasar el ratón, la carta sube unos
píxeles (transform: translateY) y la sombra crece, todo en 0.2 segundos. Tiempos
de 0.15s a 0.3s se sienten naturales; más, y la interfaz parece lenta.
Respeta a quien prefiere menos movimiento#
El movimiento no le sienta bien a todo el mundo: hay personas a quienes marea o distrae, y por eso el sistema operativo permite pedir “menos movimiento”. Detéctalo y quita el desplazamiento:
/* se aplica solo si el usuario pidió "menos movimiento" */
@media (prefers-reduced-motion: reduce) {
.card:hover {
/* anula el desplazamiento del hover para esas personas */
transform: none;
}
}Es una línea, y convierte un detalle bonito en un detalle bonito y accesible.
Fuentes web: personalidad para el texto#
Hasta ahora usamos system-ui: la fuente del sistema del usuario. Es rápida y
segura, pero genérica. Una fuente web —una tipografía propia que cargas desde
fuera— es de lo que más cambia el carácter de una página.
Hay que hacer dos cosas: cargarla y usarla. Para cargarla, lo más rápido es
un <link> en el <head> (por ejemplo, desde Google Fonts):
<head>
<!-- preconnect: abre antes la conexión con el servidor de fuentes, para que carguen más rápido -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<!-- este link trae la hoja de la fuente Inter (pesos 400 y 700) desde Google Fonts -->
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap"
rel="stylesheet"
/>
</head>Y luego se usa en font-family, siempre con una fuente de respaldo por si la
web tarda en cargar o falla:
body {
/* usa Inter; si no carga, cae a la fuente del sistema y luego a sans-serif */
font-family: "Inter", system-ui, sans-serif;
}En un proyecto real con build (lo verás más adelante) se suele usar el paquete fontsource, que sirve la fuente desde tu propio sitio en vez de depender de un tercero: más privado y sin una petición externa que bloquee el pintado. Pero la idea es la misma: cargar, y luego declarar con respaldo.
Pruébalo#
Pasa el ratón por la carta. En styles.css, sube y baja la opacidad de la sombra,
cambia el segundo color del degradado y prueba a poner la transition en 0.6s
para notar lo lento que se vuelve. El acabado bueno casi no se nota; el malo, sí.
Comprueba lo que sabes#
Pregunta 1 de 5
¿Qué distingue una sombra que da sensación de profundidad de una que parece un borde negro?
Tu turno#
La carta está plana. Dale acabado con los tres TODO: sombra, degradado y un hover suave, con mesura. Cuando lo tengas, despliega las soluciones y fíjate en lo discreto que es el nivel “mejor” frente al “ok”.
Ejercicio · en esta página
Dale acabado visual a la carta
La carta está bien maquetada pero plana. Con los tres TODO de starter/styles.css dale acabado: una sombra suave que la eleve, un degradado en el retrato y un hover que se deslice. Recuerda la regla del remate: con mesura, más no es mejor.
Paso 1: Que tenga acabado
- La carta tiene una sombra que la despega del fondo.
- El retrato usa un degradado en vez de un color liso.
- Al pasar el ratón, la carta reacciona.
Paso 2: Con criterio
- Sombra suave (poca opacidad, desplazamiento corto), no un marco oscuro.
- Degradado entre dos tonos de la misma paleta de marca.
- `transition` para que el hover se deslice, no salte.
Paso 3: Accesible y a prueba de móvil
- El efecto responde también al foco de teclado (`:focus-within`).
- Respeta `prefers-reduced-motion`: sin desplazamiento para quien lo pide.
- Aguanta a 375px sin romper.
Ver soluciones
/* SOLUCIÓN OK — tiene acabado, pero con la mano demasiado pesada.
Hay sombra, degradado y hover, pero la sombra es dura y oscura, el degradado
acaba en negro y el hover salta de golpe porque falta la transición. */
body {
margin: 0;
font-family:
system-ui,
-apple-system,
"Segoe UI",
Roboto,
sans-serif;
background: #f1eff7;
color: #1c1b22;
line-height: 1.5;
display: grid;
place-items: center;
min-height: 100vh;
padding: 2rem;
}
.hero-card {
width: 16rem;
max-width: 100%;
background: #fff;
border: 1px solid #e6e3ee;
border-radius: 14px;
padding: 1.5rem;
text-align: center;
/* Sombra dura y muy oscura: parece un borde negro, no profundidad. Y sin
transition, así que el hover de abajo cambia de golpe. */
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
}
.hero-card:hover {
/* Salto grande y brusco: sin transition, aparece de golpe. */
transform: translateY(-8px);
box-shadow: 0 18px 44px rgba(0, 0, 0, 0.5);
}
.hero-portrait {
width: 4rem;
height: 4rem;
border-radius: 50%;
/* Degradado a negro puro: chillón y rompe la armonía de marca. */
background: linear-gradient(#b8336a, #000);
color: #fff;
font-weight: 700;
font-size: 1.1rem;
display: grid;
place-items: center;
margin: 0 auto 0.85rem;
}
.hero-name {
font-size: 1.2rem;
margin: 0;
}
.hero-role {
font-size: 0.78rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: #5b5966;
margin: 0.2rem 0 1.1rem;
}
.btn {
display: inline-block;
background: #b8336a;
color: #fff;
text-decoration: none;
font-size: 0.85rem;
font-weight: 600;
padding: 0.55rem 1.1rem;
border-radius: 8px;
} Por qué este nivel
- Tiene los tres elementos, pero con la mano pesada: la sombra es dura y muy oscura, parece un borde negro pegado, no profundidad.
- El degradado acaba en negro puro: chillón y fuera de la paleta de marca.
- El hover salta de golpe: falta la `transition` que suaviza el movimiento.
/* SOLUCIÓN MEJOR — acabado con criterio.
Sombra suave (la profundidad se sugiere, no se grita), degradado dentro de la
paleta de marca y un hover que se desliza gracias a la transición. */
body {
margin: 0;
font-family:
system-ui,
-apple-system,
"Segoe UI",
Roboto,
sans-serif;
background: #f1eff7;
color: #1c1b22;
line-height: 1.5;
display: grid;
place-items: center;
min-height: 100vh;
padding: 2rem;
}
.hero-card {
width: 16rem;
max-width: 100%;
background: #fff;
border: 1px solid #e6e3ee;
border-radius: 14px;
padding: 1.5rem;
text-align: center;
/* Sombra baja y poco opaca, con la tinta de marca en vez de negro puro:
parece que la carta flota un poco, sin marco duro. */
box-shadow: 0 2px 10px rgba(28, 27, 34, 0.08);
/* Suaviza los cambios del hover (transform y sombra) en 0.2s. */
transition:
transform 0.2s ease,
box-shadow 0.2s ease;
}
.hero-card:hover {
/* Se eleva un poco y la sombra crece: gracias a la transition, se desliza. */
transform: translateY(-4px);
box-shadow: 0 10px 24px rgba(28, 27, 34, 0.12);
}
.hero-portrait {
width: 4rem;
height: 4rem;
border-radius: 50%;
/* Degradado en diagonal entre dos tonos del mismo acento: da volumen sin
salirse de la paleta. */
background: linear-gradient(135deg, #b8336a, #7d2247);
color: #fff;
font-weight: 700;
font-size: 1.1rem;
display: grid;
place-items: center;
margin: 0 auto 0.85rem;
}
.hero-name {
font-size: 1.2rem;
margin: 0;
}
.hero-role {
font-size: 0.78rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: #5b5966;
margin: 0.2rem 0 1.1rem;
}
.btn {
display: inline-block;
background: #b8336a;
color: #fff;
text-decoration: none;
font-size: 0.85rem;
font-weight: 600;
padding: 0.55rem 1.1rem;
border-radius: 8px;
transition: background 0.2s ease;
}
.btn:hover {
background: #9c2a59;
} Por qué es mejor que el anterior
- Sombra baja y poco opaca, con la tinta de marca en vez de negro: la carta flota un poco, sin marco duro. El acabado se sugiere, no se grita.
- Degradado entre dos tonos del mismo acento: da volumen sin salirse de la paleta.
- La `transition` hace que el hover se deslice; el botón también reacciona suave a su propio hover.
/* SOLUCIÓN EXCELENTE — el mismo acabado de "mejor", pero accesible y con
respeto por quien navega distinto.
- El efecto de elevación también responde al FOCO de teclado (:focus-within),
no solo al ratón: quien usa Tab también lo ve.
- Respeta prefers-reduced-motion: quien ha pedido menos movimiento en su
sistema no recibe el desplazamiento. El acabado es un extra, nunca un
estorbo de accesibilidad.
- max-width: 100% y un degradado dentro de la paleta: aguanta a 375px sin
romper. */
body {
margin: 0;
font-family:
system-ui,
-apple-system,
"Segoe UI",
Roboto,
sans-serif;
background: #f1eff7;
color: #1c1b22;
line-height: 1.5;
display: grid;
place-items: center;
min-height: 100vh;
padding: 2rem;
}
.hero-card {
width: 16rem;
max-width: 100%;
background: #fff;
border: 1px solid #e6e3ee;
border-radius: 14px;
padding: 1.5rem;
text-align: center;
box-shadow: 0 2px 10px rgba(28, 27, 34, 0.08);
transition:
transform 0.2s ease,
box-shadow 0.2s ease;
}
/* Ratón Y teclado: el foco dentro de la carta (el botón) la eleva igual. */
.hero-card:hover,
.hero-card:focus-within {
transform: translateY(-4px);
box-shadow: 0 10px 24px rgba(28, 27, 34, 0.12);
}
.hero-portrait {
width: 4rem;
height: 4rem;
border-radius: 50%;
background: linear-gradient(135deg, #b8336a, #7d2247);
color: #fff;
font-weight: 700;
font-size: 1.1rem;
display: grid;
place-items: center;
margin: 0 auto 0.85rem;
}
.hero-name {
font-size: 1.2rem;
margin: 0;
}
.hero-role {
font-size: 0.78rem;
text-transform: uppercase;
letter-spacing: 0.06em;
color: #5b5966;
margin: 0.2rem 0 1.1rem;
}
.btn {
display: inline-block;
background: #b8336a;
color: #fff;
text-decoration: none;
font-size: 0.85rem;
font-weight: 600;
padding: 0.55rem 1.1rem;
border-radius: 8px;
transition: background 0.2s ease;
}
.btn:hover {
background: #9c2a59;
}
/* Quien ha pedido menos movimiento en su sistema no recibe el desplazamiento:
se queda el cambio de sombra, sin el "salto". */
@media (prefers-reduced-motion: reduce) {
.hero-card {
transition: box-shadow 0.2s ease;
}
.hero-card:hover,
.hero-card:focus-within {
transform: none;
}
} Por qué es mejor que el anterior
- El efecto responde al foco de teclado (`:focus-within`), no solo al ratón: quien navega con Tab también lo ve.
- Respeta `prefers-reduced-motion`: quien pidió menos movimiento no recibe el salto. El acabado nunca debe estorbar la accesibilidad.
- Aguanta a 375px. Un remate bonito que se rompe en móvil o que marea a alguien no es excelente.
Con esto cierras la caja de herramientas de Nivel 1. Ya tienes todo lo necesario —y un poco del remate— para lo que viene: el proyecto de cierre, donde montas la home del Team Builder entera, tú solo, juntándolo todo.