/Blog
// Um pouco de filosofia sobre desenvolvimento, quer ouvir a minha opinião? (eu quero ouvir a sua)
»

#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:

Moreira

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:

nome responsivo

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.

habilidades responsivas

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?

#{map-get($breakpoints, $breakpoint)}

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.

min-width: #{map-get($breakpoints, $breakpoint)}

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:

tomate

Compartilhe


Comentários