A maneira 100% correta de fazer breakpoints em CSS

Depois de anos usando breakpoints, será que a maioria dos desenvolvedores front-end realmente já pararam para pensar se estão fazendo do jeito certo?

Para os próximos 2 ou 3 minutos, esqueça o que é CSS (e o que são breakpoints em CSS); esqueça o que é desenvolvimento para web; esqueça o que são digital user interfaces. E, ao esquecer estas coisas, permita que sua mente vagueie.

Que volte no tempo, para a sua época de escola — aquele tempo mais simples, quando suas maiores preocupações eram desenhar formas e manter sua incontinência sob controle.

Dê uma olhada nessas bolinhas:


CSS breakpoints: a maneira correta: inocentes bolinhas...

Observe como alguns deles estão agrupados e alguns espalhados. Prosseguindo ao exercícios mental, divida-as em 5 grupos e depois desenhe um círculo em torno de cada um destes grupos.

Provavelmente a solução para a questão terá sido algo como isso:


A maneira 100% correta de fazer breakpoints em CSS: bolinhas agrupadas

Claro, o grupamento desses 2 pontos à direita poderia ter sido de outra maneira. Na verdade, toda a demarcação também poderia ter sido diferente do “usual”, resultando em algo mais ou menos como:


A maneira 100% correta de fazer breakpoints em CSS: grupamento diferente das bolinhas

Parece que desse jeito não ficou muito bom, foi um “agrupamento bobo”… Certo?

Mas isso é basicamente o que 99% dos desenvolvedores front-end fazem para definir breakpoints que correspondem à largura exata de dispositivos populares (320px, 768px, 1024px)!


A maneira 100% correta de fazer breakpoints em CSS: divisão comum de breakpoints baseada em dispositivos populares

Palavras mais ou menos como essas já entraram em seus ouvidos ou saíram de sua boca?

O breakpoint “medium” é até 768px ou inclui 768px? E isso é landscape no iPad ou é o breakpoint “large”? Oh, “large” é 768px para cima. O “small” é 320px, certo? De 0 a 319px.

É curioso que o método acima, o “agrupamento bobo”, esteja tão difundido… Mas, então, qual deveria ser a maneira correta de fazer breakpoints em CSS?

Provavelmente a resposta para este problema, como para tantos outros, se resuma a uma terminologia desalinhada. Neste caso específico, misturas indiscriminadas de termos como “limites” (boundaries) e “intervalos” (ranges) nas discussões e implementações de breakpoints.

Fazendo uma suposição, provavelmente você tem uma variável em Sass $large com o valor de 768px. Esse é o limite inferior (lower boundary) ou superior (upper boundary) do intervalo (range) conhecido como “large”?

Se for o inferior, então não deve haver $small, já que ele teria que ser 0, certo?

E se for o superior, então como foi definido um breakpoint $large-and-up? Deve ser uma media query com min-width de $medium, confere? E se está se referindo a apenas um limite quando se refere a “large”, então haverá confusão mais tarde, porque uma media query é sempre um intervalo (range).

Essa situação é caótica e estamos perdendo tempo pensando nisso. Então aqui vão 3 sugestões:

  1. Crie breakpoints do jeito certo
  2. Nomeie breakpoints corretamente
  3. Seja declarativo

Crie breakpoints do jeito certo

No final das contas, qual é “o jeito certo” para criar breakpoints?

Lembra da divisão das bolinhas em grupos? Basta fazer a coisa direito que se chegará a algo como:


A maneira 100% correta de fazer breakpoints em CSS: divisão correta de breakpoints

600px, 900px, 1200px e 1800px (se for preciso servir algo especial a pessoas com monitores gigantes).

Essa divisão representada os 14 tamanhos de tela mais comuns:

A maneira 100% correta de fazer breakpoints em CSS: 14 tamanhos de tela mais comuns

A partir daí, torna-se possível idealizar um sistema que permita o fluxo fácil de palavras entre pessoas vestidas com ternos, designers, desenvolvedores e testadores:


A maneira 100% correta de fazer breakpoints em CSS: divisão correta de breakpoints

Nomeie breakpoints corretamente

Evidentemente, você pode nomear seus breakpoints da maneira que quiser, até como papa-bear e baby-bear. Mas, geralmente, quando pessoas de um time de desenvolvimento se sentam para resolver alguma questão, é interessante que os nomes dados não sejam um empecilho. Se nomear um tamanho para um tablet em orientação de retrato facilitar isso, tudo bem — alguns poderiam até chamar isso de… “iPad portrait”.

Mas alguns podem alegar que “o cenário está mudando”. “Telefones estão ficando maiores e tablets menores”.

Acontece que o CSS dos projetos geralmente têm uma vida-média de uns 3 ou 5 anos (a menos que seja o Gmail). O iPad esteve conosco por 2 vezes durante esse tempo e ainda não foi destronado — e sabemos que a Apple já não fabrica novos produtos; simplesmente remove coisas dos existentes (botões, buracos etc.).

Então, para o bem e para o mal, 1024×768 está aqui para ficar. Não vamos enterrar nossas cabeças na areia.

Conclusão: comunicação é importante! Não dispense propositalmente vocabulário útil.

Seja declarativo

Que se entenda por “declarativo” que o CSS deve definir o que ele quer que aconteça e não como isso deve acontecer. O “como” pode ficar implícito em algum tipo de mixin ou coisa assim.

Como discutido anteriormente, parte da confusão sobre breakpoints é que variáveis que definem um limite de um intervalo (boundary of a range) são usadas como o nome do intervalo. $large: 600px simplesmente não faz sentido se “large” for um intervalo. É o mesmo que declarar var coordinates = 4;.

Em função disso, é conveniente esconder esse tipo de detalhe dentro de um mixin ao invés de o expor para ser usado no código. Ou, fazendo melhor, sequer usar variáveis.

No começo, o trecho de código abaixo servia apenas como um exemplo simplificado. Mas realmente ele tem potencial para fazer uma boa cobertura de casos. Para vê-lo em ação, confira este pen — o uso de Sass é opcional; a lógica se aplica a qualquer outro pré-processador ou CSS puro exatamente do mesmo jeito.

Perceba que é proposital forçar o uso dos sufixos -up/-only. Ambiguidade gera confusão.

Uma crítica óbvia pode ser que isso não lida com media queries personalizadas. Mas há boas novas: se você quiser uma media query personalizada, escreva uma media query personalizada!

Outra crítica pode ser relativa à quantidade de mixins criados. Certamente, um único mixin com o tamanho necessário sendo passado seria o mais sensato a ser feito. Algo assim:

Claro, isso funciona. Mas você não receberá erros em tempo de compilação (compile-time errors) se passar um nome sem suporte. E passar em uma variável Sass significa expor 8 variáveis apenas para passar para um switch em um mixin — sem mencionar que a sintaxe @include for-desktop-up {...} é mais bonita do que @include for-size(desktop-up) {...}.

Ainda uma outra crítica a esses snippets pode ser a repetição de 900px e também 899px. Certamente, deveria-se usar apenas variáveis e subtrair 1 quando necessário.

Se quiser fazer isso, vá em frente, mas há 2 razões principais a serem consideradas:

  1. Essas não são coisas que mudam com frequência. Estes também não são números que são usados em qualquer outro lugar na base de código. Nenhum problema é causado pelo fato de não serem variáveis — a menos que você queira expor seus breakpoints de Sass a um script que injete um objeto JS com essas variáveis na sua página.
  2. A sintaxe fica nojenta quando você quer transformar números em strings com Sass. Eis o preço a ser pago por acreditar que repetir um número duas vezes é o pior de todos os males:

Por fim, alguém pode estar pensando “Eu não deveria basear meus breakpoints em conteúdo, não em dispositivos?”. Basicamente, a resposta é: sim… Para sites com um único layout — ou se existirem vários layouts e existem algum prazer mórbido em ter um conjunto diferente de breakpoints para cada um deles.

Para sites complexos, “do mundo real”, a prática sugere escolher alguns breakpoints para serem usados em todo o site.

Conclusão sobre a maneira 100% correta de fazer breakpoints em CSS

Brincadeiras de título à parte, certamente não existe uma maneira “100% correta” para se fazer ou usar breakpoints. Mas é difícil negar que a abordagem apresentada nesse artigo certamente pode trazer interessantes reflexões sobre o tema.

Sendo assim, considere os conteúdos apresentados como sugestões de técnicas a serem seguidas e, depois de as experimentar, julgue se fazem ou não sentido dentro dos projetos que você e/ou sua equipe participam.