A ascensão do Functional CSS

Descobrindo e discutindo os méritos sobre Functional CSS

Eduardo Rabelo
Tableless
10 min readApr 12, 2017

--

Idéias e experiências ao usar CSS não-monolítico!

A idéia sobre Functional CSS, se alguém me contasse, eu ia dizer que era a coisa mais maluca que eu já tinha ouvido. Por quê algum dia você usaria isso? “Eu sei CSS muito bem, obrigado!”, eu falava para mim mesmo.

Se você ainda não escutou sobre, Functional CSS (ou Atomic CSS/classes utilitárias/Immutable CSS… — eu posso continuar o dia inteiro aqui, realmente não tem um nome definido), é a idéia de, ao invés de escrever grandes pedaços monolíticos de CSS, você escreve pequenas classes, de propriedade únicas e imutáveis, que podem ser montadas para formar grandes componentes no HTML.

Para montar uma equipe maior, basta chamar outras partes!

Seu CSS se parece com:

Que irá construir seu HTML mais ou menos assim:

Loucura, certo?

Eu adoro escrever classes CSS com aquelas propriedades inteligentes e poderosas. Eu argumento à favor disso pelo fato de “é simples para o desenvolvedor usar”. Meu objetivo é que o desenvolvedor possa adicionar uma única classe no elemento e automágicamente, tudo se transforma, sem ele precisar fazer nada.

Isso é, simplesmente, o oposto do Functional CSS.

Foi então que eu li CSS e Escalabilidade, originalmente escrito por Adam Morse, eu extraí bons pensamentos daquele texto, eu recomendo que você faça uma leitura com atenção no artigo linkado. Eu vou tentar fazer um resumo simples, na verdade, vai ser essa frase:

“Nesse modelo [monolítico], 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.”

¯\_(ツ)_/¯…

E, temos que concordar com o Adam nesse ponto. Ele está certo. É bacana começar um novo projeto e escrever todas aquelas declarações CSS planejadas baseadas em componentes. Mas, no fundo, eu nem sempre vou estar lá, e no modo monolítico, o time nunca irá parar de escrever CSS.

Levanta a mão se você já trabalhou com alguma base de código CSS que não tenha dor de cabeça?

É, eu também!

Normalmente, não é porque a base de código começou errado. É porque, para escrever CSS, nós somos ensinados a escrever mais código para fixar os problemas.

E, extraindo outra frase do texto, eu atingi um ponto na minha carreira que:

"Hoje, não me interessa muito o que eu consigo fazer com CSS. Eu estou mais interessado em saber e ajudar grupos de pessoas a fazerem com CSS."

Ótimos exemplos dessa abordagem são Basscss e Tachyons.

Eu já estava convencido em tentar esse novo paradigma, e eu tive a chance de começar um novo projeto para um cliente usando essa abordagem.

3 meses escrevendo Functional CSS para arquitetar o projeto, preciso dizer, eu estou viciado! E no meio tempo que tive que mexer em outros projetos, que usavam a idéia monolítica, se tornou uma tarefa tediosa e chata, pular de arquivo em arquivo frequentemente e etc.

Eu acho que eu fui convencido, mas eu ainda estou tentando visualizar a escalabilidade e problemas que Functional CSS trazem para a base de código, ainda mais quando ela cresce e o time cresce.

Caso você já tenha tentado, por favor, deixe seus pensamentos abaixo.

A seguir, vou listar minha experiência:

A parte boa

Velocidade

Rapaz, eu consigo trabalhar muito mais rápido! Eu sempre fui daqueles de dizer “eu consigo fazer design em código”, e preferia sempre deixar o documento de design em branco (seja do Sketch ou PS). Eu brincava com isso, acho que são duas partes do meu cérebro que não se comunicam bem.

O que eu percebi usando Functional CSS é que, era a mudança de contexto que matava minha criatividade. Eu poderia ter uma idéia bacana de design, nesse ponto, eu teria que mudar meu contexto para o arquivo CSS, começar a imaginar o elemento, nomear, pensar no box-model, implicações do DOM, etc. É como se minha criatividade fosse por água abaixo.

Agora, eu navego pelo HTML, escrevendo meus componentes e rápidamente mudando sua estrutura. Usando Basscss e algumas declarações específicas para a marca do produto, algo em torno de 75 linhas, fui capaz de construir a página inicial, com os componentes necessários em menos de uma hora, digamos que essa abordagem passou no meu teste de tempo!

Só isso já me passa uma tranquilidade para continuar usando essa abordagem. É meio viciante, e fica difícil querer voltar, como Jon Gold disse:

O melhor CSS, é o menor CSS possível — Jon Gold

De uma perspectiva do design, Functional CSS te liberta de tomar decisões relacionadas ao código enquanto você está criando o design. Aliás, as decisões já foram tomadas, e você está simplesmente mixando e encontrando padrões para alcançar o estilo que você deseja, do mesmo modo que você faz com shapes, cores e espaços no Sketch.

Transferibilidade

Na maioria dos projetos que trabalho hoje em dia, os times de designs e desenvolvimento tem um acordo de que, todo design tem que ter um protótipo em HTML/CSS e o time de desenvolvimento irá portar aquilo para o ambiente/produto real.

A eficiência que vimos com isso foi enorme.

Um protótipo disponibiliza ao time de design, feedback suficiente para melhorar os detalhes da interface sem precisar da dor de cabeça de aprender JavaScript ou frameworks como React e Angular.

O problema que nós encontramos nesse processo, é mais relacionado ao HTML, por exemplo, uma diretiva pode envolver seu componente em outra tag HTML e o CSS declarado não funciona do jeito esperado.

No passado, isso resultava em manter declarações específicas por app, para sobrescerver definições, e que, com o passar do tempo, só gerava mais bugs (e um CSS de má qualidade).

Usando Functional CSS, ajustes podem ser feitos simplesmente mudando uma classe no HTML. Isso permite que o time arrume bugs sem criar mais CSS.

Não consigo te dizer como isso é irado!

Escrever mais CSS para resolver os bugs do seu CSS, é o jeito errado de arrumar o seu CSS!

Pare de tomar decisões (ao menos, as desnecessárias!)

Basscss disponibiliza um padrão de espaçamento e utilitários de tamanhos. Eliminar opções é libertador. Permitindo apenas 8px, 16px, 26px, etc. como espaçamento, você simplesmente define as estratégias para pequeno/médio e grande, e pronto.

Mas você pode dizer “Ah, isso tira minha criatividade”. Mas te garanto, vai fazer sua vida muito mais fácil, como designer ou desenvolvedor. Você pode focar no verdadeiro problema.

A parte ruim

Antes de listar as partes ruins dessa do Functional CSS, eu quero deixar claro — no momento, esses itens são mais questões do que realmente críticas. Tenho certeza que pessoas mais inteligentes do que eu já acharam uma solução (ou justificativas) para esses problemas!

Perda da cascata

Como estamos usando pequenas classes específicas diretamente no HTML, isso significa que iremos perder todos os benefícios do efeito cascata. É incrível quando você cria seu primeiro componente, mas atualizar estilos em um sistema que já existe pode ser complicado, é uma mistura de “buscar e substituir” e outros atalhos.

Um jeito simples de atualizar estilos que estejam perto um do outro, no mesmo arquivo, é usar a opção de multi-cursor do seu editor. Assim como no Sublime Text e no Atom, você pode apertar ⌘-D (no Mac), para selecionar múltiplos textos:

Usando multi-cursor no Atom

Isso assume que você criou componentes semelhantes e que você esteja seguindo uma order de nomenclatura igual. Isso é nem importante, principalmente para buscar e substituir em vários arquivos. Fora isso, não é simples a busca em múltiplos arquivos dentro da sua aplicação para achar componentes similares.

Esse foi um dos, se não único, principais pontos ruins ao implementar Functional CSS em um app grande. Tente imaginar um componente comum como um “box” que é feito de 710 classes. Se você quiser atualizar o font-size de todas as “box”, você terá que procurar todas as declarações dentro do seu app.

Isso deixa um espaço para erros.

Reusabilidade de componentes

Com Funcional CSS, criar um “componente” é simples, bastar unir várias classes. Reusar esses componentes significa usar essas mesmas classes em lugares diferentes.

Mais uma vez: um espaço para erros.

A solução a longo prazo seria implementar algum tipo de guia de estilo para documentar todos os seus componentes e disponibilizar centralizadamente.

Documenta-los ainda tem o benefício de poder descrever as opções necessárias, tipos de classes para poder mixar e resultar em variações do mesmo componente, etc. Um exemplo, um componente ”Card” pode ter diferentes cores de fundo se simplesmente substituirmos a classe bg-color.

Combine isso com a perda do efeito cascata e a busca para atualizar os componentes. Foram alguns desafios que encontrei ao implementar Functional CSS.

Um jeito simples de arrumar isso, seria adicionar um nome de classe para seu componente, com a missão única de servir de âncora para quando você for buscar por instâncias desse componente no seu código.

Esses tipos de classe são simples de adicionar aqui e ali. Mas tenha absoluta certeza de não estar aplicando nenhum CSS nelas.

Design Responsivo

Se o seu design muda muito durante os breakpoints, o seu nome de classe será grande e verboso, com toda a certeza. Se possível, comece desde cedo declarar as unidades responsivas. Um exemplo class=”m2 md-m0”, esse elemento irá receber 2 unidades de espaço até atingir o breakpoint md, onde irá computar zero, a partir dali.

Eu encontrei uma situação no projeto que estava aplicando essas idéias, que a navegação se transformava em um slide menu em mobile, e em desktop era uma lista horizontal. Rapidamente, esse componente saiu fora de controle:

Vai por mim, foi só o começo, depois teve cores e tamanhos de fonte. Quando o seu design varia muito através dos breakpoints, pode ser desafiador implementar as classes necessárias (e como falamos acima, a ordem das suas classes começa a ser um problema também — vamos falar mais sobre isso já já)

Para combater isso, estabelecemos um padrão para lidar com a responsividade — convenção de nome, breakpoints e padrões para min-width e max-width.

Controlando estado

Uma situação comum é ter que esconder um componente por padrão e ao clicar em algo, mostra-lo. Escrevendo no padrão CSS monolítico, teríamos algo como:

One o JavaScript ficaria responsável por fazer o toggle da classe is-open. Agora, ao invés disso, meu JavaScript irá fazer o toggle da classe utilitária .block (ou similar):

Não é muito complicado em um pequeno componente, para quesistos de demonstração. Porém, mesmo nesse caso, você tem que ter certeza que .block irá sobrescrever .hide, ou remover .hide completamente via JavaScript. Em um componente mais complicado, vamos dizer que, onde as posições e estilos mudam também, é uma lista grande para lembrar de fazer o toggle no JavaScript.

Não vi um problema muito grande aqui, mas sem dúvida é mais fácil definir seu componente no CSS e trocar apenas uma classe.

Padrão de order de classes

Qualquer projeto com mais de um desenvolvedor, irá ter algum tipo de padrão em torno de como suas classes devem ser colocadas. Caso contrário, você irá lutar com qualquer definição de classe para saber o que está sendo declarado.

Pessoalmente, eu sou fã do Concentric CSS.

Não só a order das classes, mas seu time deve definir se irão agrupar todos os breakpoints ou não:

ou em order de propriedades:

E para falar a verdade, eu não tenho um preferido! 😄

Documentação

No meu CSS, seu tenho o costume de documentar algumas declarações e propriedades que não são tão comuns, como:

Eu até poderia criar uma classe imutável para esses hacks, mas a marcação HTML ficaria bem estranha, nesse caso, não há problema fugirmos à regra! :)

Conclusão

No geral, eu estou bem feliz utilizando uma abordagem funcional em CSS. É uma daquelas coisas que, quando você visualiza, você passa a prestar atenção e, toda vez que eu começo a escrever CSS de forma monolítica, meu cérebro já sinaliza um desinteresse desse modelo.

Algumas vezes eu me vejo desejando não escrever mais CSS. Eu quero escrever algumas classes no início do projeto e formar o design a partir da união desses blocos. Ter que tomar decisões no meio do projeto, passa aquela sensação de “está fora do lugar” — as vezes passamos muito tempo escrevendo CSS do que arrumando problemas de usabilidade (do design, nesse caso).

Eu realmente gostaria de saber sua opinião, e caso você já tenha usado essa abordagem, compartilha nos comentários!

Caso você queria saber mais sobre Funcional CSS, eu recomendo você seguir os feras do assunto Adam Morse, Jon Gold, Brent Jackson e Marcelo Somers

Créditos

--

--