“Design responsivo” se refere a ideia de que sua página web deve apresentar igualmente o conteúdo em uma tela widescreen assim como em um smartphone. É uma abordagem de desenvolvimento e design que elimina a distinção entre as versões compatíveis com dispositivos móveis e computadores desktops da sua sua página web. Com o design responsivo eles fazem a mesma coisa, em qualquer tela.

Design responsivos são feitos através de “media queries” da CSS. Pense em media queries como uma forma de aplicar condicionalmente as regras CSS. Elas falam para o navegador que ele deve ignorar ou aplicar certas regras dependendo do dispositivo do usuário.

Diagram: HTML content pointing to media queries, which point to mobile, tablet, and desktop devices

Media queries nos permitem apresentar o mesmo conteúdo HTML em diferentes layouts CSS. Assim, ao invés de manter uma página web para smartphones e uma outra página totalmente diferente para computadores, nós podemos utilizar a mesma marcação HTML (e servidor web) para ambos. Isso significa que onde quer que esteja nós adicionamos novos artigos ou editamos um erro de escrita no nosso HTML, e essas alteração são alterados automaticamente em ambos os layouts, no dispositivo móvel e no computador. Esse é o motivo de separarmos o conteúdo da apresentação.

Neste capítulo, vamos aprender como media queries são somente uma capa fina que cobre a CSS que estivemos trabalhando até o momento. Como vamos descobrir logo, é realmente muito fácil implementar um layout responsivo (Imagens Responsivas, por outro lado, são uma história completamente diferente).

Configuração

Crie um novo projeto chamado responsive-design e um arquivo novo chamado responsive.html. É a nossa página web vazia, que já estamos acostumado, mas que irá nos ajudar a demonstrar algo bem importante na próxima seção:

<!DOCTYPE html>
<html lang='pt-br'>
  <head>
    <meta charset='UTF-8'/>
    <title>Design Responsivo</title>
    <link rel='stylesheet' href='styles.css'/>
  </head>
  <body>
    <!-- Não tem nada aqui! -->
  </body>
</html>

Você também precisará fazer o download de algumas imagens para usar mais tarde no capítulo. Descompacte tudo na mesma pasta do arquivo responsive.html, mantendo a pasta pai images. Seu projeto deve estar parecendo como esse da figura abaixo:

Screenshot: Atom’s file browser with project files in it

Media queries CSS

Vamos começar pequeno, modificando a cor de fundo do elemento <body> baseado na largura do dispositivo. Esta é uma boa forma de garantir que nossas media queries estão funcionando antes de o layout ficar mais complicado.

Diagram: mobile device with red background, tablet with yellow background, desktop with blue background. Background colors set with media queries.

Vamos diferenciar entre um layout estreito, médio e largo criando uma nova folha de estilo styles.css e adicionando o seguinte:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Estilo para Mobile */
@media only screen and (max-width: 400px) {
  body {
    background-color: #F09A9D; /* Vermelho */
  }
}

/* Estilo para Tablet */
@media only screen and (min-width: 401px) and (max-width: 960px) {
  body {
    background-color: #F5CF8E; /* Amarelo */
  }
}

/* Estilo par Desktop */
@media only screen and (min-width: 961px) {
  body {
    background-color: #B2D6FF; /* Azul */
  }
}

Quando você redimensionar seu navegador, você deve ver três cores de fundos diferentes: azul quando for maior que 960px, amarelo quando tiver entre 401px e 960px, e vermelho quando for menor que 400px.

A regra” das Media queries sempre iniciarão com @media seguida de algum tipo de estado condicional, e depois as chaves. Dentro das chaves, você vai colocar todo tipo de regra CSS. O navegador só vai respeitar aquelas regras se a condição for satisfeita.

Diagram: media query composed of the @media at-rule, a media type, a media feature, then a bunch of ordinary CSS

O “tipo de mídia” only screen significa que o estilo só deve ser aplicado aos dispositivos com telas (o oposto de documentos impressos, como quando você pressiona Ctrl+P) em um navegador). As partes min-width e max-width são o que chamamos de “funções de mídia”, e elas especificam as dimensões do dispositivo que você está mirando.

As media queries acima são de longe as mais comuns utilizadas hoje em dia, mas existem muitas outras condições que você pode utilizar, incluindo se o dispositivo está em modo retrato ou paisagem, a resolução da tela, e se ela tem um mouse ou não.

Algumas coisas sobre Design

Beleza, então é com @media que definimos diferentes layouts para larguras específicas de dispositivos, mas que tipos de layouts estamoss tentando implementar? A página web de exemplo para este capítulo deve se parecer com algo como isso:

Mockups of mobile, tablet, and desktop web pages

No mundo real, é responsabilidade do seu web designer providenciar para você esses modelos. Seu trabalho como desenvolvedor é implementar os layouts utilizando media queries para separar as diferentes regras CSS que se aplicam a cada tipo.

Existem alguns padrões já bem definidos de como um layout para desktop deve ser transformado em um layout para mobile (estamos utilizando “layout shifter”). Muitas dessas decisções estão sob o domínio do design, que está fora do objetivo desses tutoriais orientados ao código; no entanto, existem dois conceitos que você deve entender como desenvolvedor:

  • Um layout “fluido” é aquele que se alarga e encolhe para caber na largura da tela, assim como as caixas flexíveis que cobrimos alguns capítulos atrás.
  • Um layout “largura-fixa” é o oposto: ele tem a mesma largura independente da dimensão da tela (criamos um desses no capítulo de Seletores CSS).
Diagram: fluid layout expanding to fill entire width of the browser, fixed-width layout staying the same even if browser gets wider

Na nossa página de exemplo, as versões para mobile e tablet são fluídas e a versão desktop é de largura-fixa.

Escolhendo como redimensionar

A maioria desses padrões de designs responsivos tem um comportamento similar, usam layouts fluídos para mobile/tablet e de largura-fixa para telas maiores. Existe uma razão para isso.

Layouts fluídos nos permitem alcançar um grande números de telas com larguras diferentes, ao contrário de telas de dispositivos móveis específicos. Isso é muito importante para web designer. Quando eles iniciam a criação de um layout, não estão tentando fazer alguma coisa que fique bom em um iPhone 6s, Galaxy S7, ou em um Ipad mini—estão criando um layout fluído que vai ficar bom em qualquer lugar entre 300 pixels e 500 pixels (ou como quiser).

Em outras palavras, os valores exatos em pixel para os parâmetros min-width e max-width em um media query (são conhecidos como pontos de redimensionamento para uma página responsiva) não importam muito. Nossa página não se importam com qual dispositivo o usuário está utilizando. Tudo que ele precisa saber é se aquilo deveria parecer um layout que fica bem em uma tela mais larga que 400 pixels (ou qual quiser).

Desenvolvimento para dispositivos móveis

Vamos mergulhar na implementação da imagens acima. É sempre uma boa ideia começar com o desenvolvimento para dispositivos móveis e depois na versão para desktop. Layouts para desktops são normalmente mais complexos que os para dispositivos móveis, e essa abordagem “dispositivos-móveis-primeiro” maximiza a quantidade de CSS que você poderá reutilizar entre os layouts.

Primeiro, precisamos completar o elemento <body> do responsive.html com algumas caixas vazias. Cada caixa tem uma imagem dentro dela assim conseguimos diferenciá-las mais facilmente.

<div class='page'>
  <div class='section menu'></div>
  <div class='section header'>
    <img src='images/header.svg'/>
  </div>
  <div class='section content'>
    <img src='images/content.svg'/>
  </div>
  <div class='section sign-up'>
    <img src='images/sign-up.svg'/>
  </div>
  <div class='section feature-1'>
    <img src='images/feature.svg'/>
  </div>
  <div class='section feature-2'>
    <img src='images/feature.svg'/>
  </div>
  <div class='section feature-3'>
    <img src='images/feature.svg'/>
  </div>
</div>

E aqui está nossa estilização base, que deve ser aplicada a todos os layouts (smartphones, tablet e desktop). Tenha certeza de adicionar isso acima das regras @media que criamos mais cedo e abaixo da regra de seletor universal que reconfigura nossas margens e preenchimento:

.page {
  display: flex;
  flex-wrap: wrap;
}

.section {
  width: 100%;
  height: 300px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.menu {
  background-color: #5995DA;
  height: 80px;
}

.header {
  background-color: #B2D6FF;
}

.content {
  background-color: #EAEDF0;
  height: 600px;
}

.sign-up {
  background-color: #D6E9FE;
}

.feature-1 {
  background-color: #F5CF8E;
}

.feature-2 {
  background-color: #F09A9D;
}

.feature-3 {
  background-color: #C8C6FA;
}

Se você diminuir a largura da janela do navegador, verá o nosso layout para dispositivos móveis, ou seja, bem estreito. Bem fácil, não? Sem necessidade de media queries. Isso é o que chamamos de “dispositivos-móveis-primeiro”—a versão para dispositivos móveis não precisa de nenhum tratamento especial. Note também a propriedade flex-wrap na div .page. Assim fica muito mais fácil de implementar os layouts para tablet e desktop.

Web page showing layout created with mobile-first CSS (no media queries)

Se mantermos esse estilo base fora das media queries, será possível sobreescrever e adicionar a ela, assim que precisar implementar os diferentes layouts. Isso é muito conveniente quando, por exemplo, o designer quiser ajustar o esquema de cores para toda a página web. Ao invés de rastrear todas as possíveis redundâncias de declarações background-color em diferentes regras @media, você só precisa alterá-la aqui. Essa mudança se aplica automaticamente aos diferentes layouts que tivermos disponível.

Layout para Tablet

Sobre o layout para tablet. A única diferença entre os modelos para dispositivos móveis e tablet é que as seções Sign Up e Feature formam uma grade 2×2 ao invés de uma coluna simples.

Flexbox torna isso realmente muito fácil. Só ajustar as larguras dos itens flex para ser a metade da tela e o flex-wrap vai tomar conta do resto. Claro, só queremos que esse comportamento seja aplicado a telas de tablets, então isso precisa estar dentro de uma regra @media. Altere a media query em /* Estilo para Tablet */ para o seguite:

/* Estilo para Tablet */
@media only screen and (min-width: 401px) and (max-width: 960px) {
  .sign-up,
  .feature-1,
  .feature-2,
  .feature-3 {
    width: 50%;
  }
}

Para visualizar estas mudanças, garanta que a janela do seu navegador tem uma largura entre 400 pixels e 960 pixel, depois role até fim da página para ver uma grade bem colorida:

Web page showing the grid created from tablet media query

De novo, não importa qual é a largura exata que a tela tem: essa é a reposta fluída do layout para qualquer largura no intervalo da media query. Nosso layout para dispositivos móveis também é fluído, então agora temos uma página web muito bonita (mesmo meio vazia) em todos os dispositivos com largura menores que 960px.

Layout para Desktop

E é agora que nosso layout para desktop aparece. Não queremos que nossa página web se expanda sem fim, então vamos definir uma largura fixa e centralizar com o auto-margins. Assim como no estilo para tablet, isso precisa estar definido dentro da media query. Substitua media query do /* Estilo para Desktop */ que já existe, para o que está abaixo:

/* Estilo para Desktop */
@media only screen and (min-width: 961px) {
  .page {
    width: 960px;
    margin: 0 auto;
  }
  .feature-1,
  .feature-2,
  .feature-3 {
    width: 33.3%;
  }
  .header {
    height: 400px;
  }
}

Isso nos dará a largura correta para tudo, e ainda teremos espaço suficiente para brincar, então faremos o cabeçalho um pouco mais alto. Quase lá, mas nosso layout para desktop precisa de uns ajustes: as caixas do Sign up e Content devem aparecer abaixo da seção Feature.

Desktop layout of web page before and after flexbox re-ordering

É aqui que o flexbox vai realmente brilhar. Tentar criar essa combinação de layouts para todos esses tamanhos de telas diferentes seria extramamente difícil com o floats. Com a propriedade propriedade order do flexbox, só precisamos de algumas linhas de CSS. Adicione essas regras à media query do desktop:

.sign-up {
  height: 200px;
  order: 1;
}
.content {
  order: 2;
}

Tcharam!! Uma página responsiva! Nada mal para pouco mais de cem linhas de CSS. O mais importante, não precisamos mudar uma linha sequer da HTML para contemplar os três layouts.

Esse foi só um exemplo da construção de uma página responsiva. Agora você pode usar essas mesmas técnicas para implementar todo tipo de designs. Comece com uma estilização básica que irá ser aplicada a toda página, depois vá alterando-a para várias larguras de dispositivos e seletivamente aplicando regras CSS com a @media. Você pode até mesmo adicionar outras media query para, vamos dizer, criar um layout para monitores ultra-widescreen.

Desabilitando o zoom da janela

Temos uma última tarefa para fazer uma página web responsiva. Antes da criação do design responsivo, dispositivos móveis tinham somente o layout desktop para trabalhar. Para lidar com isso, eles tiravam o zoom para que o layout desktop coubesse no tamanho da tela, permitindo que o usuário interagisse com o zoom quando necessário.

Diagram: zoom enabled (desktop layout rendered in a tablet device) versus zoom disabled (tablet layout rendered in a tablet device)

Esse comportamento padrão irá prevenir que dispositivos móveis utilizem o layout adequado, ou seja, o de dispositivos móveis, e isso é terrível. Para desabilitar isso, adicione o elemento abaixo ao <head> do nosso documento HTML. Como o <meta charset='UTF-8'/>, esse é um elemento crítico que deve estar em toda página web que você criar:

<meta name='viewport'
      content='width=device-width, initial-scale=1.0, maximum-scale=1.0' />

Para ver isso em ação, vamos precisar simular um dispositivo móvel no nosso navegador. Isso é um pouco avançado demais no ponto onde estamos agora, mas podemos tentar. Abra o responsive.html no Mozilla Firefox ou no Google Chrome, e pressione F12 ele irá exibir as Ferramentas de desenvolvedor. Depois, para simular um dispositivo móvel, clique no ícone de Modo de design responsivo , como na figura a seguir.

Screenshot: responsive icon in Chrome’s developer toolbar

Você deve estar vendo a versão com o zoom desabilitado do diagrama acima no seu navegador, já que agora ele está se comportando como um dispositivo móvel. (Vamos deixar a discussão sobre as ferramentas de desenvolvimento para um tutorial futuro.)

Outra opção é, se você estiver lendo este capítulo em um smartphone, você pode navegar para a versão antes e depois do nosso projeto para ver as mudanças que o viewport faz.

REsumo

Acredite ou não, atualmente isso é tudo que você precisa saber para criar páginas web responsivas. Se precisássemos resumir, só estamos preocupados com três coisas:

  • O design responsivo (o modelo de cada layout)
  • As regras CSS para implementar cada um desses layouts
  • As media queries para aplicação condicional dessas regras CSS

Começamos esse capítulo aprendendo sobre as diferenças entre layouts fluídos e de largura-fixa. Depois, criamos uma folha de estilo para uma abordagem dispositivos-móveis-primeiro que utilizou media queries para construir layouts para tablets e desktop sob um estilo base. E finalmente, desabilitamos o comportamento padrão de zoom da janela para navegadores de dispositivos móveis.

Então, essa foi a parte fácil de design responsivo. No próximo capítulo, vamos descobrir a parte difícil: imagens. Apresentar diferentes CSS para dispositivos específicos não é tão ruim, mas otimizar as imagens para esses dispositivos é preciso um pouco mais de planejamento.