Fundamentos do Web design responsivo

Como criar sites que atendam às necessidades e aos recursos do dispositivo no qual são visualizados.

O uso de dispositivos móveis para navegar na Web continua crescendo em um ritmo astronômico, e esses dispositivos muitas vezes são limitados pelo tamanho da tela e exigem uma abordagem diferente para o layout do conteúdo.

O Web design responsivo, originalmente definido por Ethan Marcotte em A List Apart, atende às necessidades dos usuários e aos dispositivos que eles utilizam. O layout muda com base no tamanho e nos recursos do dispositivo. Por exemplo, em um smartphone, os usuários veriam o conteúdo em uma única coluna, enquanto um tablet pode mostrar o mesmo conteúdo em duas colunas.

Neste vídeo, o design muda de uma janela de visualização estreita para uma ampla, respondendo ao espaço disponível na tela.

Existem diversos tamanhos de tela entre celulares, "phablets", tablets, desktops, consoles de jogos, TVs e até mesmo wearables. Os tamanhos das telas estão sempre mudando. Por isso, é importante que seu site possa se adaptar a qualquer tamanho, hoje ou no futuro. Além disso, os dispositivos têm diferentes recursos com os quais interagimos com eles. Por exemplo, alguns visitantes vão usar uma tela touchscreen. O design responsivo moderno considera todos esses fatores para otimizar a experiência para todos.

Definir a janela de visualização

Páginas otimizadas para diversos dispositivos devem incluir uma tag meta janela de visualização no cabeçalho do documento. Uma tag de janela de visualização meta fornece ao navegador instruções sobre como controlar as dimensões e o dimensionamento da página.

Para oferecer a melhor experiência possível, os navegadores de dispositivos móveis renderizam a página na largura de uma tela de computador (geralmente cerca de 980px, embora isso varie de acordo com os dispositivos) e, em seguida, tentam melhorar a aparência do conteúdo aumentando os tamanhos da fonte e dimensionando o conteúdo para que ele caiba na tela. Isso significa que os tamanhos das fontes podem parecer inconsistentes para os usuários, que podem precisar tocar duas vezes ou fazer gesto de pinça para aplicar zoom a fim de visualizar e interagir com o conteúdo.

<!DOCTYPE html>
<html lang="en">
  <head>
    …
    <meta name="viewport" content="width=device-width, initial-scale=1">
    …
  </head>
  …

O uso do valor width=device-width da janela de visualização meta instrui a página a corresponder à largura da tela em pixels independentes de dispositivo. Um pixel independente de dispositivo (ou densidade) é uma representação de um único pixel, que pode, em uma tela de alta densidade, consistir em vários pixels físicos. Isso permite que a página reflow do conteúdo para corresponder a diferentes tamanhos de tela, seja renderizado em um smartphone pequeno ou em um monitor grande de computador.

Captura de tela de uma página com texto difícil de ler porque o zoom está muito baixo.
Exemplo de carregamento da página em um dispositivo sem a metatag da janela de visualização. Confira este exemplo no Glitch.
Captura de tela da mesma página com o texto em um tamanho que pode ser lido.
Exemplo de carregamento da página em um dispositivo com a metatag da janela de visualização. Confira este exemplo no Glitch.

Alguns navegadores mantêm a largura da página constante ao girar para o modo paisagem e aplicar zoom em vez de ajustar o fluxo para preencher a tela. Adicionar o valor initial-scale=1 instrui os navegadores a estabelecer uma relação de 1:1 entre pixels CSS e pixels independentes de dispositivo, independentemente da orientação do dispositivo. Isso permite que a página aproveite a largura total do modo paisagem.

A auditoria do Lighthouse não tem uma tag <meta name="viewport"> com width ou initial-scale pode ajudar a automatizar o processo para garantir que seus documentos HTML estejam usando a metatag da janela de visualização corretamente.

Garantir uma janela de visualização acessível

Além de definir um initial-scale, você também pode definir os seguintes atributos na janela de visualização:

  • minimum-scale
  • maximum-scale
  • user-scalable

Quando definidos, eles podem desativar a capacidade do usuário de ampliar a janela de visualização, possivelmente causando problemas de acessibilidade. Portanto, não recomendamos o uso desses atributos.

Dimensione o conteúdo de acordo com a janela de visualização

Em computadores e dispositivos móveis, os usuários estão acostumados a rolar os sites verticalmente, mas não horizontalmente. Forçar o usuário a rolar horizontalmente ou diminuir o zoom para ver a página inteira resulta em uma experiência do usuário ruim.

Ao desenvolver um site para dispositivos móveis com uma tag de janela de visualização meta, é fácil criar acidentalmente um conteúdo da página que não se encaixa na janela de visualização especificada. Por exemplo, uma imagem exibida em uma largura mais larga do que a janela de visualização pode fazer com que ela role horizontalmente. Ajuste esse conteúdo para caber na largura da janela de visualização, para que o usuário não precise rolar horizontalmente.

O conteúdo não está no tamanho correto para a janela de visualização. A auditoria do Lighthouse pode ajudar a automatizar o processo de detecção de conteúdo em excesso.

Imagens

Uma imagem tem dimensões fixas e, se for maior do que a janela de visualização, criará uma barra de rolagem. Uma maneira comum de lidar com esse problema é dar a todas as imagens um max-width de 100%. Isso fará com que a imagem seja reduzida para caber no espaço que ela tem, caso o tamanho da janela de visualização seja menor que a imagem. No entanto, como max-width, em vez de width, é 100%, a imagem não será maior do que o tamanho natural. Geralmente, é seguro adicionar o seguinte à sua folha de estilo para que você nunca tenha problemas com imagens que causam uma barra de rolagem.

img {
  max-width: 100%;
  display: block;
}

Adicionar as dimensões da imagem ao elemento img

Ao usar max-width: 100%, você substitui as dimensões naturais da imagem. No entanto, ainda é necessário usar os atributos width e height na tag <img>. Isso ocorre porque os navegadores mais recentes usam essas informações para reservar espaço para a imagem antes que ela seja carregada. Isso ajuda a evitar mudanças de layout à medida que o conteúdo é carregado.

Layout

Como as dimensões e a largura da tela em pixels CSS variam muito entre dispositivos (por exemplo, entre smartphones e tablets e até mesmo entre smartphones diferentes), o conteúdo não pode depender de uma largura de janela de visualização específica para ser renderizado corretamente.

Antes, isso exigia elementos de configuração usados para criar o layout em porcentagens. No exemplo abaixo, você pode ver um layout de duas colunas com elementos flutuantes, dimensionados usando pixels. Quando a janela de visualização se torna menor que a largura total das colunas, é necessário rolar a tela horizontalmente para ver o conteúdo.

Captura de tela de um layout de duas colunas com a maior parte da segunda coluna fora da janela de visualização
Um layout flutuante usando pixels. Confira este exemplo no Glitch.

Ao usar porcentagens para as larguras, as colunas sempre permanecem uma determinada porcentagem do contêiner. Isso significa que as colunas ficam mais estreitas, em vez de criar uma barra de rolagem.

As técnicas modernas de layout de CSS, como Flexbox, layout de grade e multicol, facilitam muito a criação dessas grades flexíveis.

Flexbox

Esse método de layout é ideal quando você tem um conjunto de itens de diferentes tamanhos e quer que eles caibam confortavelmente em uma ou mais linhas, com itens menores ocupando menos espaço e os maiores recebendo mais espaço.

.items {
  display: flex;
  justify-content: space-between;
}

Em um design responsivo, é possível usar o Flexbox para exibir itens como uma única linha ou agrupados em várias linhas à medida que o espaço disponível diminui.

Leia mais sobre o Flexbox.

Layout de grade CSS

O layout de grade CSS permite a criação direta de grades flexíveis. Se considerarmos o exemplo flutuante anterior, em vez de criar nossas colunas com porcentagens, poderíamos usar o layout de grade e a unidade fr, que representa uma parte do espaço disponível no contêiner.

.container {
  display: grid;
  grid-template-columns: 1fr 3fr;
}

A grade também pode ser usada para criar layouts de grade regulares, com quantos itens couberem. O número de faixas disponíveis vai ser reduzido à medida que o tamanho da tela diminuir. Na demonstração abaixo, temos quantos cards couberem em cada linha, com um tamanho mínimo de 200px.

Leia mais sobre o layout de grade CSS

Layout de várias colunas

Para alguns tipos de layout, você pode usar o layout de várias colunas (multicol), que pode criar números responsivos de colunas com a propriedade column-width. Na demonstração abaixo, é possível ver que as colunas são adicionadas quando há espaço para outra coluna 200px.

Leia mais sobre a Multicol

Usar consultas de mídia CSS para capacidade de resposta

Às vezes, você precisará fazer mudanças mais extensas no layout para oferecer suporte a um determinado tamanho de tela, do que as técnicas mostradas acima permitem. É aqui que as consultas de mídia se tornam úteis.

As consultas de mídia são filtros simples que podem ser aplicados a estilos CSS. Eles facilitam a mudança de estilos com base nos tipos de dispositivo que renderizam o conteúdo ou nos recursos do dispositivo, como largura, altura, orientação, capacidade de passar o cursor e se o dispositivo está sendo usado como tela touchscreen.

Para fornecer estilos diferentes para impressão, é preciso segmentar um type de saída para incluir uma folha de estilo com estilos de impressão, da seguinte maneira:

<!DOCTYPE html>
<html lang="en">
  <head>
    …
    <link rel="stylesheet" href="print.css" media="print">
    …
  </head>
  …

Como alternativa, é possível incluir estilos de impressão na sua folha de estilo principal usando uma consulta de mídia:

@media print {
  /* print styles go here */
}

Para o Web design responsivo, normalmente consultamos os recursos do dispositivo para fornecer um layout diferente para telas menores ou quando detectamos que o visitante está usando uma tela touchscreen.

Consultas de mídia baseadas no tamanho da janela de visualização

As consultas de mídia nos permitem criar uma experiência responsiva em que estilos específicos são aplicados a telas pequenas, telas grandes e qualquer tela intermediária. Portanto, o recurso que estamos detectando é o tamanho da tela, e podemos testar o seguinte.

  • width (min-width, max-width)
  • height (min-height, max-height)
  • orientation
  • aspect-ratio

Todos esses recursos oferecem excelente suporte ao navegador. Para mais detalhes, incluindo informações de suporte, consulte largura, altura, orientação e proporção no MDN.

Consultas de mídia com base na capacidade do dispositivo

Considerando a variedade de dispositivos disponíveis, não podemos supor que cada dispositivo grande seja um computador desktop ou laptop normal ou que as pessoas estejam usando apenas uma tela touchscreen em um dispositivo pequeno. Com algumas adições mais recentes à especificação de consultas de mídia, podemos testar recursos, como o tipo de ponteiro usado para interagir com o dispositivo e se o usuário pode passar o cursor sobre elementos.

  • hover
  • pointer
  • any-hover
  • any-pointer

Tente visualizar esta demonstração em diferentes dispositivos, como um computador desktop e um smartphone ou tablet.

Esses novos recursos têm bom suporte em todos os navegadores mais recentes. Saiba mais nas páginas MDN para hover, passar o cursor, apontador e qualquer ponteiro.

Como usar any-hover e any-pointer

Os recursos any-hover e any-pointer testam se o usuário tem a capacidade de passar o cursor ou usar esse tipo de ponteiro, mesmo que essa não seja a principal forma de interação com o dispositivo. Tenha muito cuidado ao usá-los. Não é muito amistoso forçar um usuário a trocar para um mouse quando estiver usando a tela touchscreen! No entanto, any-hover e any-pointer podem ser úteis se for importante entender o tipo de dispositivo do usuário. Por exemplo, um laptop com tela touchscreen e trackpad precisa corresponder a ponteiros aproximados e finos, além da capacidade de passar o cursor.

Como escolher pontos de interrupção

Não defina pontos de interrupção com base em classes de dispositivo. Definir pontos de interrupção com base em dispositivos, produtos, nomes de marcas ou sistemas operacionais específicos em uso atualmente pode resultar em um pesadelo com a manutenção. Em vez disso, o próprio conteúdo deve determinar como o layout se ajusta ao contêiner.

Selecione os principais pontos de interrupção começando pequeno e progredindo

Projete o conteúdo para que ele caiba primeiro em uma tela pequena e depois expanda a tela até que um ponto de interrupção se torne necessário. Isso permite otimizar pontos de interrupção com base no conteúdo e manter o menor número possível de pontos de interrupção.

Vamos analisar o exemplo que vimos no início: a previsão do tempo. A primeira etapa é fazer com que a previsão tenha uma boa aparência em uma tela pequena.

Captura de tela de um app meteorológico na largura de um dispositivo móvel
O app com largura estreita.

Em seguida, redimensione o navegador até que haja muito espaço em branco entre os elementos e a previsão não esteja tão bonita. A decisão é subjetiva, mas valores acima de 600px são muito amplos.

Captura de tela de um app meteorológico com grandes lacunas entre os itens
O app em um ponto em que achamos que precisamos ajustar o design.

Para inserir um ponto de interrupção em 600px, crie duas consultas de mídia no final do CSS para o componente, uma para usar quando o navegador estiver 600px ou abaixo e outra para quando ele for mais largo que 600px.

@media (max-width: 600px) {

}

@media (min-width: 601px) {

}

Por fim, refatore o CSS. Dentro da consulta de mídia para um max-width de 600px, adicione o CSS, exclusivo para telas pequenas. Dentro da consulta de mídia para uma min-width de 601px, adicione CSS para telas maiores.

Escolha pontos de interrupção secundários quando necessário

Além de escolher os principais pontos de interrupção quando o layout muda significativamente, também é útil ajustar para pequenas mudanças. Por exemplo, entre os principais pontos de interrupção, pode ser útil ajustar as margens ou o padding de um elemento ou aumentar o tamanho da fonte para que ela pareça mais natural no layout.

Vamos começar otimizando o layout para telas pequenas. Nesse caso, vamos aumentar a fonte quando a largura da janela de visualização for maior que 360px. Segundo, quando há espaço suficiente, podemos separar as temperaturas máximas e mínimas para que elas fiquem na mesma linha, e não uma em cima da outra. E também vamos aumentar um pouco os ícones de clima.

@media (min-width: 360px) {
  body {
    font-size: 1.0em;
  }
}

@media (min-width: 500px) {
  .seven-day-fc .temp-low,
  .seven-day-fc .temp-high {
    display: inline-block;
    width: 45%;
  }

  .seven-day-fc .seven-day-temp {
    margin-left: 5%;
  }

  .seven-day-fc .icon {
    width: 64px;
    height: 64px;
  }
}

Da mesma forma, para as telas grandes, é melhor se limitar à largura máxima do painel de previsão para que ele não consuma toda a largura da tela.

@media (min-width: 700px) {
  .weather-forecast {
    width: 700px;
  }
}

Otimizar textos para leitura

A teoria de legibilidade clássica sugere que uma coluna ideal deve conter de 70 a 80 caracteres por linha (cerca de 8 a 10 palavras em inglês). Assim, sempre que a largura de um bloco de texto ultrapassar 10 palavras, considere adicionar um ponto de interrupção.

Captura de tela de uma página de texto em um dispositivo móvel
O texto lido em um dispositivo móvel.
Captura de tela de uma página de texto em um navegador para computador
O texto lido em um navegador para computador com um ponto de interrupção adicionado para restringir o comprimento da linha.

Vamos analisar mais detalhadamente o exemplo de postagem do blog acima. Em telas menores, a fonte Roboto em 1em funciona perfeitamente com 10 palavras por linha, mas telas maiores exigem um ponto de interrupção. Nesse caso, se a largura do navegador for maior que 575px, a largura ideal do conteúdo será 550px.

@media (min-width: 575px) {
  article {
    width: 550px;
    margin-left: auto;
    margin-right: auto;
  }
}

Evite simplesmente ocultar o conteúdo

Tenha cuidado ao escolher qual conteúdo ocultar ou mostrar dependendo do tamanho da tela. Não oculte conteúdo só porque ele não cabe na tela. O tamanho da tela não é uma indicação definitiva do que um usuário pode querer. Por exemplo, eliminar a contagem de pólen da previsão do tempo pode ser um problema sério para quem sofre com alergia na primavera e precisa determinar se pode sair ou não.

Conferir pontos de interrupção de consultas de mídia no Chrome DevTools

Depois de configurar os pontos de interrupção de consultas de mídia, confira a aparência do seu site neles. Você pode redimensionar a janela do navegador para acionar os pontos de interrupção, mas o Chrome DevTools tem um recurso integrado que facilita a visualização da aparência de uma página em diferentes pontos de interrupção.

Captura de tela do DevTools com nosso app meteorológico aberto e uma largura de 822 pixels selecionada.
DevTools mostrando o app de clima enquanto ele observa um tamanho mais amplo da janela de visualização.
Captura de tela do DevTools com nosso app meteorológico aberto e uma largura de 436 pixels selecionada.
DevTools mostrando o app de clima enquanto ele analisa um tamanho de janela de visualização mais estreito.

Para visualizar sua página em diferentes pontos de interrupção:

Abra o DevTools e ative o Device Mode. Por padrão, ele é aberto no modo responsivo.

Para conferir suas consultas de mídia, abra o menu do Modo dispositivo e selecione Mostrar consultas de mídia para mostrar os pontos de interrupção como barras coloridas acima da página.

Clique em uma das barras para visualizar sua página enquanto a consulta de mídia estiver ativa. Clique com o botão direito do mouse em uma barra para acessar a definição da consulta de mídia.