Unidades de medida en CSS

Las unidades de medida en CSS es de los temas que más suelen preguntarme, sobretodo ¿Qué unidad uso para tamaños de fuentes? y la respuesta como a casi todo es: depende.

Para empezar es importante saber que CSS hay varios tipos de salida:

  • Braille
  • Embossed
  • Handheld
  • Print
  • Projection
  • Screen
  • Speech
  • TTY
  • TV

Aunque podemos usar cualquier unidad de medida independientemente de la salida, obviamente unas son más aptas para un tipo que otras:

Recomendadas para Impresión:

em, cm, mm, in, pt, pc, %

Recomendadas para Pantalla:

em, px, %, rem, vw, vh

Ahora, a lo que nos interesa: ¿Qué unidades utilizar y cuándo?

Primero que nada, vamos a simplificar un poco: Limitémonos al uso de unidades en pantallas y dejemos las salida para impresión para otra ocasión.

Muy bien, ¿qué tenemos entonces? tenemos px, em, rem y %

Pixel

Vamos a echarle un ojo a las unidades absolutas, pero tenemos que ser conscientes que una unidad absoluta es una unidad que no depende de nada más que de sí misma, su valor es el que indiquemos.

La unidad absoluta más molona que hay en CSS es px (Píxel), pero con la web abrazando cada vez más una adaptabilidad a los diferentes viewports una unidad de medida absoluta va perdiendo protagonismo. No podemos establecer un ancho absoluto e ir ajustándolo con mediaqueries, sería una locura en miles de breakpoints.

¿Entonces cuándo usamos píxels?

Obviamente para tamaños absolutos. padding y margin son mis constantes en pixels: Declaro una variable en Scss con estos valores y los mantengo como constantes para mantener consistencia en el diseño, puede que a veces necesite varias variables para ajustarlas en resoluciones pequeñas o grandes, pero nada que una función en Scss no arregle:


// Declaramos todas las variables absolutas en un mapa para usarlas luego en una función:
$gutter           : 12px;
$space : (
   pad           : $gutter,
   pad-mobile    : $gutter / 2,
   gutter        : $gutter * 2,
   gutter-mobile : $gutter
);

// Creamos una función para usar las diferentes medidas:

@function gutter($size) {
  @return map-get($space, $size);
}

// Y para usarla:

.article {
  margin: gutter(gutter-mobile);
  padding: gutter(pad-mobile);
}

@media all and (min-width: 30em) {
   .article {
     margin: gutter(gutter);
     padding: gutter(pad); 
   }
}

No nos limitemos a este uso, en muchas ocasiones alguna propiedad requerirá su valor en pixels, usad vuestro criterio.

Lectura recomendada sobre px

em

Son la unidad relativa por excelencia, y a veces resulta confuso entenderla. Por definición un em es igual al valor del font-size del elemento al que pertenece. Si el elemento que contiene una propiedad en em no tiene un font-size definido, lo heredará del padre, o del primer ancestro con font-size declarado – si ninguno tiene font-size declarado, tomará el del HTML: 100% -.

Si un elemento tiene un font-size declarado, todo otro valor dado en em en ese mismo elemento equivale a ese font-size:



.element {
   font-size: 20px;
   border-radius: 1em;
}

En este caso el border-radius tiene un valor de 20px. Si reducimos el font-size a 10px, pues el border radius será de 10px. La potencia del em radica en esta propiedad ¿os imagináis el poder para controlar la escalabilidad visual de nuestros componentes?

Supongamos una clase con propiedades en los pseudoselectores ::after y ::before para crear un botón con diferentes elementos, con los pseudoselectores vamos a hacer dos bloques antes y después del botón. Dichos bloques tienen unidades y medidas propias, ajenas al botón a no ser que las declaremos en em con lo que todas esas declaraciones serán relativas al tamaño de fuente del botón, aquí el CSS (en Scss) y HTML:

See the Pen EM for components by Wakkos (@Wakkos) on CodePen.

Es un buen momento para aclarar que, efectivamente, un valor de propiedad en em dentro de un pseudoselector va a ser relativo a la propiedad font-size del selector al que pertenece.

Podéis apreciar como todas las propiedades cuyo valor son definidas en em tendrán un tamaño relativo al font-size del elemento, y cambiamos el font-size en la clase .btn todas esas propiedades se reajustan, un componente proporcional en todo momento!.

Otro uso de la unidad em es, por supuesto, en texto. Pero no a TODOS los textos ¿os imagináis el arroz con mago que tendríamos si tuviéramos que calcular el tamaño de un <span> a 1.3em alojado en un <a> con un font-size de .8em dentro de un <h6> a 1.5em? Ese es un mal uso de los em, o al menos un uso poco productivo.


body { font-size: 100%; }
li { font-size: .75em; // 12px }

Para calcular el valor en em tenemos que usar la fórmula target / context. En este caso para obtener el font-size en em del <li> usamos 12px/16px = .75em

Si declaramos el font-size del <li> con un valor de .75em, cuando añadimos dentro otra lista, sus <li> tendrán un valor de .75em basado en .75em del <li> contenedor (unos 9px) y así sucesivamente.

Esto nos puede llevar a tener que establecer definiciones extras en nuestro CSS para arreglarlo:


body { font-size: 100%; }
li, li li, li li li { font-size: .75em; // 12px }

Pero ¿quién quiere eso? Este es un ejemplo donde la unidad rem es útil, más adelante hablamos de ella.

Sin embargo si podemos usar em en tamaño de fuente cuando queremos que un texto sea siempre relativo a su contenedor: un small que tenga que ser .8 veces su contenedor sin importar el tamaño del mismo.


h1 { font-size: 2.5em; }
h1 small {font-size: .5em; }

De esta manera, el small se mantiene relativo al tamaño del h1.

Lectura recomendada sobre em

rem

Rem está definida como “root em” o lo que es lo mismo: un em basado únicamente en la raíz del documento: el html. Esto quiere decir que podemos declarar un tamaño de fuente en el HTML y dejar que el resto sean relativas sólo a ella.

Normalmente quiero tamaños de fuentes diferentes según las resoluciones, en resoluciones pequeñas que indican un móvil lo tenemos cerca de la cara cuando lo manipulamos, con lo que quiero todas mis fuentes un 20% más pequeña (dependiendo del font-face usado) y luego volverlas a la normalidad cuando superan cierta resolución (Los chicos de IA.net han escrito un post muy bueno al respecto).


html { font-size: 80%; }

@media screen and (min-width: 48em) { 
   html { font-size: 100%; } 
}

h1 { font-size: 5.5rem; }
p { font-size: 1rem; }

Como vemos, rem es una unidad ideal para definir tamaños de fuentes y nos permite gestionar todos los tamaños con sólo modificar el tamaño de fuente de la raíz.

Lectura recomendada sobre rem

%

Los porcentajes es una unidad que habla por sí misma: toman un porcentaje del contenedor. Si tenemos un elemento a 100% de width va a ocupar el 100% de su contenedor, si no tiene un contenedor que limite su tamaño (width) será el 100% del viewport.

Si juntamos % con las propiedades max-width y min-width tendremos un arma muy potente para crear comportamientos variables según el tamaño del viewport, un

que se vea a no menos de 320px pero que no pase de 480px es flexibles pero con unos límites:


.article {
   width: 100%;
   max-width: 480px;
   min-width: 320px;

Si les asignamos además la propiedad display: inline-block esos divs se colocarán dos en línea en resoluciones mayor a 960px, tres en línea en resoluciones mayores a 1440px. Os dejo un ejemplo para que hagáis la frikada esa que solo hacemos los web designers de estirar y encoger la ventana del navegador (Sorry si estáis en viewports pequeños):

See the Pen NPoYJq by Wakkos (@Wakkos) on CodePen.

Simple y bonito, ¿verdad? Sin embargo, hay casos – pocos – donde solucionar los problemas de width con % (Exacto: width. Es la propiedad donde más se utiliza el %) puede llevar un par de cálculos extras. Tomemos por ejemplo, un elemento <section> a 80% y dentro tenemos un elemento <header> que queremos que ocupe el 50% del viewport total, no de su contenedor, tendríamos que calcular, como bien me indica Roberto Abizanda, con una simple regla de 3:

Y hasta ahí todo bien, pero los cálculos se podrían complicar si tenemos más anidaciones o tendremos que reajustar esa fórmula si cambia el width del header, o usar variables en Scss. y llegar a ser un caos para los menos duchos en matemáticas. Gracias al dios de la W3C nos ha llegado una unidad con la que podemos hacer este tipo de cosas.

VH / VW

Viewport Height y Viewport Width no son otra cosa que el ancho y el alto respectivamente del viewport del navegador. 1vw equivale a 1/100 del ancho total del viewport del navegador, un 1%. Al no depender de nada más que del viewport, podríamos colocar un elemento con 50vw y este va a medir el 50% del viewport, independientemente del width que tenga su contenedor – con lo que ahorramos los cálculos que tuvimos que hacer en la sección anterior para calcular el 50% del viewport con % cuando el contenedor mide algo diferente al viewport.

No nos confundamos y utilicemos vw solo para anchos y vh solo para alturas: puedes usarlos dónde y cuando quieras (incluso en tipografía), puedes tener un recuadro que sea siempre proporcional al ancho o al alto del viewport por ejemplo, o una navegación vertical de 5 items que ocupe el 100% del alto del viewport (height: 100vh) y cada item que mida 20vh de alto.

Lectura recomendada sobre VH / VW

Cada una de las unidades vistas tiene un uso común pero no limitante, nada está escrito en piedra! dadles el mejor uso que veáis y disfrutad del CSS.

Daniel Martínez

3 comentarios - ¿Quieres opinar?
  1. Entiendo que “1em” equivale al tamaño de fuente del documento, pero seria bueno declararlo desde un principio o o si no lo declaro será un caos no?

    Aclarando un poco lo anterior mi pregunta sería ¿cual es el tamaño base de fuente? segun yo varia dependiendo el navegador esto se soluciona usando normalize pero entonces tendria que estudiar los estilos de normalize para saber que font size se usa ¿o no?

    Siempre que leo de esto me confundo pues todos dicen 1 em o .8 em y escriben de que depende del tamaño de fuente pero jamas hablan si ese valor de fuente se lo tiene que declarar al principio como base y en que afecta al diseño responsivo, es decir, una fuente de 14 px puede que se vea muy bien en escritorio pero se vea grande en una pantalla de 4.5″ en fin sigo confundido….

Opiniones y preguntas:

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *