Desenvolver aplicações web hoje em dia muitas vezes se resume à correta escolha do framework de componentes (como Bootstrap, Google Material Design Lite, etc.) para facilitar a construção da estrutura e estilo das páginas. Esse cenário funciona muito bem até o momento em que tais bibliotecas não atendem mais aos recursos específicos do seu projeto: por exemplo, quando precisamos de componentes/design muito específicos ou, pior ainda, quando precisamos misturar os componentes de duas bibliotecas diferentes numa só aplicação para atender a demanda, aumentando consideravelmente a quantidade de código e arquivos (muitos deles sequer usados). Uma solução mais adequada seria a criação da sua própria biblioteca de componentes responsivos, com seu próprio estilo. Assim, evitamos o excesso de implementação e, acima de tudo, temos o total controle de todo o website. Este artigo vai ao encontro à essa realidade, ensinando a fazer uso dos recursos mais recentes da HTML5 e CSS3 para construir seus frameworks web.


Guia do artigo:

Sem dúvida a responsividade é o conceito mor que define a qualidade de um site, aliada a conceitos como confiabilidade, segurança, performance e preocupação dos criadores para com seu público. Não dá mais para pensar em criar qualquer aplicação web ou website sem priorizar a responsividade como pré-requisito básico e fundamental.

O próprio Google, bem como outras ferramentas de busca na web, ranqueiam melhor sites que apresentam seu conteúdo de forma mobile friendly, isto é, preparam seus conteúdos para serem exibidos em dispositivos de diversos tamanhos, a incluir smartphones, tablets, notebooks, etc.

Em ferramentas e metodologias de SEO (Search Engine Optimization) esse conceito é tido como primário para um bom resultado junto aos sites de pesquisa, logo, você deve estar preparado para lidar com isso em seus projetos front-end como um todo.

Frameworks famosos como o Twitter Bootstrap, Angular Material (do AngularJS) e o novo Google Material Design Lite já trazem toda uma especificação de componentes HTML, classes CSS e funções JavaScript prontas para lidar com o desenvolvimento de todo tipo de página responsiva. Elas permitem ainda que você customize facilmente esse aparato de arquivos usando ferramentas de manipulação dinâmica de CSS (Less ou Sass), JavaScript (jQuery, AngularJS, etc.) e HTML puro, via build automatizado, usando o Grunt, por exemplo.

Todavia, existem várias situações onde o projeto em que você estiver trabalhando exija que o design da aplicação como um todo seja completamente diferente do fornecido por esses frameworks, ou casos em que os componentes das mesmas não sejam suficientes para desenvolver as peculiaridades que seu projeto exige, dentre outros.

Nestes casos, o designer, ou desenvolvedor front-end deve ter embasamento o suficiente para lidar com esse tipo de desenvolvimento, de repente criando seu próprio framework de componentes, classes e funções. E são exatamente estes pontos que esse artigo visa tratar, explorando conceitos como grids, desenvolvimento com Sass, tipografia, dentre outros.

O poder do Sass

Para fins de simplicidade e produtividade, usaremos o Sass para facilitar a implementação do CSS nos exemplos do artigo.

O Sass permite que elementos sejam aninhados para flexibilizar a forma como as regras serão geradas no CSS final. Por exemplo, vejamos o exemplo demonstrado pela Listagem 1.

A primeira parte dela mostra um código CSS feito em Sass que define a forma de exibição de um elemento de classe “barra-navegacao” via display com valor flex (que diz que o conteúdo deve se adaptar às dimensões da tela onde for exibido), bem como o padding dos elementos de lista li que estiverem inseridos dentro do anterior.

Na segunda parte, vemos o resultado da compilação desse Sass, ou seja, o CSS final gerado. Veja como o Sass simplifica a criação de regras de estilo ao evitar que tenhamos de duplicar código sempre que quisermos uma regra em herança.

Listagem 1. Exemplo de conteúdo Sass e CSS gerado.

  // Antes
  .barra-navegacao {
            display: flex;
            li {
                        padding: 5px 10px;
            }
  }
   
  // Depois
  .barra-navegacao {
            display: flex;
  }
  .barra-navegacao li {
            padding: 5px 10px;
  }

O Sass se baseia num conjunto de vários conceitos para implementar CSS, vejamos:

  • Ele pode ser baseado em duas tecnologias diferentes: Ruby ou LibSass (BOX 1). Vamos usar neste artigo o Ruby por questões de simplificação.
  • Ele é um gem no Ruby, isto é, um pacote usado no Ruby.
  • Podemos executá-lo via interface de linha de comando, mas também é possível sua execução via aplicações de terceiros, com a devida importação de suas bibliotecas dependentes.
  • Ele é uma linguagem de scripting convencional, como JavaScript, CoffeeScript, etc.
  • O Sass também contribui para a eliminação das repetições de código quando desenvolvemos CSS puro. Isso se dá por intermédio da sua sintaxe hierárquica que permite o reaproveitamento de regras para os elementos que pertencerem à mesma. Veremos mais detalhes sobre isso na prática adiante.
  • Parte do fluxo de trabalho do Sass é “assistir” a um arquivo de tipo SCSS, por exemplo, estilos.scss. Quando ele detecta uma mudança nesse arquivo, um novo arquivo estilos.css é automaticamente gerado e compilado.

BOX 1. LibSass

É uma versão do Sass que possibilita a integração do mesmo em outras linguagens como C/C++, Lua, Java, .NET, etc.. Veja na seção Links a URL oficial do projeto.

Configurando o Sass

Precisamos de basicamente três passos para ter o Sass instalado:

  1. Baixar e executar o instalador do Ruby.
  2. Abrir um terminal de comandos referente ao seu SO.
  3. Instalar a gem do Sass.

Para verificar se o Ruby já está instalado na sua máquina, digite o seguinte comando no cmd:

ruby -v

Uma mensagem com a versão do mesmo, bem como a data da revision e versão do instalador para o seu SO (32 ou 64 bits) será impressa no console:

ruby 2.1.5p273 (2014-11-13 revision 48405) [x64-mingw32]

Caso o leitor já esteja com uma versão antiga do Ruby instalada é aconselhado remove-la antes de instalar a nova, a fim de evitar problemas de conflito no ambiente. Para o Windows, especificamente, precisamos do RubyInstaller for Windows (vide seção Links).

Quando finalizar o download, execute o arquivo, selecione a língua para o passo a passo da instalação, aceite os termos de licença e, na próxima tela, selecione o diretório onde deseja que os arquivos sejam descompactados, bem como marque as opções mostradas na Figura 1 para que a pasta de binários seja adicionada às variáveis de ambiente e possamos executar comandos no cmd. Clique em Install e aguarde.

No final, antes de executar qualquer comando com o novo Ruby precisamos fechar a janela do terminal e abrir uma nova. Então execute mais uma vez o comando de verificação da versão e veja se a mesma corresponde à versão instalada:

ruby 2.2.3p173 (2015-08-18 revision 51636) [x64-mingw32]
Tela de configuração das opções do Ruby
Figura 1. Tela de configuração das opções do Ruby.

Com o Ruby ok, agora é hora de instalar a gem do Sass no ambiente. Para isso, execute o seguinte comando no terminal:

gem install sass

Aguarde até que o utilitário do gem faça o download completo e execute o comando sass -v para verificar se deu certo. O resultado será algo como:

Sass 3.4.20 (Selective Steve)

Para trabalhar com o Sass, precisamos ter um mínimo de organização de diretórios possível. Portanto, selecione um diretório de sua preferência para o projeto e crie a estrutura de pastas demonstrada na Listagem 2. Veja que temos duas pastas de estilo em detrimento dos arquivos de Sass não compilados, e CSS pós compilados.

Listagem 2. Estrutura de diretórios do projeto.

    +--responsive-web
     +---- html
     +---- img
     +---- js
     +---- style
           +---- css
           +---- scss

Navegue até a pasta /scss e crie um novo arquivo de nome estilos.scss. No terminal cmd, usando o comando cd, navegue até a pasta /style e execute a seguinte instrução:

sass --watch scss:css

Esse comando é responsável por dizer ao Sass que ele deve “assistir” as pastas informadas à frente (scss/css), checando quais arquivos do Sass existem, e gerando automaticamente o arquivo CSS correspondente sempre que alterações forem feitas no de extensão .scss. Salve qualquer conteúdo Sass no arquivo e veja o arquivo .css ser gerado de forma automática na sua respectiva pasta.

Sass vs SCSS

Existem duas sintaxes padrão para escrever código de estilo usando o Sass: a Sass e a SCSS. A primeira foi, por muito tempo, a única forma disponível para tal finalidade, porém era considerada muito diferente do CSS original, aumentando assim a curva de aprendizado na tecnologia, mesmo para quem já tivesse familiaridade com o mesmo.

Vejamos um exemplo bem simples na Listagem 3 que define uma propriedade de float para um seletor a, e uma propriedade de cor (color) da fonte para o mesmo seletor e para um outro seletor b.

A sintaxe Sass se baseia em “espaços em branco” para definir a hierarquia dos elementos do CSS final. Quando criamos o seletor-b com um espaçamento maior que o do seletor-a dizemos ao Sass que a regra se aplica a ambos.

Caso contrário, se o seletor-b estivesse no mesmo nível do seletor-a, teríamos a regra aplicada apenas ao primeiro. O CSS de resultado pode ser visto na mesma listagem.

Veja como o procedimento não é tão intuitivo quanto usar a sintaxe do SCSS, como podemos ver na Listagem 4. Nele temos o uso do novo símbolo &, que nos permite adicionar o nome do seletor pai aos seletores aninhados sem ter de digitar o nome completo.

Em outras palavras, basta mapear o prefixo do seletor e, dentro do mesmo, concatenar cada um dos nomes via operador &; assim, o SCSS fará todo o trabalho de montagem que acabará findando no mesmo resultado do exemplo com Sass.

Listagem 3. Exemplo de CSS gerado a partir de um Sass.

  // Antes
  .seletor-a
     float: left;
   
         .seletor-b
            color: red;
   
  // Depois
  .seletor-a {
     float: left;
  }
  .seletor-a, .seletor-b {
     color: red;
  }
Listagem 4. Exemplo de CSS gerado a partir de um SCSS.

  // Antes
  .seletor- {
     &a {
         float: left;
     }
     &a, &b {
         color: red;
     }
  }
   
  // Depois
  .seletor-a {
     float: left;
  }
  .seletor-a, .seletor-b {
     color: red;
  }

HTML5

A HTML é uma parte essencial de ser assimilada e entendida quando do desenvolvimento de código responsivo. Diante disso, muitas tags padrão da HTML5 que existem para nos auxiliar são simplesmente ignoradas pelos desenvolvedores e designers.

Veja na Tabela 1 algumas delas, suas utilidades e as regras nas quais as mesmas se inserem quando se trata de criar conteúdo responsivo.

Tag

Descrição

Regras

<main>

Pode ser usada como um container para os conteúdos principais do documento. Geralmente está relacionada à marcação de um tópico central de uma seção/funcionalidade da aplicação. Esse conteúdo deve ser único no documento.

  • O conteúdo principal da página deve ser incluído nessa tag.
  • Deve ser exclusivo e único.
  • Essa tag não deve ser inserida nas tags: <header>, <footer>, <nav>, <aside> ou <article>.
  • Deve haver apenas uma dela por página.

<article>

Representa uma composição autocontida num documento, página, aplicação, ou site, que deve ser distribuível ou reusável de forma independente. Pode ser um post de fórum, um artigo de revista ou jornal, uma entrada num blog, ou qualquer outro item independente de conteúdo.

  • Um <article> pode ser aninhado em outros <article>.
  • Pode existir mais de um por página.

<section>

Representa uma seção genérica de um documento, isto é, um agrupamento temático de conteúdo, tipicamente com um cabeçalho. Cada seção deve ser identificada incluindo um cabeçalho (<h1> <h6>) como elemento filho.

  • Um modo seguro de usar uma seção é colocá-la dentro de um elemento <article>. Além disso, é bom sempre colocar um cabeçalho <h1> <h6> em cada uma.
  • Pode existir mais de uma por página.

<aside>

Representa uma seção com conteúdo conectado lateralmente ao corpo da página. O mesmo pode ser considerado separado do resto do conteúdo. Geralmente são representadas como sidebars ou inserts. Bons exemplos de uso dela incluem: biografia de um autor, informações de perfil de usuário, ou links relacionados num blog.

  • Se o conteúdo não se encaixar na tag <main>, ele certamente poderá ser inserido num aside.
  • Pode existir mais de um por página.

<header>

É comum pensar que a seção de topo da nossa página é o header (cabeçalho), e que isso é correto. Entretanto, o nome correto para essa parte do site é masthead, ou seja, o header principal da página, que geralmente contém a logo, alguma navegação, talvez um campo de pesquisa, etc. Já o header pode ser considerado o cabeçalho de qualquer seção, portanto, podemos ter vários deles.

  • Uma boa regra é sempre usar o <header> dentro de uma <section>.
  • Você pode mapear um heading (<h1> <h6>) em um header, mas não é comum, tampouco necessário.
  • Pode existir mais de um por página.

<footer>

Representa o rodapé para a sua seção mais próxima, ou secciona o elemento raiz da página. Tipicamente contém informações sobre autor da seção, dados de copyright, ou links para documentos relacionados.

  • Deve sempre conter informações sobre o elemento pai que o contém.
  • Apesar do nome “footer” se referir à parte de baixo de uma página, artigo ou aplicação, esse elemento não necessariamente tem que estar nesta parte.
  • Pode ter mais de um por página.

<nav>

  • Representa uma seção da página que conecta a outras páginas ou a outras partes da mesma página: uma seção com links de navegação, por exemplo.
  • Deve ser usada para agrupar uma lista ou coleção de links, externos ou internos.
  • É uma prática comum usar listas não-ordenadas (<ul>) dentro desse elemento para melhor estruturar os links, já que é mais simples para o design.
  • Também é comum incluir essa tag em um elemento <header>, mas não é requerido.
  • Nem todos os links são requeridos de estar dentro desse elemento. Por exemplo, se tivermos links no rodapé, não é preciso inserir uma <nav> dentro do <footer>.
  • Pode existir mais de um por página.
Tabela 1. Lista de tags usadas para incutir responsividade.

Outro conceito importante para a definição de uma correta responsividade nas páginas HTML é o de roles do WAI-ARIA (Web Accessibility Initiative – Accessible Rich Internet Applications), um padrão internacional que visa implementar práticas de acessibilidade nas aplicações ricas da web.

As suas roles (ou regras), também chamadas de ARIA roles, servem para definir determinados comportamentos às páginas, através de tipos pré-definidos. Vejamos um exemplo simples disso:

<header role=’banner’>

Existem muitos tipos diferentes de roles que podem ser implementadas, mas vamos focar apenas nas mais importantes para o conceito acessibilidade responsiva. A Tabela 2 ilustra esta relação, com suas respectivas características.

Role

Descrição

banner

  • É usualmente aplicada à tag <header> do topo da página.
  • Geralmente, o conteúdo que tem um role="banner" aparece constantemente ao longo do site, em vez de apenas em uma página específica.
  • Apenas uma é permitida por página.

navigation

  • É usualmente aplicada ao elemento <nav>, mas pode também ser aplicada a outros containers como <div> ou <ol>.
  • Descreve um grupo de elementos/links navegáveis (internos ou externos).
  • Pode ter mais de um na página.

main

  • É usualmente aplicada ao elemento <main> da página.
  • O container principal/central da página deve ser marcado com essa role.
  • Apenas uma é permitida por página.

contentinfo

  • É usualmente aplicada ao elemento <footer> da página.
  • É a seção que contém informações sobre o documento/site/app.
  • Apenas uma é permitida por página.

search

  • É usualmente aplicada ao elemento <form> que pertence à funcionalidade de busca da página.
  • Se o elemento <form> estiver mapeado dentro de uma <div>, essa role também pode ser aplicada à mesma. Se for o caso, não há necessidade de adicionar a role ao form novamente.
  • Pode haver mais de uma por página.

form

  • É usualmente aplicada ao elemento <div> que contém algum tipo de formulário, exceto o de search que acabamos de ver.
  • Não deve ser aplicada ao elemento de <form> atual, porque o mesmo já tem uma semântica de role padrão que suporta essa tecnologia.

complementary

  • É usualmente aplicada ao elemento <aside>.
  • Deve ser usada em uma região que contém suporte a conteúdo.
  • Pode haver mais de uma por página.
Tabela 2. Lista de roles usadas pela WAI-ARIA.

Meta tags

As meta tags são estruturas importantes, principalmente no SEO, para marcar coisas como autoria das páginas, versionamento, se a página é responsiva ou não, bem como enviar certos comandos aos navegadores que identificam o conteúdo e melhoram a exibição do HTML. Veja na Tabela 3 uma relação das tags (e suas descrições) mais importantes para implementar design responsivo nas páginas web.

Meta Tag

Exemplo

Descrição

viewport

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

  • É a meta tag mais importante para o design responsivo.
  • A diretiva “viewport” descreve o tipo de meta tag.
  • A propriedade “width” define o tamanho do viewport. O valor “device-width” diz ao browser para ocupar todo o espaço da tela na largura. Também pode ser informado um valor em pixels.
  • A propriedade “initial-scale” define o nível de zoom sob o qual a página deve ser exibida. 1 é igual a 100% de zoom e 1.5 igual a 150%, por exemplo.

X-UA-Compatible

<meta http-equiv="X-UA-Compatible" content="IE=edge">

  • Visa estabelecer compatibilidade com o Internet Explorer, por isso é aplicada apenas a esse navegador.
  • A diretiva “http-equiv” diz ao IE que uma certa engine de renderização precisa ser usada para carregar a página.
  • A diretiva “contente” diz ao IE que ele deve usar suas engines de HTML e JavaScript mais recentes.

charset

<meta charset="utf-8">

  • Essa é talvez a mais conhecida pelos desenvolvedores, já que se não inserida na página, os caracteres especiais e acentos gráficos aparecerão distorcidos.
  • Ela diz ao browser que conjunto de caracteres deve ser uso para interpretar o conteúdo.
  • Outro valor muito comum é “ISSO-8859-1”, mas o UTF-8 é mais aconselhado pois há mais chances de o seu browser o interpretar.
Tabela 3. Lista de meta tags usadas para incutir responsividade.

Exemplo prático

Para exemplificar os conceitos até aqui expostos, vamos implementar uma página inteiramente responsiva, com a inclusão de código HTML5 organizado com base nas tags que explanamos, bem como estilo definido pelo documento Sass criado. Trata-se de uma página em formato de site convencional, com um cabeçalho (e barra de navegação, menus, caixa de pesquisa), conteúdo principal (com um artigo, cabeçalho interno, formulário de contato) e um rodapé (com copyright e links de rodapé).

Comecemos então pelo cabeçalho da página. Crie um novo arquivo HTML de nome index.html no diretório raiz do projeto e insira ao mesmo o código da Listagem 5.

Ela traz apenas uma implementação simples da tag <head> da página HTML, com as respectivas meta tags que citamos e foram antes inseridas, um título (tag <title>) e o arquivo de estilo CSS que criamos sendo importado.

Ainda precisamos criar o conteúdo deste último. Observe também que, em vez das convencionais tags <div> usadas para dividir as seções das páginas, estamos usando a tag <header> dentro do corpo HTML para demarcar o cabeçalho único e principal do site. Demos a ele uma classe CSS de nome “masthead” e a role de “banner”, já que será único também.

Dentro do header temos duas div: a primeira contém o título do cabeçalho propriamente dito e a segunda guarda o formulário de pesquisa que, por sua vez, contém a role de “search” (única por página). Para todos os campos de texto da página daremos a classe CSS “field” para padronizar no Sass.

Listagem 5. Cabeçalho HTML da nossa página do site.

  <!DOCTYPE html>
  <html>
   
  <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Design Resopnsivo com HTML5 & CSS3</title>
      <link rel="stylesheet" href="style/css/estilos.css">
  </head>
   
  <body>
      <header class="masthead" role="banner">
          <div class="logo">Design Responsivo com HTML5 & CSS3</div>
          <div class="search" role="search">
              <form>
                  <label>Busca:
                      <input type="text" class="field">
                      <button>Buscar Agora!</button>
                  </label>
              </form>
          </div>
      </header>
         
         <!-- Restante do conteúdo -->
         
  </body>
   
  </html>

Com o HTML pronto precisamos agora criar o conteúdo Sass para lidar com o design inicial da página. Comecemos então pelo Sass de propriedades globais, tais como cor do plano de fundo, logo, cabeçalho e alguns atributos globais que serão comuns a todos os elementos da página. Insira o código da Listagem 6 no arquivo estilos.scss.

Veja que no início dela criamos algumas declarações globais. No Sass é possível declarar variáveis, tal como fazemos nas linguagens de programação como JavaScript, por exemplo, e usar seus valores em todo o restante do código. Isso facilita a padronização uma vez que não precisamos repetir a cor da fonte, por exemplo, para toda nova regra CSS criada.

As cores abrangem o plano de fundo, fontes, cabeçalhos, etc. Em seguida, definimos uma função mixin (vide BOX 2) do Sass de nome paraTelasPequenas(), a qual será responsável por traduzir as regras criadas mais abaixo para dispositivos pequenos, por isso a divisão por 16+em no atributo @media. Lembre-se que este atributo é responsável por delimitar o tamanho das telas onde certas regras CSS devem se aplicar. Em seguida, dividimos o restante das regras em algumas subcategorias, a saber:

  • Regras globais: definem propriedades comuns do CSS para fonte do texto, cor de fundo (via variável do Sass, &bg), cor dos cabeçalhos <h1> <h6> e estilo dos blockquote (neste último, chamamos o mixin pela primeira vez, passando uma regra específica para telas de até 420px).
  • Header: definimos o estilo do cabeçalho, que deve estar alinhado ao centro com seus elementos também centralizados, uma logo (somente texto) e cor de fundo (note que estamos usando o mesmo estilo do portal da DevMedia).
  • Placeholder: essa é a primeira herança no Sass que usamos. Esse elemento contém regras CSS universais que todos os elementos de seção também terão. Dessa forma, eles só precisam estender do placeholder e as mesmas regras serão aplicadas.
  • Campo de busca: logo na classe “search” já herdamos do placeholder que criamos. O restante das configurações é intuitivo.
  • Formulários: regras básicas para que o formulário ocupe 100% do espaço disponível.
  • Elementos de formulário: configura o estilo para os campos de input, textarea e botões (repare que para este último definimos seu estilo separadamente, e não dentro de cada regra que tenha um botão qualquer, deixando o mesmo universal).

Como o “watcher” do Sass já foi ativado, basta salvar a página HTML e abri-la em um navegador web. O resultado da página em um browser desktop pode ser visto na Figura 2, enquanto a visualização em dispositivos menores se encontra na Figura 3.

Listagem 6. Código de SCSS global do Sass.

  //// Declarações Customizadas
     // Cores
     $bk: #272822;
     $r: #c03;
     $g: #429032;
     $b: #8cc53e;
     $y: #49c5bf;
     $bg: #f4f4f4;
   
  // Media Query Mixin - Desktop-first
  @mixin paraTelasPequenas($media) {
     @media (max-width: $media/16+em) { @content; }
  }
   
  //Globais
  *,
  *:before,
  *:after {
     box-sizing: border-box;
  }
   
  body {
     font-family: "Segoe UI", Arial, "Helvetica Neue", Helvetica, sans-serif;
     background-color: $bg;
  }
   
  h1, h2 {
     color: white;
  }
   
  blockquote {
     font-style: italic;
     @include paraTelasPequenas(420) {
        margin-left: 10px;
     }
  }
   
  // Header
  .masthead {
     display: flex;
     justify-content: space-between;
     max-width: 980px;
     margin: auto;
     padding: 10px;
     background: $b;   
     @include paraTelasPequenas(700) {
        display: block;
        text-align: center;
     }
  }
   
  .logo {
     padding: 10px 0 10px 10px;
     color: white;
     line-height: 1.5;
     font-size: 1.3em;
     @include paraTelasPequenas(700) {
        padding: 10px 0;
        font-size: 1.5em;
     }
     @include paraTelasPequenas(420) {
        font-size: 1.1em;
     }
  }
   
  //Placeholder
  %highlight-section {
     /*border: white 1px solid;
     border-radius: 3px;
     background: rgba(white, .1);*/
     background: rgba(black,.2);
     border-radius: 3px;
  }
   
   
  // Campo de busca
  .search {
     @extend %highlight-section;
     display: flex;
     align-items: center;
     justify-content: center;
     text-align: center;   
     color: white;
     font-size: .9em;
     padding: 10px;
     .field {
        width: 50%;
        margin: 0 5px;
        padding: 7px;
        @include paraTelasPequenas(420) {
           width: 70%;
        }
     }
     button {  
        @include paraTelasPequenas(420) {
           width: 90%;
           margin-top: 10px;         
        }
     }
  }
   
  // Formulários
  .field,
  .comments {
     width: 100%;
     margin-bottom: 10px;
     
     @include paraTelasPequenas(420) {
        width: 100%;
     }
  }
   
  // Elementos de formulário
  input, textarea {
     font-family: "Segoe UI", Arial, "Helvetica Neue", Helvetica, sans-serif;
     padding: 10px;
     border: none;
     background: rgba(white,.8);
     border-radius: 2px;
     box-shadow: inset 0 1px 1px rgba(black,.5);
  }
   
  button {
     border: none;
     padding: 7px 10px;
     background: #333;
     border-radius: 3px;
     color: white;
     font-family: "Segoe UI", Arial, "Helvetica Neue", Helvetica, sans-serif;
     cursor: pointer;
  }

BOX 2. Mixins

Um mixin é uma diretiva que permite a definição de múltiplas regras que serão traduzidas para o CSS dependendo dos argumentos enviados dinamicamente por parâmetro. Pense num mixin como uma função que permite reusar estilo ao longo da folha de estilos sem precisar recorrer a recursos estáticos do CSS em si.

Tela com cabeçalho responsivo
Figura 2. Tela com cabeçalho responsivo.
Tela com cabeçalho responsivo em dispositivo
pequeno
Figura 3. Tela com cabeçalho responsivo em dispositivo pequeno.

Vamos incluir agora o restante do conteúdo HTML da página, que se divide entre barra de navegação (<nav>), corpo da página (<main>) e rodapé (<footer>). Logo, inclua o conteúdo da Listagem 7 após a declaração do cabeçalho recém-criado. Nela, podemos perceber a inclusão das seguintes tags principais:

  • nav: cria a barra de navegação com uma lista não ordenada HTML e, dentro de cada item, um link para cada opção de menu. Note que também estamos usando a role de “navigation” que debatemos antes.
  • main: guarda todo o conteúdo principal da página (com a role de “main”), que inclui desde o título e subtítulo do post (já que simula a exibição de um artigo – article) e a tag <article> com o texto do post (no qual também inserimos um <aside> com role “complementary” para complementar o conteúdo do post).
  • form: está inserido dentro do main, mas traz configurações específicas do formulário de contato (role “form”), com uma segunda tag <header> (dessa vez interna a uma seção), bem como os campos de input, textarea e botão de submit.
  • footer: através da role “contentinfo”, o rodapé traz apenas um texto de copyright e mais uma lista de links de menu tal como tivemos no header.
Listagem 7. Restante do código HTML de navegação, corpo e rodapé.

    <nav class="main-nav" role="navigation">
         <ul class="nav-container">
               <li><a href="#">Link 1</a></li>
               <li><a href="#">Link 2</a></li>
               <li><a href="#">Link 3</a></li>
               <li><a href="#">Link 4</a></li>
         </ul>
  </nav>
  <main class="main-container" role="main">
         <h1>Criando conteúdo em HTML5</h1>
         <p>HTML5 é uma linguagem de marcação de hipertexto, muito utilizada na web...</p>
         <article class="article-container flex-container">
               <section class="main-content">
                      <header>
                             <h1>O elemento <code><main></code></h1>
                      </header>
                      <p>Por definição:</p>
                      <blockquote>
                             <p>O Elemento (<code><main></code>) representa…
                             </p>
                      </blockquote>
               </section>
               <aside class="side-content" role="complementary">
                      <h2>Quer se tornar um programador?</h2>
                      <p>Provavelmente você terá um longo caminho, mas pode fazer uso do nosso conteúdo para te ajudar.</p>
               </aside>
         </article>
         <div class="contact-form" role="form">
               <header>
                      <h2>Mande-nos sua sugestão/dúvida/questão</h2>
               </header>
               <form>
                      <div class="flex-container">
                             <label class="label-col">Nome:
                                    <input type="text" class="field name" id="nome" required>
                             </label>
                             <label class="label-col">Email:
                                    <input type="email" class="field email" id="email" required>
                             </label>
                      </div>
                      <label for="comentario">Comentário:</label>
   
                      <textarea class="comments" id="comentario" cols="50" required></textarea>
                      <button>Enviar</button>
               </form>
         </div>
         <footer class="main-footer" role="contentinfo">
               <p>Copyright © 2015 | Todos os direitos reservados. </p>
               <ul class="nav-container" role="navigation">
                      <li><a href="#">Rodapé Link 1</a></li>
                      <li><a href="#">Rodapé Link 2</a></li>
                      <li><a href="#">Rodapé Link 3</a></li>
                      <li><a href="#">Rodapé Link 4</a></li>
                      <li><a href="#">Rodapé Link 5</a></li>
               </ul>
         </footer>
  </main>

Agora precisamos criar as regras Sass para lidar com o estilo dos novos componentes. Como se trata de muito conteúdo, vamos dividir em duas partes: Listagens 8 e 9. Na primeira temos as definições divididas da seguinte forma:

  • Navegação: mapeia o CSS para a tag <nav> definindo o tamanho máximo de largura, cor de plano de fundo (veja que nesta usamos o valor hexadecimal da cor inline, isto é, direto no código) e exibição da seção usando o recurso do FlexBox (essa propriedade é nova no CSS3 e especifica o tamanho do item relativo ao resto dos itens de igual modo flexíveis que estejam dentro do mesmo container. Outro destaque se reflete na função rgba() do Sass definida nas propriedades box-shadow e border-bottom do link (<a>). Essa função recebe quatro argumentos: as cores red, green e blue da cor em si, e o fator alpha, que representa o nível de opacidade aplicado ao campo (valor deve estar entre 0 e 1).
  • Container principal: define propriedades gerais para o corpo da página. Veja que aqui fazemos uso da variável global &y criada no início do arquivo para configurar a cor da border-bottom do mesmo. Destaque para o elemento <h1> que recebe suas propriedades de estilo, aplicando-as a todos os h1’s da página. Isso se dá através do código &>h1 (o caractere & quer dizer “todo o documento” no Sass).
  • Article: configura as propriedades do artigo que incluem margem, cor de fundo, padding e bordas.
Listagem 8. Código Sass para navegação, corpo e artigo.

  // Navegação
  .main-nav {
     max-width: 980px;
     margin: auto;
     padding: 10px 5px;
     border-bottom: rgba(black,.2) 1px solid;
     background: #49c5bf;
     @include paraTelasPequenas(420) {
        padding: 5px 0;
     }
  }
   
  // Todas as navegações
  .nav-container {
     display: flex;
     justify-content: center;
     list-style-type: none;
     margin: 0;
     padding: 0;
     @include paraTelasPequenas(420) {
        flex-wrap: wrap;
     }
     li {
        display: flex;      
        width: 100%;
        margin: 0 5px;
        text-align: center;
        @include paraTelasPequenas(420) {
           display: flex;
           justify-content: center;
           flex-basis: 45%;
           margin: 5px;
        }
     }
     a {
        @extend %highlight-section;
        display: flex;
        justify-content: center;
        align-items: center;
        width: 100%;
        padding: 10px;
        color: white;
        text-decoration: none;
        font-size: 1.3em;
        box-shadow: inset 0 1px 2px rgba(black,.2);
        border-bottom: rgba(white,.6) 1px solid;      
     }
  }
   
  // Container Principal
  .main-container {
     max-width: 980px;
     margin: auto;
     padding: 40px 40px 20px;
     background: #2a2a2a;
     color: rgba(white,.8);
     border-bottom: $y 40px solid;
     @include paraTelasPequenas(420) {
        padding: 20px;
        line-height: 1.5;
     }
     //Main Headings
     &>h1 {
        margin-top: 0;
        padding-bottom: 10px;
        border-bottom: $y 3px solid;
        @include paraTelasPequenas(420) {
           font-size: 1.6em;
        }
     }
  }
   
  // Article
  .article-container {
     margin-bottom: 20px;
     padding: 10px;
     background: rgba(white,.05);  
     border-radius: 2px;
     border: rgba(black,.2) 10px solid;
     box-shadow: 0 5px 15px rgba(black,.3);
  }
   
  // Conteúdo principal da página
  .main-content {
    width: 75%;
    margin-right: 10px;
    padding: 10px;      
    @include paraTelasPequenas(600) {
          width: 100%;
    }
    h1 {
          margin: 0;
          padding-bottom: 10px;
          border-bottom: $g 3px solid;
    }
  }

Para a segunda listagem certifique-se de incluir seu conteúdo no final do arquivo estilos.scss. Nela podemos ver recursos gerais para os demais componentes da página, a saber:

  • Conteúdo lateral: configura o estilo dos títulos de cabeçalho, links, listas ordenas e parágrafo que possam existir no corpo do post.
  • Formulário de Contato: cria uma espécie de delimitação ao redor da div de formulário, configurando propriedades de estilo específicas para os campos de botão, labels, input, textarea desse formulário. Estas sobrescreverão as demais criadas antes para campos de formulário.
  • Rodapé: faz uso das variáveis de cores declaradas no início do arquivo para dar cor à borda, ao texto, bem como define o espaçamento padrão do texto.
Listagem 9. Código Sass para conteúdo lateral, formulário de contato e rodapé.

  // Conteúdo lateral
  .side-content {
    width: 25%;
    padding: 10px;
    font-size: .8em;
    border: $b 2px dotted;
    border-left: none;
    border-right: none;
    @include paraTelasPequenas(600) {
          width: 100%;
          margin-top: 12px;
    }
    h2 {
          margin: 0;
    }
    ol {
          padding-left: 20px;
    }
    a {
          color: #eee;
    }
    p {
          @include paraTelasPequenas(420) {
               font-size: 1.2em;
          }
    }
  }
   
  // Formulário de Contato
  .contact-form {
     width: 540px;
     margin: 40px auto;
     padding: 20px;
     border: rgba(black,.2) 10px solid;
     box-shadow: 0 5px 15px rgba(black,.3);
     @include paraTelasPequenas(600) {
        width: 100%;
     }
     h2 {
        margin-top:0;
        padding-bottom: 10px;
        border-bottom: $r 3px solid;
     }
     label, button {
        display: block;      
     }
     input, textarea {
        margin-top: 5px;
     }
     .comments {
        height: 100px;
     }
     button {
        font-size: 1.3em;
        background: $b;
        @include paraTelasPequenas(420) {
           width: 100%;
        }
     }
     .flex-container {
        justify-content: space-between;
        @include paraTelasPequenas(600) {
           display: flex;
        }
        @include paraTelasPequenas(400) {
           display: block;
        }
     }
     .label-col {
        width: 48%;
        @include paraTelasPequenas(400) {
           width: 100%;
        }
     }
  }
   
   
  // Rodapé
  .main-footer {
     color: white;
     padding: 10px;
     border-top: $y 2px dotted;
     font-size: .7em;
     p {
        margin-top: 0;
        font-size: 1.2em;
     }
  }
   
  // Classes utilitárias
  .flex-container {
     display: flex;
     @include paraTelasPequenas(600) {
        display: block;
     }
  }

Após isso, o leitor já pode salvar todos os documentos e verificar o resultado no browser. Na Figura 4 temos o resultado do site num navegador em modo desktop, e na Figura 5 a mesma página visualizada a partir de um iPhone 6 Plus. Veja como os elementos se rearranjam em detrimento da diminuição de espaço disponível.

tela final visualizada de um browser desktop
Figura 4. Tela final visualizada de um browser desktop.
Tela final visualizada de um iPhone 6 Plus
Figura 5. Tela final visualizada de um iPhone 6 Plus.

Grids CSS

Uma grid é um conjunto de guias visuais (verticais, horizontais ou ambas) que ajudam a definir onde os elementos podem ser alocados. Uma vez que eles tenham sido alocados, alcançamos o conceito de layout. Uma das maiores vantagens de usar grids é que seus elementos internos terão um fluxo harmonioso ao longo das páginas, incrementando a experiência do usuário em termos de legibilidade, consistência de layout e boas proporções entre os elementos.

Muitos frameworks de componentes já usam esse conceito, como o Bootstrap por exemplo, que mantém o container com uma largura de no máximo 980px, e divide seu espaço interno em até doze divs menores de tamanhos variados.

O conceito se baseia em definir para cada grid as “linhas” (rows) que, por sua vez, serão constituídas de colunas (columns) em quantidade máxima de 12. Vejamos o exemplo exposto pela Listagem 10. No início dela configuramos as propriedades de box-sizing para definir uma borda padrão ao documento como um todo.

A classe “container-12” deve ser a primeira e mais ao topo da div que vai conter todo o conteúdo principal. Veja que definimos sua largura fixa em 980px (se o leitor não quiser fazer uso do @media para quando esta classe for executada em dispositivos menores pode definir essa largura como máxima permitida - “max-width” – e a largura em si (“width”) com o valor de 100%).

Em seguida, fazemos uso do Sass para imprimir o float à esquerda e uma margem para todas as classes de grid, da 1 até a 12. Note que cada grid tem seu valor prefixado de acordo com as dimensões de tamanho máximo da página (de 60px – valor mínimo – até 940px – valor máximo).

Listagem 10. Código de exemplo para sistema de grids.

  *,
  *:before,
  *:after {
      box-sizing: border-box;
  }
  // Container
  .container-12 {
      width: 980px;
      padding: 0 10px;
      margin: auto;
  }
  // Grid >> Global
  .grid {
      &-1, &-2, &-3, &-4, &-5, &-6, &-7, &-8, &-9, &-10, &-11, &-12 {
          float: left;
          margin: 0 10px;
      }
  }
  // Grid >> 12 colunas
  .container-12 {
      .grid-1 {
          width: 60px;
      }
      .grid-2 {
          width: 140px;
      }
      .grid-3 {
          width: 220px;
      }
      .grid-4 {
          width: 300px;
      }
      .grid-5 {
          width: 380px;
      }
      .grid-6 {
          width: 460px;
      }
      .grid-7 {
          width: 540px;
      }
      .grid-8 {
          width: 620px;
      }
      .grid-9 {
          width: 700px;
      }
      .grid-10 {
          width: 780px;
      }
      .grid-11 {
          width: 860px;
      }
      .grid-12 {
          width: 940px;
      }
  }
  // Limpa elementos formatados - http://davidwalsh.name/css-clear-fix
  .clear,
  .row {
      &:before, &:after {
          content: '';
          display: table;
      }
      &:after {
          clear: both;
      }
  }
  // Usa linhas para aninhar os containers
  .row {
      margin-bottom: 10px;
      &:last-of-type {
          margin-bottom: 0;
      }
  }
  // Legado IE
  .clear {
      zoom: 1;
  }

Além dessa configuração feita fixamente em pixels, podemos implementar o modelo todo baseado em percentagem. Para isso, precisamos nos assegurar que a largura máxima do container também esteja em percentagem, bem como as linhas e as demais divisórias do documento. Veja na Listagem 11 como ficaria o mesmo código com as alterações percentuais.

Para calcular esses valores, o leitor pode fazer uso de uma fórmula bem simples: (alvo / contexto) x 100 = resultado%. No nosso exemplo, o alvo seria o valor de cada propriedade em pixels e o contexto seria o valor máximo de largura, ou seja, 980px.

Listagem 11. Código de exemplo para sistema de grids com percentual.

  // Container
  .container-12 {
      width: 100%;
      max-width: 980px;
      padding: 0 1.02%;
      margin: auto;
  }
  // Grid >> Global
  .grid {
      &-1, &-2, &-3, &-4, &-5, &-6, &-7, &-8, &-9, &-10, &-11, &-12 {
          float: left;
          margin: 0 1.02%;
      }
  }
  // Grid >> 12 colunas
  .container-12 {
      .grid-1 {
          width: 6.12%;
      }
      .grid-2 {
          width: 14.29%;
      }
      .grid-3 {
          width: 22.45%;
      }
      .grid-4 {
          width: 30.61%;
      }
      .grid-5 {
          width: 38.78%;
      }
      .grid-6 {
          width: 46.94%;
      }
      .grid-7 {
          width: 55.10%;
      }
      .grid-8 {
          width: 63.27%;
      }
      .grid-9 {
          width: 71.43%;
      }
      .grid-10 {
          width: 79.59%;
      }
      .grid-11 {
          width: 87.76%;
      }
      .grid-12 {
          width: 95.92%;
      }
  }
  // Limpa elementos de float - http://davidwalsh.name/css-clear-fix
  .clear,
  .row {
      &:before, &:after {
          content: '';
          display: table;
      }
      &:after {
          clear: both;
      }
  }
  // Usa linhas para aninhar os containers
  .row {
      margin-bottom: 10px;
      &:last-of-type {
          margin-bottom: 0;
      }
  }
  // Legado IE
  .clear {
      zoom: 1;
  }

Tipografia

A tipografia (seleção de fontes) de um site é uma das partes mais importantes da definição responsiva de um design, já que precisamos também considerar como nossos textos, títulos, subtítulos, etc. irão se comportar em diferentes cenários. Dentro dessa questão, muitas perguntas surgem como “deve-se usar pixels, ems, ou rems? ”, “que scale devo aplicar? ” ou “qual a melhor fonte para cada seção?”.

Dentre outras decisões importantes, a definição do tamanho base da fonte, bem como seu ratio precisam ser tomadas no início da criação da página, para se certificar de que as demais sigam o mesmo ritmo.

Na seção Links você encontra a URL para o site Modular Scale, uma ferramenta poderosa para a definição de ratios e bases do texto com visualização em tempo real e geração de conteúdo em CSS, Sass ou JavaScript.

Veja na Figura 7 um exemplo de definição na página. Nele selecionamos dois valores padrão para a base, em pixels, e clicamos no botão Table que mostra uma relação dos valores de fonte em pixels (primeira coluna), ems (segunda coluna) e o possível valor se o tamanho fosse 16px.

O leitor pode ir aumentando ou diminuindo tais valores e ver como o texto se comporta até que tenha uma definição final de qual usará. O mesmo vale para o ratio.

Definindo scales para fontes
na Modular Scale
Figura 6. Definindo scales para fontes na Modular Scale.

Na Listagem 12 temos um exemplo de página HTML gerada com alguns cabeçalhos de título (<h1> <h6>) para que possamos entender a aplicação dos valores base/ratio.

Veja que criamos um segundo arquivo de estilo SCSS para garantir que as regras não se misturem com as definidas no primeiro exemplo.

Na Listagem 13 você encontra o código Sass para aplicar o estilo desejado aos referidos componentes. Note que implementamos o mesmo conceito de função mixin para receber o valor e converter as fontes para telas maiores.

No estilo do body definimos a base da fonte como 16px e o ratio como 1.4, e nos cabeçalhos de títulos os valores proporcionais apontados pela Modular Scale. O resultado final pode ser visualizado na Figura 7.

Listagem 12. HTML para aplicação de base/ratio na fonte.

  <!DOCTYPE html>
  <html>
   
  <head>
      <meta charset="utf-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Design Responsivo com HTML5 & CSS3</title>
      <link rel="stylesheet" href="style/css/estilos2.css">
  </head>
   
  <body>
      <h1>Exemplo de tipografia para Design Responsivo</h1>
      <blockquote>
          <p>"Você não pode juntar os pontos olhando para frente; você pode conectá-los apenas olhando para trás. Então, você deve confiar que os pontos vão se conectar de alguma forma no seu futuro. Você precisa confiar em alguma coisa — nos seus colhões, destino, vida, carma, qualquer coisa. Essa abordagem nunca me deixou para baixo e fez toda a diferença na minha vida."</p>
          <p>— Steve Jobs</p>
      </blockquote>
      <h2>Typografia - Fonte H2</h2>
      <p>Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...</p>
      <h3>Exemplo H3</h3>
      <p>Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit...</p>
  </body>
   
  </html>
Listagem 13. Código Sass para aplicar base/ratio nos títulos.

  //Mobile-first Media Query Mixin
  @mixin paraTelasGrandes($media) {
      @media (min-width: $media/16+em) {
          @content;
      }
  }
  body {
      font: 16px/1.4 Open Sans, Arial, "Helvetica Neue", Helvetica, sans-serif;
      @include paraTelasGrandes(640) {
          font-size: 20px;
      }
  }
  h1 {
      font-size: 2.454em;
  }
  h2 {
      font-size: 1.618em;
  }
  h3 {
      font-size: 1.517em;
  }
Tela com tipografia aplicada
via Modular Scale
Figura 7. Tela com tipografia aplicada via Modular Scale.

Definir um design responsivo é tarefa custosa e muitas vezes envolve vários riscos como a falta de maturidade dos profissionais envolvidos em sua construção<, falta de tempo e organização para definir os escopos, falta de conhecimento sobre que tipos de websites receberão aquele estilo, bem como o não entendimento da quantidade de mudanças que esse mesmo site irá sofrer com o decorrer do tempo.

Todas estas variáveis devem ser sempre levadas em consideração na hora de implementar um design responsivo, principalmente se o mesmo for servir como framework base para futuros sites/sistemas. Outro enfoque importante nessa abordagem é o SEO.

Um bom design quase sempre implica em melhorias no SEO de uma página. Todavia, se o designer/desenvolvedor não tiver experiência o suficiente para escolher os passos certos, o CSS final poderá ficar gigante e não performático.

Em relação às bibliotecas de terceiros (third parties) é preciso ter muito cuidado com seu uso. Por um lado, elas podem acrescentar em muito ao design e facilitar certas tarefas que demorariam muito se feitas manualmente, entretanto, por outro, podem importar uma carga muito alta de código que, em sua grande maioria, não será usada, logo, perdemos em performance mais uma vez.

Tudo é uma questão de conhecimento da biblioteca e da existência de outras substitutas que possam fornecer o mesmo resultado, com melhor produtividade e usando mais recursos da mesma. O único jeito de alcançar isso é experienciando.


Links

Confira também