#DicaPrática Três técnicas e componentes incríveis para o seu site ficar (ainda mais!) responsivo
Como você deve ter percebido pelo título se você não percebeu, por favor procure um oculista rápido! e depois volte pra ler meu blog ♥, tem uma parte amarela alí indicando que esse post:
- Fará parte de uma série/hastag/sequência intitulada de Dica Prática
- Será mais curto e direto, facilitando a leitura
- Será prático! Facilitando a sua implementação
Se você estava em coma não sabe o que significa um design responsivo, eu falo um pouco sobre isso no meu segundo post. Mas é basicamente um design que se adequa à diferentes tipos de tela.
Os exemplos mostrados aqui serão feitos em Sass porque eu quero e pronto facilita muito nosso trabalho.
Se você é programador, e não conhece Sass ou outro pré-processador de CSS, como diria o Murilo Gun, você tá de brincadeira na tomateira. Levanta a bunda da cadeira metaforicamente, a menos que queira usar o computador em pé e vai logo aprender sobre isso, para o seu próprio bem! Meu primeiro post conta um pouco das vantagens.
Sem mais delongas:
1. Mudando o texto com seletor :before e :after
Essa técnica é uma sacada muito boa, e confesso que a tirei do site do meu amigo Will.
Se você tá de brincadeira na tomateira não sabe o que significa esses ::after
e ::before
, é muito simples. Eles são pseudo elementos.
Como o w3schools explica muito bem nesse artigo, esse tipo de seletor é usado para selecionar partes de dentro de um elemento, como a primeira linha ou a primeira letra.
Os seletores after
e before
, além disso, nos permitem inserir um conteúdo antes ou depois do conteúdo do elemento, como a propriedade content
.
Olha esse exemplo simples e legal:
<style>
div.nome:before {
content: 'Dayman ';
}
div.nome:after {
content: ' Novaes';
}
</style>
<div class="nome">Moreira</div>
Produz o resultado:
E como esse texto é inserido com CSS, pode ser facilmente alterado com o uso de Media Query. Como por exemplo, mostrar apenas partes do nome em telas menores:
.nome {
@include media-query(md) {
&:after {
content: ' Novaes';
}
}
@include media-query(sm) {
&:before {
content: 'Dayman ';
}
}
}
O &, no Sass, referencia o seletor pai, no caso, o .nome. Portanto, esse código diz que a parte “Novaes” só será mostrada para telas maiores que tamanho médio (medium), e “Dayman” apenas para telas maiores que tamanho pequeno (small).
O compilado fica assim:
@media (min-width: 48em) {
.nome:after { content: ' Novaes'; }
}
@media (min-width: 34em) {
.nome:before { content: 'Dayman '; }
}
E o resultado:
Eu uso essa técnica no meu site pessoal, na seção de habilidade, onde mostra várias tecnologias com o nome e uma imagem. O nome é incluído desta forma, sendo que em dispositivos mobiles, o texto some e ficam apenas as imagens.
2. Utilitários Sass que podem salvar seu tempo
Os mixins
do Sass são ótimos, pois são funções que podemos criar para executar e compilar algum código CSS.
Misturando um pouco com a ideia de breakpoints do Bootstrap, podemos criar um mixin que utiliza disso para facilitar e padronizar o desenvolvimento.
Você deve ter percebido que usei no exemplo anterior o @include media-query(..), e é exatamente ele que vou explicar agora.
Primeiro, precisamos definir as variáveis que definem os tamanhos de tela que queremos, isto é, os breakpoints.
$breakpoints: (
// Extra small screen / phone
xs: 22em,
// Small screen / phone
sm: 34em,
// Medium screen / tablet
md: 48em,
// Large screen / desktop
lg: 62em,
// Extra large screen / wide desktop
xl: 75em
);
Essa variável é do tipo map, e podemos acessá-la usando map-get($breakpoints, xs)
por exemplo.
A definição do mixin então fica assim:
@mixin media-query($breakpoint) {
@media (min-width: #{map-get($breakpoints, $breakpoint)}) {
@content;
}
}
Calma que vou explicar. Ta vendo a parte amarela desse código aqui?
Então, esse é a sintaxe de interpolation do Sass. Interpolation significa algo como trocar, substituir. Significa que, no caso, o Sass pega o valor da chave escolhida (xs, sm, md…) e colocar na propriedade de min-width
.
E dentro das chaves tem um @content, que basicamente pega o conteúdo que você definiu na chamada do mixin, e coloca alí.
Exemplificando:
@include media-query(xs) {
article {
max-width: 350px;
}
}
Compila para:
@media (min-width: 22em) {
article {
max-width: 350px;
}
}
É simples, mas muito útil para agilizar nosso desenvolvimento.
E se você quiser fazer um mixin que, ao invés do min-width
da tela utilize o max-width
, é simples, basta trocar essa propriedade no mixin, usar o mesmo valor do breakpoint mas subtrair um centésimo, para que as duas não se confudam quando o tamanho de tela for exatamente aquele.
@mixin media-query-down($breakpoint) {
@media (max-width: #{map-get($breakpoints, $breakpoint) - 0.01}) {
@content;
}
}
3. Modularização inteligente com o Sass
Modularização não é algo que está diretamente ligada à responsividade, porém é algo tão importante, mas tão importante, que ou você se atenta à isso, ou você se atenta à isso.
Se você não busca organizar e modularizar seu código, tome vergonha na cara e só volte aqui quando refatorar todo o seu projeto.
Vamos lá!
Digamos que você esteja trabalhando com Bootstrap e deseja um componente que em telas grandes ocupe duas colunas, e em telas pequenas ocupe quatro colunas, como é o caso do componente de skill que fiz e exemplifiquei no primeiro tópico. O código ficaria assim:
<div class="col-lg-2 col-xs-4 component-skill">
...
</div>
A classe .component-skill
seria usada para adicionar estilos diferentes. Mas ao invés de “poluir” o html, podemos torná-lo mais semântico dessa forma:
.component-skill {
@extend .col-lg-2;
@extend .col-xs-4;
}
Agora, quais são os componentes que têm dentro deste componente? O texto, e a imagem. O html fica, então, intuitivo:
<div class="component-skill">
<span class="component-skill-title"></span>
<div class="component-skill-img"></div>
</div>
Esse é o nosso componente. Simples e modular.
Vamos agora implementá-lo.
Se quisermos mostrar nossa habilidade em Angular, basta fazer assim:
.component-skill {
@extend .col-lg-2;
@extend .col-xs-4;
&:angular {
.component-skill-title:before {
content: 'Angular';
}
.component-skill-img {
background-image: url(/img/angular-logo.png);
}
}
}
Desta forma, basta adicionar a classe .angular
no nosso componente, que o seu title conterá o texto “Angular” e o sua imagem terá a logo do Angular.
<div class="component-skill javascript">
<span class="component-skill-title"></span>
<div class="component-skill-img"></div>
</div>
Mas peraí…
Adicionaremos manualmente tooodas as habilidades no CSS, mudando nas partes convenientes?
Bom, seria uma forma, mas ainda assim, é claro que podemos modularizar ainda mais. E se criarmos uma lista com as habilidades, e criarmos uma @foreach
para percorrer cada uma e compilar o código?
Bom, vamos lá então. A lista ficaria algo assim:
$skills: (
javascript: "Javascript",
java: "Java",
c: "C/C++"
);
É importante ser do tipo map, e não apenas um array de strings, porque se não não conseguiremos, por exemplo, criar a classe .C/C++
, pois seria um nome inválido.
A sintaxe do Sass para percorrer um map é simples, seria algo como @each $skill, $s in $skills
, onde $skill
corresponde à chave, e $l
ao valor. Exemplificando, o primeiro seria c
e o segundo C/C++
.
A implementação fica assim:
@each $skill, $s in $skills {
.component-skill--#{$skill} {
@extend .col-lg-2;
@extend .col-xs-4;
.component-skill-title:before {
content: '#{$s}';
}
.component-skill-img {
background-image: url(/img/#{$skill}-logo.png);
}
}
}
Note os três interpolations que criei. O primeiro é para criar o nome da classe. No caso, é compilado para .component-skill--javascript
, .component-skill--java
e .component-skill--c
.
E o segundo e terceiro é apenas para preencher e ficar igual àquele exemplo que dei do Angular, mas com os parâmetros de cada linguagem.
Legal né? Faltam apenas alguns detalhes, como a media query no title para sumir com o nome, e algum estilo na imagem para deixá-la arredondada e aumentá-la em mobile.
O resultado final fica assim:
@each $skill, $s in $skills {
.component-skill--#{$skill} {
@extend .col-lg-2;
@extend .col-xs-4;
@include media-query(sm) {
.component-skill-title:before {
content: '#{$s}';
}
}
.component-skill-img {
border-radius: 50%;
width: 30px;
height: 30px;
@include media-query-down(sm) {
width: 60px;
height: 60px;
}
background-image: url(/img/#{$skill}-logo.png);
}
}
}
É isso, se você gostou, compartilha e se inscreva na lista de email pra receber mais dicas práticas como essa.
E para garantir que você não vai ficar de brincadeira na tomateira, aqui vai uma foto de um tomate:

Comentários