Uma Grade Simples, Ainda Melhor Com Sass
() translation by (you can also view the original English article)
Nesse tutorial, construiremos um sistema de grades (grids) simples, porém responsivo, usando CSS. Uma vez que estejamos familiarizados com suas funcionalidades, aprimoraremos ele utilizando Sass, enquanto aprenderemos algumas das funcionalidades padrão do Sass.
Iniciando Com o CSS
Vejamos como nosso sistema de grades ficará. Há maneiras mais interessantes de se construir grades, inclusive, algumas são menos intrusivas e requerem menos código. Contudo, essa grade nos possibilita práticar as várias técnicas simples, porém bastante úteis, do Sass. A grade usa um elemento recipiente, com elementos internos que agem como linhas que, por sua vez, tem elementos internos que agem como colunas.



Grid.css
Para começar, tudo que precisaremos é de um arquivo CSS, então crie um novo documento no seu editor preferido e chame-o de "grid.css".
A primeira coisa que adicionaremos será um reconfigurador global (css reset) e a regra de box-sizing
. Isso garantirá que o espaçamento interno (padding) aplicado ao nosso elemento seja considerado no cálculo de suas dimensões, dando-nos muito mais liberdade para definir a largura das colunas.
1 |
*,
|
2 |
*:after, |
3 |
*:before { |
4 |
margin: 0; |
5 |
padding: 0; |
6 |
-webkit-box-sizing: border-box; |
7 |
-moz-box-sizing: border-box; |
8 |
box-sizing: border-box; |
9 |
}
|
O próximo passo é adicionar a regra que faz com que as imagens se comportem fluidamente.
1 |
img { |
2 |
width: auto; |
3 |
max-width: 100%; |
4 |
height: auto !important; |
5 |
}
|
O Recipiente
Agora, criaremos algumas regras para fazer com que nosso recipiente se comporte.
1 |
.wrapper { |
2 |
width: 100%; |
3 |
margin: 0 auto; |
4 |
}
|
Nota: Tenha em mente que trabalharemos levando em conta os dispositivos móveis em primeiro lugar. Nosso recipiente começa com largura de 100% da área de visualização, mas alteraremos isso para telas maiores.
As Linhas
Nossos elementos de linha servirão apenas para conter as colunas, garantindo que os grupos de colunas estejam bem ajustadas. Adicionaremos algumas regras gerais de .clearfix
aos nossos elementos recipiente e às linhas.
1 |
.wrapper:after, |
2 |
.row:after { |
3 |
content: ""; |
4 |
display: table; |
5 |
clear: both; |
6 |
}
|
Nota: Não precisamos nomear esse elementos como .wrapper
, .row
e .column
, podemos ser muito mais criativos que isso. Esses nomes são usados, simplesmente, para facilitar esse tutorial.
As Colunas
Teremos um conjunto vasto de classes de colunas, dependendo do tamanho de cada um (por exemplo .column-1
e .column-6
). Usemos um seletor de atributos para selecionar e estilizar todas essas classes de uma só vez.
1 |
[class*='column-'] { |
2 |
float: left; |
3 |
padding: 1em; |
4 |
width: 100%; |
5 |
min-height: 1px; |
6 |
}
|
Esse seletor diz: pegue todos os elementos que contenham uma classe iniciada com column-
e aplique os estilos a seguir. Dessa forma, todos os elementos colunares flutuarão para a esquerda, terão espaçamento interno de 1em
(isso dá um espaçamento horizontal e vertical interessante) e preencherá 100% da largura da área de visualização (lembre-se, dispositivos móveis em primeiro lugar). Por último, a propriedade min-height: 1px
garante que a coluna se mostre apropriadamente, mesmo que não tenha conteúdo.
Acredite ou não, já temos uma grade! O código HTML abaixo é tudo que precisamos.
1 |
<section class="wrapper"> |
2 |
|
3 |
<div class="row"> |
4 |
|
5 |
<div class="column-3"></div> |
6 |
<div class="column-3"></div> |
7 |
<div class="column-6"></div> |
8 |
|
9 |
</div>
|
10 |
|
11 |
</section>
|
Podemos usar qualquer combinação de colunas dentro das linhas, veja a demonstração para ver o que já temos.



Hora do Responsivo
A parte para dispositivos móveis está pronta, é hora de adicionar as media queries para gerar layouts diferentes para telas maiores. Você terá de determinar os pontos de quebra para sua própria grade, mas usaremos um ponto de quebra arbitrário de 30em
.
1 |
@media only screen and (min-width: 30em) { |
2 |
|
3 |
}
|
Quaisquer estilos que colocarmos dentro da media query afetarão telas com largura de 30em
ou mais. Nós usaremos esse ponto para começar a dar as larguras corretas de nossas colunas.
Larguras em %
O quão larga devem ser cada coluna? Depende de quantas colunas temos. Para essa demonstração, usarei doze colunas, então, cada uma deve ter um doze avos (1/12) da largura do recipiente. Para uma coluna que terá duas dessas larguras, será 2/12, e por aí vai. Eis o código:
1 |
@media only screen and (min-width: 30em) { |
2 |
|
3 |
.wrapper { |
4 |
width: 95%; |
5 |
max-width: 65em; |
6 |
}
|
7 |
|
8 |
.column-1 { |
9 |
width: 8.33333%; |
10 |
}
|
11 |
|
12 |
.column-2 { |
13 |
width: 16.66667%; |
14 |
}
|
15 |
|
16 |
.column-3 { |
17 |
width: 25%; |
18 |
}
|
19 |
|
20 |
.column-4 { |
21 |
width: 33.33333%; |
22 |
}
|
23 |
|
24 |
.column-5 { |
25 |
width: 41.66667%; |
26 |
}
|
27 |
|
28 |
.column-6 { |
29 |
width: 50%; |
30 |
}
|
31 |
|
32 |
.column-7 { |
33 |
width: 58.33333%; |
34 |
}
|
35 |
|
36 |
.column-8 { |
37 |
width: 66.66667%; |
38 |
}
|
39 |
|
40 |
.column-9 { |
41 |
width: 75%; |
42 |
}
|
43 |
|
44 |
.column-10 { |
45 |
width: 83.33333%; |
46 |
}
|
47 |
|
48 |
.column-11 { |
49 |
width: 91.66667%; |
50 |
}
|
51 |
|
52 |
.column-12 { |
53 |
width: 100%; |
54 |
}
|
55 |
|
56 |
}
|
Você também verá que tornamos o elemento recipiente .wrapper
menor que a totalidade da largura da tela, configurando a propriedade max-width
dele. Veja como está nossa grade.



Limpando As Coisas Com Sass
A nossa grade funciona, mas o que aconteceria se quiséssemos que ela tivesse 16 colunas? Ou quem sabe até mais? Teríamos de recalcular cada coluna todas as vezes que precisássemos. Sem mencionar que nosso CSS ficaria muito maior e mais difícil de manter. Felizmente, o Sass (ou qualquer outro pré-processador) pode nos ajudar.
Configurando o Sass
Esse tutorial não é sobre como configurar o Sass, assim, assumimos que você já sabe fazê-lo. Se não é o seu caso e precisa aprender como fazer isso, dê uma olhada no Dominando Sass: Lição 1 ou SASS e Compass para Web Designers: Introdução.
Uma vez que seu projeto em Sass esteja configurado, vá para o próximo passo.
Definindo Variáveis
O Sass ajuda a limpar nosso CSS de todas as formas, mas a primeira coisa que faremos é extrair quaisquer valores úteis e guardá-los em variáveis. Comece por um novo arquivo parcial chamado "_variables.scss"; esse arquivo parcial não será compilado diretamente em CSS, mas o referenciaremos em outros arquivos.
1 |
// variáveis da grade |
2 |
$grid-columns: 12; |
3 |
$grid-max-width: 65em; |
4 |
|
5 |
|
6 |
// breakpoints |
7 |
$breakpoint-small: "only screen and (min-width: 20em)"; |
8 |
$breakpoint-medium: "only screen and (min-width: 30em)"; |
Essas variáveis nos dão a quantidade de colunas que trabalharemos, 12 nesse momento, mas poderiam ser 16 ou, quem sabe, 32. Qualquer quantidade que quiser. Também salvamos alguns pontos de quebra como cadeias de caracteres dentro de variáveis, mesmo que estejamos usando apenas uma, até agora.
Nós as usaremos logo-logo, mas configuremos as mixins primeiro.
Mixins
As mixins do Sass são trechos de código que definimos uma vez e reusamos em qualquer outro lugar do nosso projeto. Por exemplo, poderíamos transformar nosso primeiro conjunto de regras, onde configuramos a border-box
, em uma mixin. Comecemos:
1 |
*,
|
2 |
*:after, |
3 |
*:before { |
4 |
margin: 0; |
5 |
padding: 0; |
6 |
-webkit-box-sizing: border-box; |
7 |
-moz-box-sizing: border-box; |
8 |
box-sizing: border-box; |
9 |
}
|
Agora, peguemos a parte dele que podemos reusar, criando uma mixin que chamaremos de border-box
:
1 |
@mixin border-box { |
2 |
-webkit-box-sizing: border-box; |
3 |
-moz-box-sizing: border-box; |
4 |
box-sizing: border-box; |
5 |
}
|
Então, poderemos usar o comando @import
de nossas variáveis e mixins dentro do arquivo grid.scss
, usando a mixin através da declaração @include
.
1 |
@import "variables"; |
2 |
@import "mixins"; |
3 |
|
4 |
*,
|
5 |
*:after, |
6 |
*:before { |
7 |
margin: 0; |
8 |
padding: 0; |
9 |
|
10 |
@include border-box; |
11 |
|
12 |
}
|
@extend do Clearfix
Podemos fazer algo parecido com as regras de clearfix, como sugerido por Sebastian Ekström. Nesse caso, pegamos as regras recomendadas por Nicolas Gallagher e as adicionaremos no arquivo de nossas mixins como um seletor de espaço reservado (%
):
1 |
%clearfix { |
2 |
*zoom: 1; |
3 |
&:before,
|
4 |
&:after { |
5 |
content: " "; |
6 |
display: table; |
7 |
}
|
8 |
&:after { |
9 |
clear: both; |
10 |
}
|
11 |
}
|
O seletor de espaço reservado nos permite definir trechos de código que só gerarão algo caso o estendamos em algum lugar, dessa forma:
1 |
.wrapper, |
2 |
.row { |
3 |
@extend %clearfix; |
4 |
}
|
Quando compilado, essas poucas linhas gerarão algo assim:
1 |
.wrapper, |
2 |
.row { |
3 |
*zoom: 1; |
4 |
}
|
5 |
.wrapper:before, |
6 |
.row:before, |
7 |
.wrapper:after, |
8 |
.row:after { |
9 |
content: " "; |
10 |
display: table; |
11 |
}
|
12 |
.wrapper:after, |
13 |
.row:after { |
14 |
clear: both; |
15 |
}
|
Usando Nossas Variáveis
Que tal usarmos algumas dessas variáveis que configuramos? Para começar, podemos substituir o valor de max-width
no elemento recipiente. Isso:
1 |
.wrapper { |
2 |
width: 95%; |
3 |
max-width: 65em; |
4 |
}
|
torna-se isso:
1 |
.wrapper { |
2 |
width: 95%; |
3 |
max-width: $grid-max-width; |
4 |
}
|
Agora, façamos o mesmo com nossa media query. Isso:
1 |
@media only screen and (min-width: 30em) { |
será aprimorado com nossa variável $breakpoint-medium
e virará isso:
1 |
@media #{$breakpoint-medium} { |
Nota: você deve ter pecebido que envolvemos a variável em #{}
. Isso é chamado de interpolação. Isso é necessário caso precisemos mostrar o valor de uma variável dentro de outra. Contudo, nesse caso é necessário porque o compilador do Sass acusará problemas na media query caso o @media
não seja diretamente seguido por um par de ()
. Você pode ler mais sobre isso no artigo de Hugo Giraudel, Tudo Que Você Sempre Quis Saber Sobre Interpolação no Sass.
Para usar nossa variável $grid-columns
, precisamos lançar mão de mais uma funcionalidade do Sass; laços (loops).
Laços no Sass
Nossas definições de colunas são todas da mesma forma, exceto pelo valor da propriedade. É muito mais simples imprimir todas as definições de coluna que forem necessárias para a grade, alterando o valor para cada um. Para isso, usaremos o laço @for
do Sass, que é mais ou menos assim:
1 |
@for $i from 1 through 12 { |
2 |
// conteúdo repetido |
3 |
}
|
Isso se reptirá pode 12 vezes e, em cada vez, o valor da variável $i
refletirá naquele laço. Podemos retornar $i
dessa forma:
1 |
@for $i from 1 through 12 { |
2 |
|
3 |
.column-#{$i} { |
4 |
|
5 |
}
|
6 |
|
7 |
}
|
Novamente, você perceberá que interpolamos $i
com #{}
para retornar o valor como uma cadeia de caracteres que anexaremos ao seletor .column-
. Isso gerará o seguinte CSS:
1 |
.column-1 { |
2 |
|
3 |
}
|
4 |
|
5 |
.column-2 { |
6 |
|
7 |
}
|
8 |
|
9 |
.column-3 { |
10 |
|
11 |
}
|
12 |
|
13 |
.column-4 { |
14 |
|
15 |
}
|
16 |
|
17 |
.column-5 { |
18 |
|
19 |
}
|
20 |
|
21 |
.column-6 { |
22 |
|
23 |
}
|
24 |
|
25 |
.column-7 { |
26 |
|
27 |
}
|
28 |
|
29 |
.column-8 { |
30 |
|
31 |
}
|
32 |
|
33 |
.column-9 { |
34 |
|
35 |
}
|
36 |
|
37 |
.column-10 { |
38 |
|
39 |
}
|
40 |
|
41 |
.column-11 { |
42 |
|
43 |
}
|
44 |
|
45 |
.column-12 { |
46 |
|
47 |
}
|
Perfeito! Agora, faremos alguns cálculos para retornar o valor correto de cada estilo dentro desses seletores.
Operadores do Sass
Estamos indo bem, mas precisamos retornar algo parecido com o seletor abaixo:
1 |
.column-5 { |
2 |
width: 41.66667%; |
3 |
}
|
A largura dessa coluna é obtido através da divisão de 100% pela quantidade de colunas total e multiplicado pelo número da coluna em questão. Nesse caso, seria 100% / 12 * 5 = 41.66667%
. Assim, esse é o cálculo que precisamos usar, substituindo os respectivos valores por variáveis.
1 |
@for $i from 1 through 12 { |
2 |
|
3 |
.column-#{$i} { |
4 |
width: 100% / 12 * $i; |
5 |
}
|
6 |
|
7 |
}
|
O Sass fará o cálculo por nós e retornará algo assim:
1 |
.column-1 { |
2 |
width: 8.33333%; |
3 |
}
|
4 |
|
5 |
.column-2 { |
6 |
width: 16.66667%; |
7 |
}
|
8 |
|
9 |
.column-3 { |
10 |
width: 25%; |
11 |
}
|
12 |
|
13 |
.column-4 { |
14 |
width: 33.33333%; |
15 |
}
|
16 |
|
17 |
.column-5 { |
18 |
width: 41.66667%; |
19 |
}
|
20 |
|
21 |
.column-6 { |
22 |
width: 50%; |
23 |
}
|
24 |
|
25 |
.column-7 { |
26 |
width: 58.33333%; |
27 |
}
|
28 |
|
29 |
.column-8 { |
30 |
width: 66.66667%; |
31 |
}
|
32 |
|
33 |
.column-9 { |
34 |
width: 75%; |
35 |
}
|
36 |
|
37 |
.column-10 { |
38 |
width: 83.33333%; |
39 |
}
|
40 |
|
41 |
.column-11 { |
42 |
width: 91.66667%; |
43 |
}
|
44 |
|
45 |
.column-12 { |
46 |
width: 100%; |
47 |
}
|
Como passo final, podemo usar a variável $grid-columns
ao invés do valor 12
:
1 |
@for $i from 1 through $grid-columns { |
2 |
|
3 |
.column-#{$i} { |
4 |
width: 100% / $grid-columns * $i; |
5 |
}
|
6 |
|
7 |
}
|
Agora, se quisermos mudar o número de colunas, simplesmente mudaremos o valor da variável e os cálculos serão realizados, automaticamente, para nós! Por exemplo, alterando $grid-columns
para o valor 4
nos retornará o seguinte CSS:
1 |
@media only screen and (min-width: 30em) { |
2 |
.wrapper { |
3 |
width: 95%; |
4 |
max-width: 65em; } |
5 |
|
6 |
.column-1 { |
7 |
width: 25%; } |
8 |
|
9 |
.column-2 { |
10 |
width: 50%; } |
11 |
|
12 |
.column-3 { |
13 |
width: 75%; } |
14 |
|
15 |
.column-4 { |
16 |
width: 100%; } |
17 |
}
|
Conclusão
Nosso grid.scss
finalizado contém, apenas, 42 linhas de código. Bem menos que nosso CSS inicial.
1 |
@import "variables"; |
2 |
@import "mixins"; |
3 |
|
4 |
*, *:after, *:before { |
5 |
margin: 0; |
6 |
padding: 0; |
7 |
@include border-box; |
8 |
}
|
9 |
|
10 |
img { |
11 |
width: auto; |
12 |
max-width: 100%; |
13 |
height: auto !important; |
14 |
}
|
15 |
|
16 |
.wrapper { |
17 |
width: 100%; |
18 |
margin: 0 auto; |
19 |
}
|
20 |
|
21 |
.wrapper, .row { |
22 |
@extend %clearfix; |
23 |
}
|
24 |
|
25 |
[class*='column-'] { |
26 |
float: left; |
27 |
padding: 1em; |
28 |
width: 100%; |
29 |
min-height: 1px; |
30 |
}
|
31 |
|
32 |
@media #{$breakpoint-medium} { |
33 |
.wrapper { |
34 |
width: 95%; |
35 |
max-width: $grid-max-width; |
36 |
}
|
37 |
@for $i from 1 through $grid-columns { |
38 |
.column-#{$i} { |
39 |
width: 100% / $grid-columns * $i; |
40 |
}
|
41 |
}
|
42 |
}
|
Através desse processo, aprendemos como usar as variáveis, mixins, espaços reservados, extensões, laços, operadores e até interpolação no Sass. Esse é um conjunto muito poderoso de funcionalidades e um belo começo para aprender o Sass.
Como mais poderíamos aprimorar a grade que construímos? O que mais poderia ser adicionado ou removido? Deixe seu comentário!
Leitura Adicional
- 8 mixins do Sass que você tem de aprender
- SASS e Compass para Web Designers: Introdução
- Misture Suas Próprias e Deliciosas Mixins no Sass
- Anything by Hugo Giraudel
Seja o primeiro a saber sobre novas traduções–siga @tutsplus_pt no Twitter!