Unidades
Lección 03 de 37 · 5 min
Cada medida en CSS lleva una unidad, y la unidad dice contra qué se mide. Elegir bien es lo que hace que una página se adapte a la pantalla y a la configuración de quien la lee.
Absolutas y relativas
px es una unidad absoluta: 64px mide lo mismo en cualquier lugar de la página. No es un píxel físico de la pantalla; en pantallas de alta densidad, un píxel de CSS ocupa varios. Las unidades relativas se calculan a partir de otra medida:
emElfont-sizedel propio elemento, que si no lo cambia hereda del padre.remElfont-sizede la raíz, el elementohtml.%Enwidth, el ancho del bloque contenedor, casi siempre el padre.vwEl ancho de la ventana del navegador;1vwes el 1%.chEl ancho del carácter «0» en la fuente del elemento.cqiEl ancho del contenedor más cercano;1cqies el 1%.
Cambiá la unidad y mové los sliders: la tabla marca en naranja la medida de la que depende el ancho del campo, y la regla debajo lo divide en pasos de esa unidad.
| html · font-size | 16px |
|---|---|
| formulario · font-size | 20px |
| «0» del formulario | 12px |
| formulario · width | 240px |
| ventana · width | 1280px |
html {font-size: 100%; /* 16px si el navegador usa 16px */}.formulario {width: 240px;font-size: 20px;}.campo {width: 4em; /* 4 × 20px = 80px */}
<html class="text-[100%]"> <!-- 16px si el navegador usa 16px --><div class="w-[240px] text-[20px]"> <!-- formulario --><div class="w-[4em]"></div> <!-- campo --></div></html>
em y rem
em depende del elemento, y eso se acumula al anidar. Usado en font-size, em toma el tamaño del padre: si cada nivel pide 1.25em, cada uno multiplica al anterior.
html { font-size: 100%; } /* 16px por defecto */.tarjeta { font-size: 1.25em; } /* 16 × 1.25 = 20px */.tarjeta .titulo { font-size: 1.25em; } /* 20 × 1.25 = 25px */
El título termina en 25px: 1.5625 veces la raíz, no 1.25. Con 1.25rem los dos medirían 20px, porque rem siempre mira la raíz, sin importar dónde esté el elemento.
Por eso rem es la opción por defecto para tamaños de texto y espaciados: si quien lee subió el tamaño de letra en su navegador, todo crece en proporción. Para que funcione, no fijes el font-size de html en px. Guardá em para lo que tiene que seguir al texto del propio elemento, como el relleno de un botón.
Porcentajes y ventana
En width, un porcentaje se calcula sobre el ancho del bloque contenedor. Un campo de 50% dentro de un padre de 240px mide 120px, y si el padre se achica, el campo también.
Las unidades de ventana ignoran al padre: vw es el 1% del ancho de la ventana y vh, el 1% del alto. En celulares, 100vh puede quedar más alto que lo visible cuando aparecen las barras del navegador. dvh sigue el alto visible en cada momento:
.portada {min-height: 100dvh;}
Una guía rápida:
- rem
- tamaños de texto y espaciados
- em
- lo que acompaña al texto del elemento
- %
- anchos que dependen del contenedor
- ch
- el ancho de una línea de texto
- vw · dvh
- lo que depende de la pantalla
- px
- detalles finos, como un borde de 1px
Otras unidades
CSS tiene más unidades. Estas son las que vale la pena conocer:
chEl ancho del «0». En una fuente proporcional es aproximado, pero sirve para limitar el largo de línea:max-width: 65chdeja unas 65 letras por renglón.lh · rlhEl interlineado del elemento y el de la raíz.margin-block: 1lhsepara párrafos exactamente una línea.vmin · vmaxEl 1% del lado más corto o del más largo de la ventana, para algo que tiene que entrar parado y acostado.svh · lvh · dvhEl alto de la ventana con las barras visibles, ocultas, o el que haya en cada momento. También existensvw,lvwydvw.cqi · cqb · cqw · cqhComo las de ventana, pero relativas al contenedor más cercano que declaracontainer-type.
Las de contenedor hacen que un componente se adapte al lugar donde está y no a la pantalla:
.tarjetas {container-type: inline-size;}.tarjeta h2 {font-size: clamp(1rem, 5cqi, 2rem);}
Quedan las de nicho. ex, cap e ic miden la altura de la «x», la de las mayúsculas y el ancho de un ideograma, y cada una tiene su versión de raíz: rex, rcap, ric y también rch. Las físicas, cm, mm, Q, in, pt y pc, son para imprimir: en pantalla 1in siempre vale 96px, aunque tu monitor diga otra cosa.
Hay unidades que no son de longitud: fr reparte el espacio libre entre las columnas de una grilla; deg, rad, grad y turn miden ángulos, como en rotate(45deg) o el tono de oklch(); y s y ms miden tiempo en transiciones y animaciones. Cada una aparece en su bloque.
En Tailwind
La escala de Tailwind está en rem: cada paso de w-*, p-* o gap-* vale 0.25rem, así que w-16 es 4rem, que da 64px solo si la raíz mide 16px. Para cualquier otra unidad, escribí el valor entre corchetes y Tailwind lo copia tal cual.
| CSS | Tailwind |
|---|---|
| width: 4rem | w-16 |
| width: 64px | w-[64px] |
| width: 4em | w-[4em] |
| width: 50% | w-1/2 · w-[50%] |
| max-width: 65ch | max-w-prose · max-w-[65ch] |
| height: 100dvh | h-dvh · h-svh · min-h-dvh |
| container-type: inline-size | @container · w-[50cqi] |
<section class="min-h-dvh"><div class="@container"><article class="max-w-prose p-6"><h2 class="text-[clamp(1rem,5cqi,2rem)]">Título</h2><p class="text-base">Texto con unas 65 letras por renglón.</p></article></div></section>
Units
Lesson 03 of 37 · 5 min
Every length in CSS has a unit, and the unit says what it's measured against. Picking the right one is what lets a page adapt to the screen and to the reader's settings.
Absolute and relative
px is an absolute unit: 64px is the same size anywhere on the page. It isn't a physical screen pixel; on high-density screens, one CSS pixel covers several. Relative units are worked out from another length:
emThe element's ownfont-size, which it inherits from the parent unless it sets one.remThefont-sizeof the root, thehtmlelement.%Forwidth, the width of the containing block, almost always the parent.vwThe width of the browser window;1vwis 1% of it.chThe width of the “0” character in the element's font.cqiThe width of the nearest container;1cqiis 1% of it.
Switch the unit and move the sliders: the table marks in orange the length the field's width depends on, and the ruler under the field splits it into steps of that unit.
| html · font-size | 16px |
|---|---|
| form · font-size | 20px |
| the form's “0” | 12px |
| form · width | 240px |
| window · width | 1280px |
html {font-size: 100%; /* 16px when the browser uses 16px */}.form {width: 240px;font-size: 20px;}.field {width: 4em; /* 4 × 20px = 80px */}
<html class="text-[100%]"> <!-- 16px when the browser uses 16px --><div class="w-[240px] text-[20px]"> <!-- form --><div class="w-[4em]"></div> <!-- field --></div></html>
em and rem
em depends on the element, and that compounds when you nest. Used in font-size, em takes the parent's size: if every level asks for 1.25em, each one multiplies the last.
html { font-size: 100%; } /* 16px by default */.card { font-size: 1.25em; } /* 16 × 1.25 = 20px */.card .title { font-size: 1.25em; } /* 20 × 1.25 = 25px */
The title ends up at 25px: 1.5625 times the root, not 1.25. With 1.25rem both would be 20px, because rem always looks at the root, wherever the element sits.
That's why rem is the default choice for text sizes and spacing: if the reader turned up the font size in their browser, everything grows in proportion. For that to work, don't set the html font-size in px. Keep em for things that should follow the element's own text, like a button's padding.
Percentages and the window
For width, a percentage is worked out from the width of the containing block. A 50% field inside a 240px parent is 120px wide, and if the parent shrinks, so does the field.
Viewport units ignore the parent: vw is 1% of the window's width and vh 1% of its height. On phones, 100vh can end up taller than what you see when the browser bars show up. dvh follows the visible height at every moment:
.hero {min-height: 100dvh;}
A quick guide:
- rem
- text sizes and spacing
- em
- things that go with the element's text
- %
- widths that depend on the container
- ch
- the width of a line of text
- vw · dvh
- things that depend on the screen
- px
- fine details, like a 1px border
More units
CSS has more units. These are the ones worth knowing:
chThe width of the “0”. In a proportional font it's approximate, but it's handy to cap line length:max-width: 65chleaves about 65 letters per line.lh · rlhThe element's line height and the root's.margin-block: 1lhspaces paragraphs exactly one line apart.vmin · vmax1% of the window's shorter or longer side, for something that has to fit both upright and sideways.svh · lvh · dvhThe window's height with the bars showing, hidden, or whatever it is right now. There are width versions too:svw,lvwanddvw.cqi · cqb · cqw · cqhLike the viewport ones, but relative to the nearest container that declarescontainer-type.
Container units let a component adapt to where it sits rather than to the screen:
.cards {container-type: inline-size;}.card h2 {font-size: clamp(1rem, 5cqi, 2rem);}
Then there are the niche ones. ex, cap and ic measure the height of an “x”, the height of capitals and the width of an ideograph, and each has a root version: rex, rcap, ric, and rch too. The physical ones, cm, mm, Q, in, pt and pc, are for print: on screen 1in is always 96px, whatever your monitor says.
Some units aren't lengths: fr shares out the free space between a grid's columns; deg, rad, grad and turn measure angles, as in rotate(45deg) or the hue in oklch(); and s and ms measure time in transitions and animations. Each one shows up in its own block.
In Tailwind
Tailwind's scale is in rem: every step of w-*, p-* or gap-* is 0.25rem, so w-16 is 4rem, which is 64px only when the root is 16px. For any other unit, write the value in brackets and Tailwind copies it as is.
| CSS | Tailwind |
|---|---|
| width: 4rem | w-16 |
| width: 64px | w-[64px] |
| width: 4em | w-[4em] |
| width: 50% | w-1/2 · w-[50%] |
| max-width: 65ch | max-w-prose · max-w-[65ch] |
| height: 100dvh | h-dvh · h-svh · min-h-dvh |
| container-type: inline-size | @container · w-[50cqi] |
<section class="min-h-dvh"><div class="@container"><article class="max-w-prose p-6"><h2 class="text-[clamp(1rem,5cqi,2rem)]">Title</h2><p class="text-base">Text with about 65 letters per line.</p></article></div></section>
