Controla el tamaño de la fuente con rem y olvida los px y pt. CSS3

Controla el tamaño de la fuente con rem y olvida los px y pt. CSS3

Uno de los quebraderos de cabeza a la hora de maquetar bien una página, es decidir qué medida se va a utilizar para la definición del tamaño de la fuente. En CSS3 tenemos las diferentes medidas ya existentes en CSS 2.1.

Este tipo de medidas se dividen comúnmente en escalables o fijas. Dentro de las escalables tenemos el % y el em, siendo las fijas el px y los pt.

Tamaños fijos de fuente

Los píxeles como tamaño para nuestra fuente

De forma tradicional se ha utilizado el píxel como la unidad de medida para el tamaño de las fuentes. De hecho, los navegadores web suelen tener como valor por defecto para la fuente de un documento, 16px.

Sin embargo, el uso de los píxeles como tamaño para nuestra fuente tiene un par de problemillas:

  1. No todos los navegadores lo pintan igual. Puede parecer extraño, pero este punto es fruto de la experiencia personal. Aunque la diferencia no es extremadamente grande, un texto en 14px (por poner un ejemplo) no tiene el mismo tamaño según el navegador que utilices. Esto conlleva que cuando el montaje requiere precisión, puedes encontrarte con sorpresas desagradables.
  2. No es un valor escalable. Cada día es más importante la accesibilidad web y la correcta visualización en diferentes dispositivos con resoluciones radicalmente diferentes. Como el píxel no es un valor escalable, si quieres que al ver tu web desde el móvil los tamaños de la fuente sean diferentes a cuando lo haces desde el PC, tendrás que tener el respectivo media query dónde sobreescribas todas las reglas dónde esté un font-size, un margin o un padding… porque recuerda que no sólo querrás cambiar la fuente, si no también los espacios exteriores e interiores que separan el contenido de tu web.

Los puntos como tamaño de nuestra fuente

Junto con el píxel tenemos el punto. El punto es un valor heredado de la imprenta y muy utilizado en programas de diseño como Photoshop. Al ser algo ajeno a la web, su uso no gusta mucho, aunque tiene un pro frente al píxel: Todos los navegadores te lo van a pintar igual sí o sí.

Sin embargo, no está libre de problemas:

  1. No es un valor escalable. Exactamente igual que en el caso del píxel.
  2. O el diseñador se vuelve loco o te vuelves tú. Hablando de web, lo normal es que el diseñador utilice Photoshop. Bueno, él hará el diseño y te dará las instrucciones de montaje… incluyendo el tamaño de fuente en puntos. La realidad es que si te dice que en Photoshop ese texto tiene 12pt de tamaño, tú no puedes poner 12pt en tu CSS porque se verá enorme. O sea, para Photoshop 1pt tiene una medida diferente que para los navegadores. Esto significa que acabas haciendo aproximaciones comparando tu resultado con el boceto… una locura. Por norma, si hablamos de valores pequeños (menos de 15pt), en el navegador son 2pt menos. Así pues, si el diseñador te dice 12pt, tú pones 10pt… aunque salta a la vista los problemas asociados.

Tamaños escalables de fuente

El em como tamaño para nuestra fuente

Como bien nos dice la wikipedia el EM es una unidad derivada de la anchura de la letra M… y 1em equivale a 16 puntos. Bueno, en CSS no es exactamente así, ya que 1em, a nivel de documento, equivale al tamaño de la fuente del documento (que puede ser 16… o 20, 12, 10, etc)

Lo bueno de utilizar em como medida es que se trata de un valor escalable ya que es una unidad relativa… ¿relativa a qué? Pues a su elemento padre… o en su defecto a su “ancestro” más próximo que tenga un tamaño declarado.

¿Qué significa esto?

Pongamos este CSS:

            html {
                font-size: 10pt;
            }
            
            div {
                font-size: 1.5em;
            }
            
            strong {
                font-size: 2em;
            }

Y este HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>Ejemplo EM</title>
        <meta charset="UTF-8" />
        <style>
            html {
                font-size: 10pt;
            }
            
            div {
                font-size: 1.5em;
            }
            
            strong {
                font-size: 2em;
            }
        </style>
    </head>
    <body>
        <div>
            Ejemplo de uso del tamaño de fuente en <strong>em</strong>
        </div>
        <strong>Negrita fuera de div</strong>
    </body>
</html>

Bueno, el tamaño de fuente para todo el documento (html) es de 10pt. Vemos que para el div tenemos puesto un font-size de 1.5em y de 2em para el strong.

Analizando el HTML, tenemos un div colocado dentro del body y dos strong, uno dentro del div y otro al mismo nivel que el div. ¿cual es el tamaño de fuente para cada caso?

En el div, vemos que tu elemento padre es el body, que no tiene ningún font-size… bueno, el body hereda el font-size de su etiqueta padre: html. Por lo tanto, el div que tenemos utilizará el font-size de la etiqueta HTML para el cálculo. Como el font-size del div es de 1.5em y el font-size heredado que tiene su etiqueta padre (body) es de 10pt:

1.5em * 10pt = 15pt

Los 1.5em de nuestro div se corresponden con 15pt.

En el caso del strong que está al mismo nivel que el div, ocurre lo mismo… el font-size heredado de su etiqueta padre es 10pt y el font-size del strong es 2em, así pues:

2em * 10pt = 20pt

El font-size para el div es 15pt y para el strong que está a su mismo nivel es 20pt. Bien, pero… ¿qué pasa con el strong que tenemos dentro del div? Y aquí viene “el problema”.

Sabemos que el font-size de strong es 2em, por lo que para calcular cuando va a medir de verdad en nuestro navegador, tenemos que multiplicar ese valor, por el tamaño de su elemento padre, ya sea tamaño declarado o heredado. Como el strong está dentro del div, su elemento padre es el div… y el font-size del div es 1.5em. Acabamos de calcular que ese 1.5em se corresponde con 15pt, así que para el strong que está dentro del div tenemos:

2em * 15pt = 30pt

Y así sucesivamente… ¿no ves el problema? Sencillo. Estamos hablando de una unidad acumulativa, su valor real dependerá del valor real de su elemento padre. Esto no es un problema especialmente grave para documentos HTML pequeños, pero cuando estamos hablando de documentos HTML grandes y con una profundidad en el anidamiento de etiquetas importante, se hace muy complicado no perder el control sobre los tamaños de los textos y podemos encontrarnos con resultados desagradables.

Resultado del ejemplo en el navegador

Resultado del ejemplo en el navegador

El porcentaje como tamaño para nuestra fuente

El funcionamiento es exactamente le mismo que para el em, así que… mismos problemas.

Va siendo hora de tomar el control, ¡rem al rescate!

No es más que una “evolución” del em… rem significa root-em y esto quiere decir que el funcionamiento es el mismo que el em, pero tomando como base únicamente el tamaño de la etiqueta raíz, del HTML. En el caso del rem, el tamaño de los elementos padre no importa, sólo importa el tamaño de la etiqueta raíz.

Usando el mismo ejemplo que para el em, pero cambiando en el CSS los em por rem:

<!DOCTYPE html>
<html>
    <head>
        <title>Ejemplo EM</title>
        <meta charset="UTF-8" />
        <style>
            html {
                font-size: 10pt;
            }
            
            div {
                font-size: 1.5rem;
            }
            
            strong {
                font-size: 2rem;
            }
        </style>
    </head>
    <body>
        <div>
            Ejemplo de uso del tamaño de fuente en <strong>em</strong>
        </div>
        <strong>Negrita fuera de div</strong>
    </body>
</html>

Tenemos que para el div, su valor real será de 15pt (10pt * 1.5) y para los dos strong será de 20pt (10pt * 2), no tendremos un tamaño para el strong que está dentro del div y otro para el de fuera porque para ambos casos, la unidad de referencia es el tamaño de la fuente en la etiqueta HTML.

¿Qué conseguimos con esto? Pues que por fin tenemos una unidad de tamaño escalable y fácilmente controlable.

Con rem, los dos strong tienen el mismo tamaño!

Con rem, los dos strong tienen el mismo tamaño!

Aunque en los ejemplos sólo vimos tamaños de fuentes, los margin y padding también permiten utilizar el rem como valor, y su referencia será el font-size (sí, sí, el font-size) de la etiqueta HTML, así que si complicamos un poco más nuestro CSS:

<!DOCTYPE html>
<html>
    <head>
        <title>Ejemplo EM</title>
        <meta charset="UTF-8" />
        <style>
            html {
                font-size: 10pt;
            }
            
            div {
                border: 1px solid #000;
                font-size: 1.5rem;
                margin: 5rem;
                padding: 10rem;
                width: 400px;
            }
            
            strong {
                font-size: 2rem;
            }
        </style>
    </head>
    <body>
        <div>
            Ejemplo de uso del tamaño de fuente en <strong>em</strong>
        </div>
        <strong>Negrita fuera de div</strong>
    </body>
</html>

Vemos que hemos metido un borde negro de 1px en el DIV y que le hemos puesto un margin de 5rem y un padding de 10rem. Así que a la hora de pintarlo en nuestro navegador, hablaremos de:

margin: 5*10 = 50pt

padding: 10*10 = 100pt

Usando rem también para margin y padding

Usando rem también para margin y padding

Cambiando los tamaños en función del dispositivo

Otra de las ventajas de usar rem como unidad de tamaño es que nos bastará con modificar el font-size de nuestra etiqueta HTML para que los tamaños de todo nuestro documento cambien en proporción. Esto nos permitirá establecer las media queries en nuestro CSS y utilizar sólo una regla para cambiar el font-size del HTML… la sencillez de este paso contrasta con la complejidad de la misma acción usando puntos o píxeles, que nos exigía tener que cambiar todas las reglas dónde se definan font-size, margin o padding. Con rem no tienes ese problema, sólo una regla y todo cambiado.

Ejemplo de cambio de tamaño con rem y javascript

Al igual que con las media queries, puedes cambiar el tamaño de la fuente con Javascript. Hace un tiempo estuvo bastante de moda los botoncitos que aumentaban/reducían los tamaños, utilizando los rem esto es mucho más sencillo:

<!DOCTYPE html>
<html>
    <head>
        <title>Ejemplo REM</title>
        <meta charset="UTF-8" />
        <style>
            html {
                font-size: 10pt;
            }
            
            div {
                border: 1px solid #000;
                font-size: 1.5rem;
                margin: 5rem;
                padding: 10rem;
                width: 400px;
            }
            
            ol li {
                cursor: pointer;
                border-right: 1px solid black;
                display: inline-block;
                font-size: 1.2rem;
                padding: 0.5rem;
            }
            
            ol li:last-child {
                border-right: 0;
            }
            
            strong {
                font-size: 2rem;
            }
        </style>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
        <script>
            $( document ).ready(function() {
                $("ol li").click(function() {
                   $("html").css('font-size', $(this).attr('id') + 'pt'); 
                });
            });
        </script>
    </head>
    <body>
        <ol>
            <li id="8">Fuente peque&ntilde;a</li>
            <li id="10">Fuente normal</li>
            <li id="15">Fuente grande</li>
        </ol>
        <div>
            Ejemplo de uso del tamaño de fuente en <strong>em</strong>
        </div>
        <strong>Negrita fuera de div</strong>
    </body>
</html>

Ver ejemplo online.

Problema: No todos los navegadores soportan rem

Pues sí… como no podría ser de otra forma, el uso de rem no está soportado por todos los navegadores. Bueno, todos los navegadores modernos sí lo soportan, pero las versiones viejas no… y claro, cierto es que tu puedes tener en tu windows XP un Opera actualizado, un Chrome actualizado, un firefox actualizado… ¿y un Internet Explorer? Ah no, eso no…

Por lo tanto, mal que nos pese, como hay mucho ordenador funcionando con XP tenemos que buscar un apaño. ¿Y cual es? Pues sí… volver a los viejos modos.

En una regla de CSS tu puedes definir dos veces el mismo valor, siendo esto válido:

div {
  margin: 50pt;
  margin: 5rem;
}

El navegador a la hora de interpretar el CSS, leerá las dos líneas y utilizará la última. Esto es importante, como lee por orden, hace caso a lo último… vamos un LIFO de toda la vida (Last In First Out).

Así que cambiamos nuestro CSS quedando nuestro ejemplo así:

<!DOCTYPE html>
<html>
    <head>
        <title>Ejemplo EM</title>
        <meta charset="UTF-8" />
        <style>
            html {
                font-size: 10pt;
            }
            
            div {
                border: 1px solid #000;
                font-size: 15pt;
                font-size: 1.5rem;
                margin: 50pt;
                margin: 5rem;
                padding: 100pt;
                padding: 10rem;
                width: 400px;
            }
            
            strong {
                font-size: 20pt;
                font-size: 2rem;
            }
        </style>
    </head>
    <body>
        <div>
            Ejemplo de uso del tamaño de fuente en <strong>em</strong>
        </div>
        <strong>Negrita fuera de div</strong>
    </body>
</html>

Y así, si un navegador no es capaz de interpretar los valores en rem, utilizará la línea en px… cierto es que se trata de un apaño y de que perdemos la escalabilidad en navegadores obsoletos… pero ahí no importa tanto, porque los navegadores que no soportan rem son navegadores de escritorio, por lo que ser verá a máxima resolución. Los navegadores de los móviles y tabletas soportan rem como unidad, así que… dónde importa sí utilizará el valor que queremos y dónde no… bueno cada día menos gente utiliza navegadores obsoletos, el problema desaparecerá solo 😉

OJO: Primero declaramos los tamaños en px/pt y luego en rem, porque si lo hacemos al revés:

            html {
                font-size: 10pt;
            }
            
            div {
                border: 1px solid #000;
                font-size: 1.5rem;
                font-size: 15pt;
                margin: 5rem;
                margin: 50pt;
                padding: 10rem;
                padding: 100pt;
                width: 400px;
            }
            
            strong {
                font-size: 2rem;
                font-size: 20pt;
            }

Nunca se usaría el valor en rem!

Pero tenemos más tamaños en CSS3

Pues sí…en CSS3 existen más tamaños que no he utilizado en este artículo:

  • Relativos: ex, ch, vw, vh, vmin, vmax
  • Absolutos: cm, mm, in, pc

Especialmente interesantes son los vw, vh, vmin y vmax, pero esto ya va más allá de lo pretendido en este artículo… Además, en este mundo donde se quiere la mayor precisión y que todo se vea “perfecto” creo que lo mejor es encontrar un patrón que te sirva para tal fin y seguirlo, hasta que encuentres otra forma de hacer las cosas que justifique modificar tu patrón. Pero mientras tanto yo no lo modificaría… eso sí, no confundir no modificar con no conocer y no probar 😉

16 pensamientos en “Controla el tamaño de la fuente con rem y olvida los px y pt. CSS3

  1. Felicitaciones de verdad me quedo muy muy claro estas medidas especialmente rem que era en la que tenia mas dudas sigue sacando mas articulos como estos y no te olvides tambien de sacar articulos de html5 que es en el q estoy en estos momentos estudiando y practicando 🙂

  2. Es la primera vez que veo utilizar la unidad de medida “puntos” (pt) en css. ¿Lo has hecho por algo en concreto o te has equivocado al escribirlo?

    1. Está hecho a propósito, por motivos de experiencia propios… en alguna ocasión extraña me ha ocurrido que los 12px en Chrome no ocupan lo mismo que en Firefox, que tampoco ocupan lo mismo que ne IE… algo que no me pasó nunca utilizando los pt

  3. A estas alturas, a la hora de desarrollar, ya no considero a IE8 ( desde que Microsoft anunció que lo abandonó ). Simplemente uso el hack para los usuarios que entren con ese navegador ; elimino todo el body, y en el HTML pongo un mensaje diciendo que el navegador es obsoleto y que para visualizar la web correctamente se debe actualizar o cambiar a otro.

    1. Buenas. Sí, hace relativamente poco tuvimos la buena noticia del adiós al soporte para IE 7, 8 y 9… momento en el que otro mundo se nos abrió. De todas maneras, optar por la solución drástica de “expulsar” a los usuarios de esas versiones de navegador, aunque recomendable, dependerá mucho de tu target, puede que, simplemente, no te lo puedas permitir 😉

  4. sdesergiSergi
    Responder

    Buenas. Hay un asunto de los px que no comprendo. ¿Por qué se dice que no son escalables? Cuando yo hago zoom in o zoom out todos los elementos dimensionados con px aumentan y disminuyen guardando las proporciones entre ellos, incluídos los textos.

    1. Cuando haces zoom en el navegador no estás aumentando el tamaño de la fuente, estás poniendo una lupa sobre el contenido. Si tu pones que un tamaño de fuente sea 10px, siempre será de 10px independientemente del dipositivo, resolución etc. Entonces, si tu tienes la web abierta y cambias de 1024 a 1920 la resolución del monitor, la fuente pasará de verde relativamente bien a super-enana y tendrás que hacer zoom para verlo correctamente.

      Si fuera un tamaño %, por ejemplo 62.5%, como un documento HTML por defecto se ve con 16px de tamaño de fuente, realmente se verá a 10px. Pensarás que estamos en el mismo caso no? Cambio resolución y tendré que hacer zoom… sí claro, era una forma chorra de explicar el “no escalable”, vamos algo más serios 😉

      Bueno, tengo por un lado mi HTML con font-size a 10px y tengo por otro el de font-size a 62.5% (16px * 0.625 = 10px), tú los verás igual. Bueno, pongamos que yo tengo problemas de visión y los tamaños de fuente pequeños me cuesta leerlos, así que configuro mi navegador para que el tamaño por defecto de la fuente (el valor por omisión) sea de 160px en lugar de 16… la versión de la web en píxeles me mostrará el texto a 10px en lugar de 160px (mi valor por omisión), por lo que no me enteraré de nada y tendré que hacer zoom. Por el contrario, la versión de 62.5%, no me mostrará el texto a 10px, lo hará a 100px, un tamaño de fuente mucho más grande que 10, por lo que lo veré bastante bien.

      Pensamos ahora en diferentes dispositivos… mi pantallote 4K con una resolución del copón va a hacer que los 12px sea un tamaño de fuente ridículo. Si quieres que tu web se vea bien en ese tipo de pantallas (cada vez más en el mercado), tendrás que poner una media query específica para que cuando la pantalla tenga más de, por ejemplo, 2000px la fuente en lugar de 10px sea 20px… y eso aplicarlo a toooooooooooooooooodos los font-size de tu hoja de estilos, por eso no es escalable, no se adapta. Si por el contrario las fuentes estuviesen en REM, sólo tendrías que cambiar el tamaño de fuente del documento base y todos los tamaños de tu hoja de estilos aumentarían o disminuirían proporcionalmente (escalable).

      Ya desde el punto de vista gráfico, todos conocemos la frase “la imagen sale pixelada” porque no está en un formato escalable (como las imágenes vectoriales, los svg por ejemplo) por lo que si quieres meter en 200px de ancho una imagen de 2px… dientes dientes dientes.

      Espero que te sea de utilidad 😉

Deja un comentario