viernes, 23 de mayo de 2014

Responsive design con medidas relativas (em y rem ), no mas pixeles.




En la actualidad cuando hablamos de responsive design hablamos de que nuestras web app se adapten a cualquier resolución de pantalla, ya que la gran cantidad de dispositivos móviles y tamaños de pantalla es increible. Una manera de lograr esto es con “Media Queries” por medio de ellas se trata de “identificar” el comportamiento del layout de acuerdo a las resoluciones de las pantallas más usadas.

Normalmente se crean “breakpoint”, los breakpoint son los tamaños específicos donde tu diseño se rompe y es en ese momento donde tenemos que escribir  “Media Queries” para resolver el problema.

Creo que alguien definió el proceso de esta manera : “Comienza con la pantalla más pequeña, luego expándela hasta que luzca como la mi*rda. Tiempo de hacer un breakpoint!"

Hoy en dia esta manera de pensar en el diseño no es lo adecuado ya que la web no es solamente  fluída, ya no hay más “pixel perfect” y debemos dejar de pensar que “Media Queries” sirve para setear solamente los anchos de los elementos, debemos de pensar también en los márgenes y  estilos.

Como programadores frontends debemos saber qué cosas podemos controlar y que cosas no. Nuestros usuarios serán los que decidan cómo visualizar nuestro sitio de la manera en la que ellos quieran. Asi que debemos dejar de pensar en “píxel perfect” cuando diseñamos para Web, y saber que los diseños estarán en constante cambio, por lo cual debemos de optimizar el contenido.

Lo primero que tenemos que hacer es configurar correctamente el viewport, normalmente lo configuracion del viewport se hace de la siguiente manera : 

<meta name="viewport" content="width=device-width, user-scalable=no">
ó
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

El propiedad width controla el tamaño del viewport , puede tomar valores fijos como 500px  o como en ese caso el valor “device-width” el cual es el ancho de la pantalla del dispositivo en pixeles a una escala de 100%. Instruye a la pagina a que su ancho tiene que coincidir con el ancho del dispositivo.
La propiedad “user-scalable=no" deshabilita las capacidad de hacer zoom y el usuario solo podrá hacer scroll, lo cual da la sensación de que tu sitio parezca una app nativa.

La propiedad “initial-scale” controla el nivel de zoom cuando la página inicia. Algunos navegadores incluidos IOS y Windows phone,mantendrán el ancho de la pagina constante cuando sea rotado en horizontal (landscape mode) ó hagas zoom, en lugar de acomodar el contenido en pantalla. Agregando el atributo "initial-scale=1" instruye al navegador a establecer una relación 1:1 entre los pixeles CSS y los pixeles del dispositivo independientemente de su orientación y permite  tomar ventaja del todo el ancho en modo landscape.

 Pueder ver un ejemplo en este link,section "Responsive Viewport" : https://developers.google.com/speed/docs/insights/ConfigureViewport

“maximum-scale” controla el máximo de zoom permitido al usuario, por lo general siempre lo he visto en valor 1 y esto puede resultar un problema para algunas personas. Aunque los elementos de nuestra web tengan tamaños adecuados puede haber algunos que no se puedan ver correctamente.
Los textos en imágenes podrían verse demasiado pequeños en un móvil. En este caso el usuario tendrá que hacer zoom para leerlo, pero no podrá. Esto supone una frustración para el usuario, algo que tenemos de evitar para ofrecer una buena experiencia.

La manera correcta en que debemos configurar el viewport es esta :

<meta name="viewport" content="width=device-width, initial-scale=1">

Por defecto, "user-scalable" tiene el valor de yes, es decir, el zoom está activado. Si no definen "maximum-scale", el zoom máximo será el determinado por el navegador, lo que resta hacer es tratar de crear nuestras “Media Queries” de manera correcta y adaptar el contenido lo mejor posible.

Cuando en una Web no es especificado el viewport, los navegadores de dispositivos móviles mostraran la web con una resolución de 800px a 1024px, el factor de escala de la página es ajustado para mostrarse, forzando a los usuarios hacer zoom antes de que puedan interactuar con la Web.

Ahora basándonos en que nuestro contenido tiene que adaptarse perfectamente en muchas resoluciones de pantallas, lo correcto sería usar unidades de medidas CSS relativas para los tamaños de letras en lugar de pixeles, por qué necesitamos cambiar los tamaños de letras de acuerdo a los diferentes tamaños de pantalla.

El tamaño de letra que se ve bien en un dispositivo móvil, no será adecuado en una pantalla de escritorio. Con todos estos cambios de tamaños, nuestros textos se modifican constantemente, es así que al diseñar para responsive debemos controlar cómo fluctúan los mismos entre las resoluciones.


En CSS existen varias maneras de darle tamaño a los textos las más comunes son:
  • PX: píxeles
  • PT: puntos
  • EM: em es la anchura de la letra mayúscula "M" en el tipo de letra dado

CSS divide las unidades de medida en dos grupos: absolutas y relativas. Las medidas relativas definen su valor en relación con otra medida, por lo que para obtener su valor real, se debe realizar alguna operación con el valor indicado. Las unidades absolutas establecen de forma completa el valor de una medida, por lo que su valor real es directamente el valor indicado.

Las medidas absolutas en CSS son el Pixel y el Punto. Los navegadores establecen por defecto el tamaño de 16 pixeles, 16 píxeles equivalen a 12 puntos. El tamaño para textos en web debe aproximarse a los 16px ya que es el equivalente a los 12px en la impresión en papel. Las pantallas están más alejadas que el libro, además que es preferible subirle el punto a tener que adoptar una mala postura para poder leer el texto.

Las medidas relativas son el "porcentaje, em y rem", como dice la definición debemos establecer una medida base para que la medida sea calculada en base a esta.

Al  usar “Media Queries” con unidades de medida relativas  para cambiar los tamaños de texto, solo tendríamos que cambiar el tamaño en un solo elemento base y  automáticamente los demás elementos con unidades relativas se ajustarán basado en el nuevo tamaño.

Medidas EM

Recordemos que las medidas relativas  definen su valor así :

definen su valor en relación con otra medida, por lo que para obtener su valor real, se debe realizar alguna operación con el valor definido”.

En el caso de em su valor es relativo al “font-size” del padre directo ó del padre más cercano, esto quiere decir que cualquier cambio del CSS en cualquier nivel del DOM hace que 1em adquiera el valor de “font-size” del padre.

Por ejemplo si no definimos ningún “font-size” en nuestro css, el valor por defecto será de 16px que es el valor que asigna el navegador, por lo tanto 1em equivale a 16px.

1em = 16px
1.5em = 24px
2em = 32px
ect..

Pero podemos modificar el valor por defecto de 16px de los navegadores, por lo tanto el valor de em usaría ese valor como base, en el siguiente ejemplo podemos ver como se ha cambiado el “font-size” a 1.375em en la etiqueta html, haciendo que las demás medidas se ajusten de acuerdo a este como base por la herencia.

En este link podemos ver un ejemplo:

Para calcular el valor de las unidades em usamos la siguiente fórmula :

1em * 16px = 16px

Una técnica muy usada para no estar haciendo tanto cálculo, consiste en bajar el porcentaje para que el valor en píxeles nos de 10px. Consiste es ajustar el tamaño del “font-size” en el body para que sea equivalente a 1em =  10px en lugar de los 16px por defecto, de esta manera es más cómodo ajustar nuestros tamaños en ems. El valor de 62.5% equivale a 10px;

body { font-size:62.5%; }
h1 { font-size: 2.4em; } /* =24px */
p  { font-size: 1.4em; } /* =14px */
li { font-size: 1.4em; } /* =14px */

El problema de usar em es que se basa en herencias. Entonces si por ejemplo en una etiqueta p tengo un “font-size” y asigno el mismo “font-size” en la etiqueta span por ejemplo, span hereda el tamaño de p como su base para em. Entonces hay que estar ajustando medidas todo el tiempo, ejemplo:

<style>
html {
   font-size:62.5%;
 }
p, span{
    font-size:1.6em;
 }
</style>
<p> texto texto texto <span> Holaaaa </span> </p>
 
p tendría 1.6em el cual lo hereda a span y este lo tomaria como base para sus medidas em.

Para resolver este problema con CSS 3 ahora tenemos rem.

Medidas REM

Rem significa Root em y se basa en que con sólo declarar el rem base al elemento html las medidas siguientes no dependerán de la herencia sino del número base que hayamos declarado. Mientras em es relativo al “font-size” del padre directo o mas cercano, rem solo es relativo al “font-size” del elemento html.

Podemos definir el “font-size” del html y definir el resto de los medidas en rem basados en el porcentaje de este.

html { font-size: 62.5%; }
h1 { font-size: 2.4em; } /* =24px */
p  { font-size: 1.4em; } /* =14px */
li { font-size: 1.4em; } /* =14px */

El sorporte de rem es bastante decente hoy en dia : http://caniuse.com/#search=rem

Otro uso muy interesante es por ejemplo para márgenes ó padding relativos, digamos que queremos usar “font icons”, en el header de nuestra web y estos tienen un valor de margin-top de 20px. 

 Podemos usar un valor relativo en “font-size” en los iconos para ajustar el tamaño de estos, lo cual hará que se ajusten dinámicamente cuando cambiemos el valor del elemento base, pero el margin-top siempre será de 20px porque  tiene un valor absoluto.  Lo ideal seria que el margin-top se ajuste en dependencia del tamaño del icono.  Lo que tenemos que hacer es usar medidas relativas en el margin-top ya sea em o rem de esta manera se ajustara en concordancia con los tamaños de los iconos.

Cual debo usar em ó rem ?

La respuesta a esta pregunta es como la mayoría de las cosas, es opcional y depende de las preferencias del programador, debemos usar con la que mas nos sintamos cómodoss y la que menos dolores de cabeza nos produzca.

Medidas relativas con Media Queries

Ahora si queremos ajustar el tamaño de nuestro contenido basado en los tamaños de pantalla podemos hacer uso de las “Media queries” de la siguiente manera. Tomando los ejemplos anteriores como partida podemos ver este sencillo ejemplo:


body {
    font-size: 1.2em
}

@media (max-width: 1000px) {
 body { font-size: 1.375em  }
}

@media (max-width: 500px) {
 body { font-size: 1.6em  }
}

De esta manera todos los elementos con medidas relativas em heredan de body por lo tanto al cambiar el “font-size” de body se calcularán con este valor como base.

Usar  "em" para Media Queries en lugar de  "rem"

¿Porqué? porque el valor que obtiene "em" en Media Queries es relativo al user agent(valor por defecto del navegador ), no al estilo CSS que definimos. Por lo que si usas "rem", que debe tener una base definida en el CSS, nunca tomará esa base definida, sino que siempre tomará la medida 16px o 14px según el navegador, cosa que no podemos controlar.

Esto es debido al especificacion de la w3 :

Relative units in media queries are based on the initial value, which means that units are never based on results of declarations. For example, in HTML, the ‘em’ unit is relative to the initial value of ‘font-size’.

El uso en las de las medidas relativas no solo se pueden limitar al “font-size” en el uso de las “Media Queries”, también las podemos usar como valor para margin, padding , width y height incluso en las mismas “Media Queries” ya que tomarán como base los 16px por defecto del navegador y se aplicarán las mismas reglas. Por ejemplo:


p { 
  width: 46.25em
  font-size: 0.750em;
  line-height: 1.5em;
  margin: 1.5em;
}

/* landscape phone and portrait tablet (>= 480px < 960px) */
@media screen and (min-width:30em) and (max-width:59.9999em) {
}

/* bigger monitor (>= 1440px) */
@media screen and (min-width:90em) {
}

/* big monitor (>= 1920px) */
@media screen and (min-width:120em) {
}

Pero hay que tener mucho cuidado de saber siempre cual es valor por defecto de “font-size” en los navegadores, ya que en algunos navegadores puede ser diferente de 16px. Por ejemplo en safari mobile he leido que es de 12px.

Usa esta herramienta para saber que tamaños usar en tus medidas relativas: http://type-scale.com/

Encontre un post en stackoverflow donde resolvieron este problema con este código:

body {
    -webkit-text-size-adjust:none;
    -moz-text-size-adjust:none;
    -ms-text-size-adjust:none;
    -webkit-text-size-adjust:100%;
    -moz-text-size-adjust:100%;
    -ms-text-size-adjust:100%;
}



El uso de medidas relativas en responsive design puede ser todo un reto, pero tenemos que empezar a pensar de esta manera, ya que el “pixel perfect” ya no existe.

Nota final: ( Antes de usar rems y ems por favor revisa la compatibilidad en móviles, por que al parecer hasta este momento de escribir este articulo, el soporte en móviles es muy pobre, por lo tanto usar con precaución )


A continuacion dejo links que considero importantes leer sobre este tema, mi post esta basado en todos ellos.



http://www.paneek.net/



No hay comentarios:

Publicar un comentario