Design Responsivo com Media Queries

Artigo que mostra como projetar um site com design responsivo utilizando Media Queries do CSS3.

Introdução
Diferentes dispositivos exibindo o mesmo conteúdo, ilustrando um design responsivo

Design Responsivo (ou Responsive Design) é uma técnica que tem ganhado destaque nos últimos tempos, mas sua ideia é bastante antiga. Ela está diretamente relacionada ao pensamento de Tim Berners-Lee (o criador da Web), que dizia que os documentos da Web deveriam ser acessíveis por qualquer tipo de hardware que estivesse conectado à Internet, seja ele uma estação física ou móvel, com tela pequena ou grande. Ou seja, Design Responsivo é o nome de uma técnica que possibilita isso: prover um documento na Web que pode ser visualizado por qualquer dispositivo, de modo que o layout se adeque de forma amigável às restrições do aparelho.


A evolução do Projeto de Design Web

Em 2011, escrevi aqui no blog sobre Layout para dispositivos Móveis, que mostrava como especificar um arquivo CSS para ser aplicado apenas para dispositivos móveis (ou dispositivos de mão, handheld). Isso era feito associando um arquivo CSS a um ou mais media types específicos. Por exemplo, um arquivo CSS para telas grandes (screen) e um arquivo CSS para telas pequenas (handheld). De fato, os media types ainda continuarão existindo e tendo sua utilidade, como será visto mais a diante.

A questão é que antigamente os dispositivos de mão tinham características muito diferentes de um aparelho maior como um PC ou laptop, pois suas capacidades gráficas eram bastante reduzidas. Com o passar dos anos, a capacidade gráfica alcançou aquelas vistas nos dispositivos maiores, inclusive superando-os em alguns casos. O tamanho da tela de alguns aparelhos celulares e smartphones também aumentou um pouco, mas ainda é um diferencial em relação às telas grandes. Além disso, apareceram os tablets e TVs com acesso à web, criando novas categorias de dispositivos de acesso, com resoluções das mais diversas possíveis.

Em meio a esta confusão de tamanhos de resoluções e capacidade de cores e combinações possíveis, a W3C criou uma extensão do CSS 3 capaz de lidar melhor com esta diversidade de dispositivos: as Media Queries do CSS 3.

As Media Queries vieram para complementar as declarações específicas por Media Types, possibilitando declarar estilos específicos para:

  • dispositivos com determinado tamanho de tela (largura e altura)
  • dispositivos com restrições de número de cores
  • dispositivos com determinada resolução (dpi)
  • dispositivos baseados em grid (com largura de fonte mono-espaçada)
  • dispositivos utilizando determinada disposição de tela (retrato ou paisagem)
  • dispositivos com determinado aspecto de proporção da largura pela altura da tela (por exemplo 16:9 ou 4:3)

Neste artigo, veremos como tirar proveito deste novo recurso para projetar um design responsivo de qualidade.


Funcionamento das Media Queries do CSS 3

O funcionamento das Media Queries do CSS 3 é muito parecido com o funcionamento da especificação de estilos por Media Type suportado no CSS 2. A diferença é que agora podemos especificar mais detalhes sobre o tipo de dispositivo que desejamos aplicar determinado estilo. Ao invés de falarmos para o navegador que temos 2 folhas de estilos, uma para tela de computador e outra para dispositivos de mão, agora podemos falar que temos uma folha de estilos para telas maiores que 800 por 600 pixels e outra para telas com até 800 por 600 pixels.

Isso pode ser feito pelo atributo media da tag link, como no exemplo:

<link type="text/css" href="tela_grande.css" media="(min-width:800px),(min-device-height:600px)" />
<link type="text/css" href="tela_pequena.css" media="(max-width:799px),(max-device-height:599px)" />

Ou então podemos utilizá-las dentro do mesmo arquivo CSS, delimitando um bloco específico para um tipo de dispositivo, como no exemplo:

@media (min-width:800px),(min-device-height:600px) {
    .container {
        width: 800px;
    }
    ...
}

@media (max-width:799px), (max-device-height:599px) {
    .container {
        width: auto;
    }
    ...
}

Note que "(min-width:800px)" também é um Media Type, assim como "screen", "handheld" e "print". A diferença é que ele é declarado dinamicamente, com características mais específicas. Observe também que utilizamos a vírgula para delimitar vários Media Types que receberão um grupo de estilos em comum. No exemplo acima, especificamos que para telas grandes (que a janela tenha largura maior que 800px ou que a tela do dispositivo tenha altura maior que 600px) terão a classe "container" com tamanho de 800px, enquanto telas pequenas (que a janela tenha largura menor que 800px ou que a tela tenha altura menor que 600px) terão a classe "container" com tamanho "auto", ou seja, elástico (proporcional à largura da janela).

Também poderíamos utilizar alguns operadores como o AND para especificar Media Types mais complexos, como por exemplo "screen and (max-width:800px)". Para conhecer melhor a sintaxe permitida para montar as Media Queries, consulte a Documentação de Sintaxe das Media Queries do CSS 3.

Os possíveis atributos que podem ser utilizados para especificação do tipo de dispositivo são:

  • width: largura da alvo (largura da janela em media contínua, ou a largura do papel em media print).
  • height: altura do alvo (altura da janela em media contínua, ou a altura do papel em media print).
  • device-width: largura do dispositivo (largura da tela em media contínua, ou largura do papel em media print).
  • device-height: altura do dispositivo (altura da tela em media contínua, ou altura do papel em media print).
  • orientation: orientação da visualização, que pode ser portrait ou landscape (retrato ou paisagem).
  • aspect-ratio: aspecto da proporção da largura pela altura (width por height).
  • device-aspect-ratio: aspecto da proporção da largura do dispositivo pela altura do dispositivo (device-width por device-height).
  • color: especifica se o dispositivo suporta cores, ou o número de bits por componente de cor (RGB), ou 0 (zero) para capturar dispositivos que não aceitam cor.
  • color-index: especifica o número de cores aceito pela palheta de cores do dispositivo.
  • monochrome: especifica o número de bits por pixel em um monochrome frame buffer, ou 0 (zero) para dispositivos que não são monocromáticos.
  • resolution: especifica a resolução do dispositivo em dpi ou dpcm.
  • scan: especifica o tipo de procedimento para percorrer os pixels da tela para exibição, que pode ser progressive (todas linhas são atualizadas a cada atualização de quadro) ou interlace (apenas linhas pares ou linhas ímpares são atualizadas a cada atualização de quadro).
  • grid: especifica se o dispositivo é baseado em um grid, com tamanho de espaçamento único (como em celulares antigos, que só aceitavam texto e símbolos mono-espaçados) ou se é baseado em mapa de pixels.

Alguns destes atributos podem receber prefixos min- ou max- para se especificar um valor mínimo e máximo, assim como foi demonstrado no primeiro exemplo. Para mais detalhes sobre cada atributo, consulte a Documentação do Media Query do CSS 3.


Estratégia para utilização das Media Queries

Ao ver a lista de atributos disponíveis para montar Media Queries, já podemos imaginar que existem infinitas possibilidades de especificação de categorias de dispositivos. No entanto, não precisamos combinar todas elas para especificar grupos de dispositivos ultra específicos. Podemos utilizar as media queries apenas para identificar uma determinada característica do dispositivo e trabalhar nos estilos CSS que estejam relacionados a esta característica. Veja este exemplo:

/* Identificar o tamanho */
@media (max-width:799px) {
    .container {
        width: auto;
    }
}
@media (min-width:800px) {
    .container {
        width: 800px;
    }
}

/* Identificar a capacidade de cor */
@media (color) {
    .container {
        background-color: #FFFF00;
    }
}

Neste exemplo, utilizamos apenas três media queries, mas a verdade é que ela consegue aplicar 4 combinações de estilos, dependendo das características do dispositivo. As combinações são:

  • Dispositivos com largura de até 799px e que suportam cores;
  • Dispositivos com largura de até 799px e que não suportam cores;
  • Dispositivos com largura maior que 800px e que suportam cores;
  • Dispositivos com largura maior que 800px e que não suportam cores.

Observe que as duas primeiras media queries servem para identificar a largura da janela e, de acordo com esta característica, atribuímos uma largura para nossa classe "container". A terceira media query serviu para identificar se o dispositivo aceita cores ou não e, caso aceite, atribuímos uma cor de fundo à nossa classe "container". Ou seja, criamos uma única classe chamada "container", mas ela possui diferentes comportamentos, que variam de acordo com as características identificadas do dispositivo.

Algo importante para se destacar é que, como as Media Queries são recentes, também é importante que você especifique um conjunto de estilos padrão fora das media queries. Este conjunto será aplicado a todos os navegadores (independente se reconhecem ou não as media queries). Depois, você pode sobrescrever os valores de algumas propriedades definidas no escopo padrão, através de um um bloco de media query.

Uma outra observação é que alguns dispositivos de mão ajustam o "zoom" de uma página para que caibam em suas telas reduzidas. Normalmente são aparelhos que oferecem recurso de zoom através da manipulação touchscreen de pinça. Para evitar que eles realizem esta operação, é utilizada uma meta tag "viewport", conforme o exemplo:

<meta name="viewport" content="width=device-width; initial-scale=1.0" />

Os padrões de Design Responsivo

Bom, agora que estamos craques na utilização de Media Queries do CSS 3, que é o coração do Design Responsivo, vamos falar do bendito Design Responsivo.

Pra começar, você deve identificar os potenciais grupos de tamanhos de telas disponíveis no mercado e trabalhar em cima de alguns poucos grupos "padrão", chamados de "breakpoints". Uma distribuição bastante adequada é aquela utilizada pelo layout toolkit "Twitter Bootstrap":

  • Telas grandes: largura igual ou superior a 1200px (monitores grandes ou TVs).
  • Padrão: largura entre 980px e 1200px (normalmente monitores).
  • Tablets usados na forma de paisagem (portrait): largura entre 768px e 980px.
  • Tablets usados na forma de retrato (landscape) ou celulares largos: largura entre 480px e 768px.
  • Celulares com tela convencional: largura de até 480px.

Veja a especificação dos grupos de tamanhos do Twitter Bootstrap, para mais detalhes.

A grande magia por trás do Design Responsivo deste toolkit e de outros é que ele é trabalhado em cima da largura da janela (e não a largura do dispositivo). Então, em um mesmo dispositivo, se você redimensiona a janela aos poucos (ou então passa a trabalhar com outra disposição como de retrato para paisagem), automaticamente o navegador aplica uma nova combinação de estilos que se adequa a aquela largura. Isso tudo para propiciar uma navegação mais amigável e acessível, sem a necessidade de barras de rolagem horizontais, e uma experiência melhor para o usuário do site. Recentemente ajustei o layout deste blog para ser responsivo para telas menores que 960px. Experimente redimensionar a largura da janela do navegador e observe o comportamento dos elementos da página.

Já existem alguns padrões e dicas para se estruturar conteúdos HTML para apresentação em diferentes dispositivos. No artigo 7 Responsive Design Tips to Revamp Your Workflow são mostrados sete deles: Mobile First, Content Strategy, Sketch and Prototype, Frameworks, Breakpoints, Scalable Images e Minification.

Neste artigo, apresentei o principal recurso necessário para se estruturar um layout responsivo do zero. Mas pode ser útil aprender a usar um layout toolkit que já possui boas práticas embutidas. Confira no artigo Layout Toolkit alguns exemplos interessantes.

4 comentários