É para rir, chorar e abraçar o dev do lado, escrever CSS deve ser excessão!

CSS e Escalabilidade — Nós deveríamos escrever menos CSS

Eduardo Rabelo
Tableless
Published in
13 min readFeb 18, 2017

--

Alguns anos atrás eu fiquei curioso para saber como CSS funcionava em escala. Quando eu comecei, não havia quase nenhum recurso sobre isso como hoje. Existiam apenas alguns livros que meus amigos me emprestavam e poucos blogs decentes. A ciência em volta do CSS ainda era muito nova e muita gente ainda não tinha a preocupação com a manutenção em grandes equipes.

CSS Zen Garden foi uma influência incrível naquele tempo. Muitos dos meus amigos e, inclusive eu, usávamos o CSS Zen Garden como um ótimo exemplo de como usar o efeito cascata. Você poderia mudar completamente o design visual do seu site sem mexer no HTML.

No início, era isso o que me vendiam como funcionalidade. Por escrever CSS, você deveria mudar uma propriedade e ter sua mudança propagada em todo lugar. Há princípio, isso soava como algo desejável.

Mas, quase 11 anos depois, minha experiência, em pequenas e grandes equipes, é que essa funcionalidade é algo aterrorizador do CSS, podendo bloquear uma capacidade de organização e até mesmo mudança em um produto.

Duas propriedades CSS entram em um bar. Um balcão, em um bar completamente diferente, foi derrubado.

— @thomasfuchs

Depois de inúmeras implementações de CSS em sistemas que se tornaram difíceis de manter, e quebravam facilmente, a partir do momento que a equipe crescia muito, cheguei a uma conclusão:

Eu descobri que cada vez mais eu quero menos do efeito cascata no meu projeto.

Eu costumava usar uma piada que, a pior parte do desenvolvimento front-end é que, a outra pessoa que está tentando resolver seu problema, também é um desenvolvedor front-end. Mas, nos últimos anos, muitos pensadores e pessoas “fora da curva”, começaram a pensar mais sobre CSS, e isso abriu portas para discussões fascinantes sobre como criar uma estrutura de interface escalável com CSS.

Quando eu comecei a pensar sobre escalabilidade, naturalmente, procurei cada livro e vídeo possível para estudar. Existem inúmeras “melhores práticas” em torno de SASS, LESS e Stylus, que irá te ajudar a construir um CSS de qualidade. Como mixins podem tornar seu código mais limpo. Como extends irão manter sua marcação mais limpa. E como BEM irá deixar seu código tão perfeito que você vai querer chorar.

Mas, o que é realidade nisso tudo? O que é que acaba sendo entregue ao usuário final? Dentro de todas essas dicas, quais são as que realmente importam para o seu CSS em produção? O mais importante, como isso afetará sua equipe, produto e usuário?

Quando falamos em projetar e entregar produtos, eu gosto de falar de realidade. O que, algumas vezes, pode ser desafiador.

Já participei de várias reuniões onde as pessoas não queriam falar ou escutar sobre a verdade. Apenas frases vazias e possibilidades hipotéticas. Mas na real, eu gosto de usar drogas e falar sobre isso, realidade, cara a cara. Mas se você não avaliar com precisão, qual seu estado atual e qual sua realidade, é bem difícil entender e descobrir seus problemas. E a chance de achar soluções para problemas desconhecidos, bem, não são muitas! 😅

Bom, aqui estamos, final de 2014, empregado novo em uma empresa de tecnologia premiada, que por sinal, tinha um website. E o website tinha muito CSS. Para me familiarizar com a base de código, eu abri o DevTools e comecei a ler o CSS do website.

Linha por linha.

Do começo ao fim.

Alguns pedaços me fizeram rir:

/* Começo dos estilos reusáveis aqui!! */

Alguns me fizeram chorar:

.homepage-promos .grid-50 {
width: 100%
}
.homepage-promos .grid-33 {
width: 100%
}
.homepage-promos .grid-34 {
width: 100%
}

Alguns me fizeram rir e chorar ao mesmo tempo:

#seo-container {
display: none;
}

Alguns me fizeram repensar matemática, de onde vem os números?

.product-tab {
height: 530px;
width: 99.7%;
}

E outros me deixaram feliz, afinal, o tempo que investi lendo a documentação do CSS não foi em vão!

.container-inner.promo-status {
float: center;
}

E de vez em quando eu tropeçava em algumas classes como:

.left {
float: left!important;
}

Eu olhava para essa classe e pensava: “Bom, pelo menos você sabe o que ela faz”. Diferente de outros pedaços do código, essa parecia bem reutilizável.

Continuei lendo e tropecei em:

.left-max-scr1,
.left-max-scr2,
.left-max-scr3,
.left-only-scr1 {
float: left;
}

Seguido de:

.left-min-scr2,
.left-min-scr3,
.left-max-scr3,
.left-only-scr3 {
float: left;
}

O próximo exemplo de código me deixou imaginando qual a história por trás disso. É para elementos com .header-nav-list que não estão aninhados em um elemento .header-nav-container??

.header-nav-container .header-nav-list {
float: left;
}
.CA .header-nav-list.second {
float: left;
}

E aqui começa a mistura entre semântica de conteúdo e classes visualmente semânticas:

#nav.challenger-a .submenu-3col li,
#nav.challenger-a .submenu-3col li {
float: left;
}
.ie6 #footer-content .flex-control-nav li a,
.ie7 #footer-content .flex-control-nav li a,
.ie8 #footer-content .flex-control-nav li a {
float: left;
}
#nav.challenger-a li.menu-products {
float: left;
}

CSS é interessante porque, diferente de outros tipos de código, o código mais recente geralmente está no final do arquivo. Ler um arquivo CSS do começo até o final, frequentemente te conta uma história cronológica de como o sistema foi construído.

Nos exemplos acima, nós vemos partes sendo quebradas e seletores crescendo para ter mais e mais relevância para no fim, aplicarmos um float: left.

HÁ, e existem apenas 3 valores para float. Ao contrário do exemplo acima, não existe o valor center. Apenas left, right e none.

Ler CSS me faz repensar a vida. Uma coisa que não sai da minha cabeça é: “Porque todo esse trabalho só para mudar uma coisa? Esse seletor enorme só para colocar float”?

Para mim, isso é uma reflexão do modelo mental que muitas pessoas tem ao escrever código front-end. Eles geralmente estão tentando mudar uma ou outra coisa na interface e pronto. E quando você está nesse modelo de pensamento, você quer limitar o impacto nas coisas que você está mexendo, e simplesmente realizar a tarefa colocada para você no JIRA.

Isso também me faz pensar em comunicação e como as coisas se movem em várias direções. Se eu estou lendo HTML, eu quero saber o que o CSS está fazendo. Se eu estou lendo CSS, eu quero saber qual tipo de elemento HTML eu estou estilizando. Em um ótimo sistema, existe uma via de mão dupla nessa comunicação. Se você olhar o CSS, você pode dizer o vai acontecer, se você olhar o HTML, você pode dizer o que está acontecendo.

Mas, a maioria dos sistemas front-end, não são ótimos. Você tem o que chamam de via de mão única de informação. Se eu olhar um bloco de HTML, eu não consigo achar todas as informações que o CSS irá alterar visualmente, em menos de 1 minuto. Eu sinto como se o sistema tivesse falhado. Se eu encontro o seguinte exemplo:

.container-inner.promo-status

Isso significa que eu vou ter que procurar elementos que contenham ambas as classes (mas não limitados a apenas elas). E olhando para esse pedaço de CSS, eu não tenho a menor idéia se ele vai ser alterado em algum outro lugar. Então, eu tenho que continuar procurando no meu arquivo CSS por definições que contenham .container-inner e .promo-status. Até eu encontrar essas definições, provavelmente eu já me distraí com alguma coisa e fui buscar um café.

Por outro lado, se tivermos algo como:

.red {
color: #FF4136;
}

Eu posso garantir que irá transformar o texto de um elemento em vermelho. Eu fui ensinado que isso é um nome horrível para uma classe. Mas, eu até que gosto. Ela só se tornaria ruim caso o resultado da cor fosse roxo, verde, azul ou qualquer outra que não vermelho. Eu também espero que ela não seja mudada conforme o arquivo continua, mudando a cor de vermelho, mas vamos falar sobre isso mais para frente.

E se eu ver algo como:

<div class=“red”>Some text</div>

Eu saberia, sem precisar olhar no CSS, o que iria acontecer. Isso é uma via de mão dupla de informação. É fácil identificar um pequeno grupo de classes que fazem uma coisa muito bem e podem ser reutilizadas em outros contextos. Deve existir uma relação de um-para-um entre classes e suas definições. Ter uma classe que contém múltiplas definições e é alterada dependendo do contexto, não resolve muitos problemas, na verdade, ela cria eles! O conceito de imutabilidade não é novo — mas tem sido ignorado na comunidade CSS por muito tempo.

Imagine se eu tenho uma função chamada tamanhoDeArquivo, onde você passa um caminho de arquivo e ela retorna o tamanho dele. Parece uma função ótima, funciona bem. Agora, imagine que, de vez em quando, ela retorna a quantidade de linhas em um arquivo. Isso não parece correto, não funciona.

Bom, na verdade, isso é o que você está fazendo com o seu CSS quando redefine aqui e ali. É complicado para outros desenvolvedores debugarem sua aplicação. É ainda mais complicado para desenvolvedores sem muita experiência com aplicações com grandes arquivos CSS.

Quando olhamos em um CSS complicado, nós precisamos lembrar que, por trás de cada regra CSS, existe uma história. Talvez o autor dessa declaração estava com pressa e não teve tempo de procurar alguma classe existente para poder reutiliza-la. Talvez ele não ligue para CSS, no momento que o que ele procura funciona, ele comita o código e volta para escrever suas Monads.

Quando eu escrevo código ruim, não é porque eu não estou tentando escrever um código bom. Sempre existem fatores externos as nossas forças, principalmente no fluxo do dia-a-dia do trabalho. Quais são as forças que trabalham contra a escrita de um código limpo e reusável? Como acabar com eles? Eu passei os últimos anos realizando vários testes de usuário, focado em saber como as pessoas escreviam seus códigos front-end, utilizando código de outras pessoas e pensando em como contribuir uma interface no geral. Tem sido uma ótima experiência (como todo teste de usuário é).

Eu aprendi muito sobre a diferença do modelo mental de cada um — e como tentar construir um sistema que permitisse que as pessoas, de cada habilidade, pudessem passar mais tempo construindo e projetando interfaces, do que debugando, lutando e chorando sob o código criado.

Antes de eu começar a oferecer teste de performance e de usuário, eu não gostava da idéia de OCSS e Atomic CSS. Eu realmente gostava de escrever grandes pedaços únicos de CSS aninhando os seletores com o HTML. Fazia sentido para mim, e eu criei vários websites assim. Rodar testes sob minhas próprias decisões, me ajudou a me informar como o meu modelo mental funcionava. É engraçado, mas hoje, não me interessa muito o que eu consigo fazer com CSS. No ponto de hoje, eu estou mais interessado em saber e ajudar grupos de pessoas a criar com CSS.

Se você vai construir um novo componente, ou mudar um pedaço da interface do seu app — o que você vai fazer? Eu não sei se alguém vai ler todo o CSS disponível no app para ver se já existe algo para ser reutilizado. Quem tem tempo o suficiente para ler linhas e linhas de código para só então começar a trabalhar? Mesmo se tiver, eu descobri que esse não é o primeiro instinto da pessoa, e eu não os culpo.

Mesmo se você ler todo o código disponível e descobrir algo que possa ser reutilizado — e se alguém editar isso depois? Se você já está começando com a idéia de que seu CSS não é reutilizável, seu primeiro instinto é escrever novos pedaços de CSS. Mas, é mais provável que você não esteja criando nenhum visual novo. Na minha experiência, é mais provável que você esteja substituindo estilos visuais já criados.

Salesforce talvez pague muito bem. E talvez eles ganhem o prêmio de empresa mais inovadora da Forbes. Mas eles não são conhecidos por contratar pessoas que são ótimas com CSS. O CSS deles é tudo, menos inovativo. Após ler todo o CSS disponível, linha por linha, chorar bastante, coçar minha cabeça e rir em alto e bom tom — Eu concluí que esse problema só existe na Salesforce. Com certeza empresas como Medium, GitHub, Adobe e Pinterest não tem esse problema. Eles contrataram brilhantes desenvolvedores CSS, eu conheci vários deles. Com certeza eles acharam o segredo para escalar CSS.

Naturalmente, eu abri o CSS do site deles e comecei a ler o CSS deles também. Linha por linha. Do começo ao fim. Eu estava curioso para saber qual a realidade deles.

E advinha? Eu encontrei exatamente os mesmos problemas!

Vamos dar uma olhada em (apenas) algumas regras que utilizam display: none.

É… é bastante código para apenas display: none. Olhando esses arquivos, a gente se pergunta: “Será que eles usam o conceito DRY?”, “Será que esses pedaços de códigos podem ser reutilizados?”

Se eu for escrever CSS, eu quero que ele seja reutilizável. Se ninguém for reutilizá-lo, não faz sentido, parece inútil.

“Então, o que DRY quer dizer?” Você tem perguntado isso a você mesmo. Você se pergunta isso tanto no HTML, quanto no CSS. Mas, não importa sua experiência com CSS — não tem como escrever um novo componente sem tocar no HTML. Mas é possível criar um novo componente sem tocar no CSS? Sim, é! E isso aplica para mudanças na interface também. Você deveria ser capaz de mudar quase tudo, apenas editando HTML.

Quando você se repete no HTML, não existe nenhum tipo de problema real, mesmo para o tamanho de arquivo (estou falando diretamente da questão de “múltiplas classes em tudo aumenta o tamanho do HTML”, mano, sério?). O usuário não precisa fazer o download de todos os seus arquivos HTML para ver uma única página. Porém, quase todos os sites estão estruturados para todo o css do site para você poder ver apenas uma única página. Isso é um modelo quebrado, com certeza.

Os arquivos que me mostro acima são resultados de desenvolvedores criando seletores longos para adicionar mais peso no efeito cascata para fazer uma ou outra coisa. E como o tempo voa, cada vez mais existem coisas para adicionar no seu efeito cascata. Então, seus seletores ficam grandes e longos, o tamanho do seu arquivo fica cada vez maior, e a quantidade de tempo que você passa debugando CSS só irá crescer.

Nesse modelo, você nunca irá parar de escrever CSS. Refatorar CSS é difícil, e costuma consumir muito tempo. Deletar CSS não utilizado, é difícil, e costuma consumir muito tempo também. E quase sempre — não é um trabalho que as pessoas ficam animadas para fazer. E o que acontece? Todo mundo continua escrevendo mais CSS.

Isso afeta escalabilidade em duas maneiras. Um, fica realmente difícil de trabalhar no seu app porque você não consegue memorizar suas classes CSS. E se for muito específico, dificilmente é reutilizável. Seus usuários irão precisar fazer um download maior. E se você pensar “ah, mas nunca vai ficar tão ruim, gzip tá aí para isso” — bom, você está errado. Pinterest tem mais de 1mb de CSS não unificado dividido em quase 5 arquivos diferentes. Depois do gzip, eles ainda ficam em torno de 159kb. Isso é muito CSS. 97% disso não é usado na página inicial. Eu provavelmente tentaria enviar apenas os 3% necessários.

Parte desse inchamento de código está ligado com a autoria de “nomes-semânticos” baseado em conteúdo. Honestamente, eu fico surpreso com pessoas que não acham isso uma idéia horrível. Nicolas Gallagher já escrever um artigo que fala o porque isso não funciona. Mas ainda assim, você encontra pessoas argumentando que isso é a salvação. Pessoalmente falando, eu acho que boa parte dos ensinamentos na internet está “quebrado”. Então, eu levo para mim que, tudo que leio ou ensinam, é “meio-errado”.

Aqui é onde a cruz do problema que encontro em qualquer sistema que mapearam estilos visuais com conteúdo HTML.

Conteúdo semântico NÃO TEM NADA HAVER COM ESTILOS VISUAIS.

Quando eu vou construir algumas coisas com Lego, eu nunca pensei em “oh, por essa peça ser azul, ela é apenas do motor do carro”, eu sempre pensei “legal, tenho uma peça 1x4 e posso fazer o que eu quiser com ela”. Não importa se eu estou montando um aquário ou um carro — eu sei exatamente como usar aquela peça de Lego.

Pense em pedaços de Lego. Eu nunca precisei criar outros contextos para entender minhas peças de Lego. Eu posso usar elas em qualquer projeto, e elas sempre serão as mesmas. Eu sonho com isso para o mundo de desenvolvimento front-end. Eu quero pedaços de Lego que funcionem em todo lugar. Existe um poder incrível em poder criar soluções agnósticas a projetos.

Fora do mundo específico de cores de marcas, images de fundo, gradientes e etc. A maior parte do CSS que você vai precisar para seu site, já foi escrita. Porém, nós como comunidade, continuamos a re-escrever a roda. É aquele sentimento de criar uma camera do zero, toda vez que você quiser tirar uma foto. Eu acho que criar uma camera do zero é bem desafiador, mas, eu não quero fazer isso toda vez que eu quiser tirar uma foto. Eu só quero sair para tirar fotos poxa =(

Quando eu leio ou escuto sobre idéias em como escalar CSS em aplicações web — a maioria delas é sobre como escrever CSS. O único modo de escalar CSS, é parar de escrever CSS. Abstrair as coisas que você mais usa, mover nome de classes para múltiplos nomes de classe, onde você consegue compor mais padrões visuais no seu HTML. Você ficaria impressionado na velocidade que seu time iria criar.

Existem vários problemas quando pessoas escrevem CSS. Valores inconsistentes, introdução de números mágicos, código duplicado, padrões não responsivos. Tenho certeza de que existem outros.

Se você criar um sistema que é flexível e estável, e puxando disso, você irá ver que seus designs são mais harmoniosos. Você irá gastar menos tempo debugando o efeito cascata. Suas páginas irão carregar mais rápido. Mas, quem sabe? Talvez isso não iria funcionar para você, ou seu produto. O que eu sei é que o modelo atual não irá funcionar.

Escrever CSS novo deveria ser uma excessão, não regra.

Pensamentos finais

Se você nunca leu o seu CSS final, do começo ao fim — eu recomendo que você faça isso, é uma experiência incrível, você irá aprender muito sobre como você e as pessoas do seu time escrevem e usam CSS. Depois que eu li o CSS na Salesforce, eu comecei a ler CSS de vários sites. Eu ainda faço isso! Sempre aprendo algo novo :)

Não leve isso como dogma. O ponto real aqui é acoroçoar a testar suas decisões e pensamentos. Quase ninguém senta do lado do outro e simplesmente olha a maneira do outro criar interfaces, componentes ou refatorar código. Testes de usuário é um grande exercício para saber como as pessoas usam as coisas. Você aprende muito com pessoas que são ótimas escrevendo código front-end e aprende muito também, com pessoas que são novas na áreas. Eu não teria aprendido tudo que sei se eu tivesse sentado sozinho e tentando resolver todos os problemas por conta própria baseado naquele último post do blog famoso de CSS.

A realidade é que várias pessoas, com diferentes níveis de experiência irão mexer no seu código front-end, e você deve projetar sua arquitetura de uma maneira que funcione para todos.

Obrigado a todos que me deram feedback nesses pensamentos nos últimos anos. E um obrigado em especial aos pioneiros que, com a cara e a coragem, desafiam as “melhores práticas” e nos mostram que podemos fazer o mesmo. Estou olhando para vocês @stubbornella, @necolas, @dam e @mrmrs_.

Créditos

--

--