wandres.dev
UNIDADES · px, em, rem, ch, lh, vi, dvh

lh y rlh: medir en alturas de línea

Qué mide exactamente la unidad lh, cómo resuelve la especificación su circularidad, y los patrones de ritmo vertical y truncado que solo salen limpios con ella.

⏱ 15 min

Antes de lh no había forma de decir en CSS “un renglón”. Se aproximaba multiplicando a mano el tamaño de fuente por la altura de línea, con el problema de que ese número dejaba de ser correcto en cuanto alguien cambiaba cualquiera de los dos, y con el problema mayor de que line-height: normal no tiene número: lo decide la fuente. lh cierra ese hueco y desbloquea una familia de patrones que antes eran aproximaciones.

🎯 Al terminar esta lección sabrás
  • Explicar contra qué se resuelve lh en cada propiedad.
  • Describir cómo evita la especificación la dependencia circular.
  • Construir un ritmo vertical con lh y rlh.
  • Escribir un truncado por número de líneas sin depender de propiedades con prefijo.

Qué mide

1lh es el valor computado de line-height del propio elemento. 1rlh es el del elemento raíz. Nada más, y esa simplicidad es lo que las hace útiles: son la altura de un renglón, expresada de forma que sigue siendo correcta cuando cambia la fuente, el tamaño o la altura de línea.

El soporte está resuelto: lh llegó con Chrome 109, Safari 16.4 y Firefox 120; rlh con Chrome 111, Safari 16.4 y Firefox 120.

La parte valiosa es el caso de line-height: normal. Ese valor no corresponde a ningún número que puedas escribir: el navegador lo calcula a partir de las métricas de la fuente —ascendente, descendente y hueco de línea— y sale distinto para cada tipografía, normalmente entre 1.1 y 1.4. Con lh puedes referenciar ese número sin conocerlo:

.parrafo {
  line-height: normal;
  margin-block-end: 1lh;   /* exactamente un renglon, sea el que sea */
}

Antes esto exigía renunciar a normal y fijar un número, con el coste de perder el ajuste que la fuente traía pensado.

La circularidad y cómo la resuelve la especificación

Hay dos propiedades donde lh se muerde la cola. Si escribes line-height: 1.2lh, el valor de la unidad depende del valor de la propiedad que estás definiendo. Lo mismo pasa con font-size, porque line-height suele depender del tamaño de fuente.

La especificación resuelve las dos igual que resolvió el caso de em en font-size: cuando lh o rlh aparecen en el valor de font-size o de line-height, se resuelven contra el valor del padre —o contra el valor inicial si no hay padre. No hay error, no hay valor inválido: hay una regla explícita que rompe el ciclo un nivel más arriba.

.cita {
  line-height: 1.5;
}
.cita blockquote {
  line-height: 1.2lh;   /* 1.2 x la altura de linea del padre, no la suya */
}

Es un detalle pequeño y conviene conocerlo porque el resultado no es intuitivo: en esa propiedad concreta, lh deja de significar “mi renglón” y pasa a significar “el renglón de mi padre”.

Ritmo vertical

El ritmo vertical es la idea de que todas las separaciones verticales de una página sean múltiplos de una misma altura de renglón, de forma que el texto de dos columnas contiguas caiga en las mismas líneas. En papel es una disciplina centenaria; en la web siempre fue frágil porque el renglón no era expresable.

Con rlh sí lo es:

:root {
  font-size: 1rem;
  line-height: 1.5;
}

h2      { margin-block: 2rlh 1rlh; }
p       { margin-block-end: 1rlh; }
figure  { margin-block: 1rlh; }
hr      { margin-block: 1rlh; border: 0; block-size: 1px; background: var(--borde); }

Todo se mueve en múltiplos del mismo renglón raíz, y si mañana cambias line-height en :root, el sistema entero se reajusta sin tocar ninguna otra línea. Con lh en lugar de rlh obtendrías separaciones proporcionales al renglón de cada elemento, lo cual es otra decisión de diseño perfectamente válida: los títulos, que tienen renglón más alto, se separarían más.

Patrones que solo salen bien con lh

Truncado a un número exacto de líneas. El recorte por altura siempre fue aproximado porque había que calcular a mano cuántos píxeles son tres renglones. Con lh es literal:

.entradilla {
  display: block;
  max-block-size: 3lh;
  overflow: hidden;
}

No añade puntos suspensivos —para eso hace falta line-clamp— pero corta exactamente donde se acaba la tercera línea, sin dejar una cuarta a medias, y sigue siendo correcto si cambia el tamaño de fuente.

Rayado del papel pautado. Un fondo de líneas que coincida con los renglones era imposible de mantener; ahora es una sola declaración:

.pautado {
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent calc(1lh - 1px),
    var(--pauta) calc(1lh - 1px),
    var(--pauta) 1lh
  );
}

Desplazamiento del ancla de scroll. Cuando una cabecera fija tapa el destino de un enlace interno, la corrección natural no es un número de píxeles inventado sino un número de renglones:

:target { scroll-margin-block-start: 2lh; }

Altura mínima estable. Un contenedor cuyo contenido puede estar vacío pero que no debe colapsar reserva exactamente una línea con min-block-size: 1lh, sin el truco del espacio de no separación.

💡
lh también depende de la fuente cargada

Como line-height: normal sale de las métricas de la fuente, 1lh cambia de valor cuando termina de cargar una fuente web con métricas distintas. Si has construido el ritmo vertical entero sobre rlh y la raíz usa una fuente web, todo el documento se recalcula en el intercambio. Con un line-height numérico en la raíz el problema desaparece, porque entonces rlh solo depende del tamaño de fuente.

Una unidad nueva no añade capacidad, añade intención

Todo lo de esta lección se podía hacer antes. margin-block-end: 1.5rem produce exactamente el mismo píxel que margin-block-end: 1rlh cuando la raíz tiene line-height: 1.5 y font-size: 1rem. La diferencia no está en el resultado de hoy, está en qué afirma cada declaración sobre el futuro: la primera dice “un espacio de 24 píxeles” y la segunda dice “un renglón”. Cuando alguien cambia la altura de línea del documento, la primera se convierte en una mentira silenciosa —sigue midiendo 24 píxeles, que ya no son un renglón— y la segunda sigue siendo verdad. Este es el patrón que se repite en cada unidad que ha añadido CSS en la última década, de ch a cqi pasando por dvh: ninguna hace nada que no se pudiera calcular a mano, y todas convierten un cálculo que había que rehacer en una relación que se mantiene sola. Por eso la pregunta al elegir unidad nunca es “cuál da el número que quiero” —dan todas— sino “cuál de estas relaciones quiero que siga siendo verdad dentro de dos años”. La hoja de estilos que sobrevive es la que ha ido eligiendo bien esa respuesta, declaración a declaración.