CUBE CSS é uma metodologia CSS orientada à simplicidade, pragmatismo e consistência. Ela foi projetada para funcionar com o meio em que se trabalha — geralmente, o navegador — e não contra ele.
Mesmo que no próprio site oficial do CUBE CSS conste que, no momento, trata-se de um work in progress, não fará mal algum já apresentar e explorar esta nova e interessante metodologia CSS.
O que é CUBE CSS
CUBE CSS é uma nova metodologia CSS. Na verdade, “CUBE” é uma sigla para Composition, Utility, Block e Exception, que fazem parte da nomenclatura e estruturas-base para se trabalhar com CUBE CSS.
O nome da metodologia indica imediatamente sua função: trata-se de uma espécie de extensão do CSS em vez de uma reinvenção do CSS. A parte “CUBE” estende o que já existe no “CSS”.
Como CUBE CSS se compara a outras metodologias
Ao comparar metodologias CSS, seria seguro dizer que CUBE CSS tira a maior parte de sua inspiração de BEM — mas, claro, com o que achou por bem alterar/aprimorar.
O núcleo do BEM é o Bloco, enquanto o núcleo do CUBE CSS é o próprio CSS: Cascata e a Herança são adotadas, não evitadas. Então, quando se chega aos Blocos na CUBE CSS, eles têm uma função bem diversa.
CUBE CSS é escalável?
Assim como CSS, CUBE CSS escala perfeitamente bem e pode ser usado para desenvolver pequenos blogs, sites gigantescos, aplicativos móveis e até software para intranets. Enfim, praticamente qualquer projeto Web.
Essa metodologia tem raízes em grandes projetos que atendem a milhões de pessoas até pequenos sites e kits iniciais, graças à sua flexibilidade. Essa flexibilidade também permite que CUBE CSS funcione desde bases de código muito antigas até muito novas.
Princípios da CUBE CSS
Um dos princípios gerais da CUBE CSS é a simplicidade. Existem muitos benefícios em permitir que as ferramentas certas façam seu trabalho sem nenhuma intervenção/interferência.
Mas CUBE CSS adota e foi construída em cima de princípios Web muito mais específicos e igualmente eficientes.
Progressive Enhancement
O visitante acessa por um navegador antigo? Isso não é um problema com CUBE CSS, porque Progressive Enhancement (Aprimoramento Progressivo) faz parte de seu núcleo.
Ao criar uma Experiência Mínima Viável (EMV), contabiliza-se navegadores muito antigos por padrão, estendendo essa EMV através de recursos mais modernos, como Flexbox e CSS Grid, sem medo de que eles não sejam suportados.
Sem hacks nem polyfills, escreve-se muito menos CSS usando o núcleo progressivo da metodologia CUBE CSS.
Abstração somente quando necessário
Essa simplicidade básica também exige uma redução na abstração. Usando CSS para o que é bom, atribui-se a maioria das regras de estilo a um nível superior, que são suportadas por Estilos de Composição (Composition Styles), Utilitários (Utilities) e, finalmente, Blocos (Blocks) e Exceções (Exceptions).
CUBE CSS possui uma estrutura muito plana (flat) e inclusiva, o que torna previsível e bastante fácil de se começar a trabalhar (mesmo para novatos).
Compatível com qualquer tecnologia CSS
Se você deseja criar seu CSS com Sass, Less, PostCSS ou mesmo CSS-in-JS, os princípios e a metodologia de CUBE CSS permanecem.
A CUBE CSS é totalmente independente de ferramentas, tratando-se mais de uma metodologia organizacional (e de mindset), do que uma metodologia de ferramentas.
Desde que o resultado gerado por qualquer ferramenta seja CSS, tudo ficará bem.
CUBE CSS e CSS
O núcleo de CUBE CSS é o próprio CSS. Onde outras metodologias podem contornar o CSS — ou, em alguns casos, evitá-lo completamente –, CUBE CSS o adota.
CSS é uma linguagem incrivelmente complexa porque existe muito conhecimento sobre como ela funciona — não apenas sobre escrita/sintaxe –, o que é compreensivelmente difícil quando alguém está acostumado a outras linguagens que quebram e/ou geram erros, como JavaScript.
Metodologia Progressive First
Assim como mencionado, adotar uma natureza progressiva do CSS é uma grande parte do que confere à CUBE CSS poder, enquanto metodologia.
Com CUBE CSS, adota-se a Cascata e a Herança para estilizar o máximo possível em alto nível. Isso significa que, quando nada além de estilos globais chegam ao navegador, a página ainda ficará ótima. É Progressive Enhancement em ação permitindo escrever o mínimo de CSS possível.
CUBE CSS, em essência, é uma abordagem de aprimoramento progressivo versus uma luta contra a granularidade do CSS.
É por isso que o próprio CSS é a parte mais importante da metodologia CUBE CSS.
C: Composição (Composition)
Como assinalado, “CUBE” é uma sigla para Composition, Utility, Block e Exception, que fazem parte da nomenclatura e estruturas-base para se trabalhar com CUBE CSS.
A camada de Composição (Composition) estende o CSS e é uma visualização macro de alto nível — mesmo quando aplicada em contextos menores, a nível de componente.
O trabalho da camada de Composição é criar sistemas de layout flexíveis e independentes de componentes que suportem tantas variantes de conteúdo quanto possível.
Isso está relacionado ao princípio de que o navegador deve ser sugerido (hinted) com regras CSS flexíveis, ao invés de ser microgerenciado com regras CSS estritas.
Com a camada de Composição, sugere-se regras de layout e permite-se que o navegador faça os julgamentos corretos com base no contexto em que se encontra.
Por que pensar em nível macro?
Mesmo quando se está trabalhando com componentes minúsculos e reutilizáveis, é necessário, em algum momento, considerar como eles serão aplicados em um contexto maior: como uma página ou view.
A camada de Composição foi projetada para ajudar esse processo, fornecendo uma estrutura de “layout-esqueleto” (skeletal layout) que não deve interferir nos componentes (ou Bloco, no contexto de CUBE CSS) que são apresentados, mas também suportam qualquer variante de um componente.
O que a camada de Composição deve e não deve fazer?
O que a camada de Composição deve fazer é:
- Fornecer layouts flexíveis e de alto nível;
- Determinar como os elementos interagem entre si;
- Criar fluxo consistente (consistent flow) e ritmo.
O que a camada de Composição não deve fazer é:
- Tratamento visual, como estilo de cor ou fonte;
- Estilos decorativos, como sombras e padrões;
- Forçar o navegador a gerar layouts pixel-perfect em vez de um layout flexível e progressivo.
Exemplos
Aqui estão 2 exemplos simples de Composição. Primeiro, um layout tradicional e, segundo, uma solução flexível com ritmo e fluxo.
Layout
Eis um exemplo de um layout clássico:
Temos aqui vários elementos que são componentes individuais. A composição desse layout é o que controla o layout geral e o ritmo dos elementos. Pense na composição como um esqueleto (ou wireframe).
Para ficar mais claro, é possível colocar quaisquer componentes que seja preciso no esqueleto. Como neste exemplo, em que um cartão foi substituído por uma CTA:
Fluxo e ritmo
Para criar fluxo (flow) e ritmo (rhythm) entre os elementos, é possível usar a camada de Composição para gerar uma regra em que os elementos-irmãos aplicam uma margem definida globalmente ou contextualmente — usando o famoso seletor coruja (owl selector).
1 2 3 |
.flow > * + * { margin-top: var(--flow-space, 1em); } |
Em seguida, usando o exemplo do cartão, aplicaria-se:
1 2 3 4 5 6 |
<article class="card"> <img class="card__image" alt="" /> <div class="[ card__content ] [ flow ]"> <!-- conteúdo agora com auto-flow --> </div> </article> |
Isso significa que agora cada elemento dentro de card__content
terá uma margem superior de 1em, a menos que --flow-space
esteja definido.
É possível, então, definir --flow-space
no contexto, como em:
1 2 3 |
.card__content { --flow-space: 1.4rem; } |
Como --flow-space
é definido no contexto, é possível obter um espaçamento maior.
U: Utilitário (Utility)
Um Utilitário (Utility), no contexto do CUBE CSS, é uma classe CSS que executa um trabalho e executa bem esse único trabalho.
Essa classe CSS — preferencialmente uma classe — terá apenas uma propriedade CSS definida, como uma cor de background, por exemplo.
Também pode ter algumas propriedades CSS definidas em um grupo conciso, como este exemplo de utilitário de wrapper:
1 2 3 4 5 |
.wrapper { margin-inline: auto; padding-inline: 1rem; max-width: 60rem; } |
Este utilitário prático fornece um contêiner de largura máxima que fica no meio da viewport quando esta tem mais de 60rem de largura.
Um trabalho. Bem feito.
CSS Baseado em Token (Token-based CSS)
CUBE CSS funciona extremamente bem em design systems porque a camada Utilitário trabalha lado-a-lado com design tokens.
Design Tokens (frequentemente) serão definidos fora da base de código CSS; portanto, para usá-los com a metodologia CUBE CSS, é recomendável gerar classes de Utilitário.
Neste exemplo, digamos que se tenha um conjunto de design tokens definidos em um arquivo JSON como este:
1 2 3 4 5 6 7 |
{ "colors": { "primary": "#ff00ff", "secondary": "#ffbf81", "base": "#252525" } } |
Seria possível gerar classes de Utilitários que representam cada token em uma propriedade CSS — usando uma ferramenta como a mostrada à frente.
Por exemplo, aqui estão algumas classes de utilidade de cor e plano de fundo resultantes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
.bg-primary { background: #ff00ff; } .bg-secondary { background: #ffbf81; } .color-primary { color: #ff00ff; } .color-secondary { color: #ffbf81; } |
Com essas classes geradas, bastaria somente aplicar ao HTML:
1 |
<article class="bg-primary color-base"></article> |
A aplicação dos design tokens como estes permite definir as coisas uma vez e aplicá-las em qualquer lugar — mantendo a premissa de que os design tokens fazem parte de uma single source of truth (fonte única de verdade).
O que a camada de Utilitário deve e não deve fazer?
O que a camada de Utilitário deve fazer é:
- Aplicar uma única propriedade CSS ou um grupo conciso de propriedades relacionadas para criar utilitários reutilizáveis;
- Estender design tokens para manter uma única fonte de verdade;
- Afastar repetições abstratas do CSS (deixando para a HTML).
O que a camada de Utilitário não deve fazer é:
- Definir um grande grupo de propriedades CSS não-relacionadas. Por exemplo, um Utilitário que definisse cor, tamanho da fonte e padding faria mais sentido ser um Bloco (que será visto a seguir);
- Ser usado como um hack de especificidade. Por exemplo, definir todas as propriedades com
!important
sem dúvida causaria problemas a longo prazo (ou antes disso).
B: Bloco (Block)
Um Bloco (Block) é um componente-esquelo ou estrutura organizacional. Exemplos para compará-lo a elementos comuns da UI: um do cartão ou um botão.
Um Bloco é “esquelético” porque, quando se chega ao nível do Bloco em CUBE CSS, a maior parte do trabalho já foi realizada pelas camadas globais de CSS, Composição e Utilitário.
Isso significa que o papel de um Bloco é menos semelhante a BEM, onde tudo é estilizado dentro de um Bloco; em vez disso, é um mecanismo de execução na contramão das camadas globais de CSS, Composição e Utilitário.
Isso cria um grupo de regras leve, mas específico, que se aplica apenas nesse contexto.
Sem sintaxe fixa/formal
Em BEM, o nome de um elemento (Bloco) contém um duplo underscore: .my-block__my-element
. Em CUBE CSS, essa convenção de nome não precisa ser aplicada se você não quiser.
Isso acontece porque, novamente, quando você chega ao nível de Bloco de CUBE CSS, a maior parte do trabalho já foi realizada pelas camadas globais de CSS, Composição e Utilitário, de modo que a declaração formal do elemento é redundante.
Dentro de um Bloco é possível fazer o que se quiser porque existe uma “rede de segurança” da classe do bloco-pai (.my-block
) que adiciona um ponto de especificidade extra.
Com tudo isso em mente, é possível haver seletores parecidos com:
1 2 3 4 5 6 7 8 |
.my-block { } .my-block .image { } .my-block .content { } |
Sendo possível até trabalhar diretamente com elementos HTML:
1 2 3 4 5 6 7 8 |
.my-block { } .my-block img { } .my-block article { } |
O importante aqui é a consistência. Como você alcança essa consistência é com você (e/ou sua equipe).
Composição com Blocos
É recomendável que se aproxime as partes internas de um Bloco com uma camada de Composição. Vamos a um card de exemplo.
Dentro da área de conteúdo deste card, há um cabeçalho e algum conteúdo. Usando um Utilitário de fluxo, é possível ter uma camada de Composição a nível de bloco (block-level), o que significa que qualquer conteúdo deve ser suportado nesse elemento.
Isso tudo está relacionado a sugerir ao navegador regras flexíveis, em vez de microgerenciá-lo. Esse mantra é o motivo pelo qual o CUBE CSS ajuda a criar frontends realmente escaláveis.
O que a camada de Bloco deve e não deve fazer?
O que um Bloco deve fazer é:
- Ampliar o trabalho já realizado pelas camadas globais de CSS, Composição e Utilitário;
- Aplicar uma coleção de design tokens em um grupo conciso;
- Criar um “namespace” (não confundir com Namespaces CSS) ou aumento de especificidade para controlar um contexto específico.
O que um Bloco não deve fazer é:
- Crescer ao ponto de ficar maior que um punhado de regras CSS (máximo de 80 a 100 linhas);
- Resolver mais de um problema contextual (por exemplo: estilizando um cartão e um botão em um arquivo).
E: Exceção (Exception)
A última parte da CUBE CSS são as Exceções. Uma Exceção (Exception) é um desvio das regras descritas em um Bloco.
Geralmente, uma Exceção está relacionada a uma mudança de estado. Por exemplo: você pode ter um estado “invertido” ou “inativo” — pense nos Modificadores de BEM.
Fazendo um outro exemplo de card, ele ficaria assim:
Adiciona-se uma Exceção usando um atributo data-*
como:
1 |
<article class="card" data-state="reversed"></article> |
Isso fornece um hook útil para ambos, CSS e JavaScript. É possível aplicar a Exceção no CSS da seguinte maneira:
1 2 3 4 |
.card[data-state='reversed'] { display: flex; flex-direction: column-reverse; } |
Que resultaria em algo como:
Por que atributos data-*
?
Usa-se atributos data-*
porque uma Exceção só deve ocorrer em circunstâncias excepcionais (o nome da coisa já dá uma pista). Como a Exceção geralmente é causada por influência externa (como JavaScript), também faz sentido um mecanismo que CSS e JavaScript possam usar com eficiência.
O objetivo da metodologia CUBE CSS é a clareza e separar Exceções em atributos data-*
contribui precisamente com isso.
O que uma Exceção deve e não deve fazer?
O que uma Exceção deve fazer é:
- Prover uma variação concisa para um Bloco
- Usar atributos
data-*
O que uma Exceção não deve fazer é:
- Variar tanto um Bloco que ele não seja mais reconhecível (é neste ponto que um novo Bloco deve ser criado)
- Usar classes CSS
Agrupamento
Muita coisa pode estar acontecendo no atributo class
quando se usa CUBE CSS, portanto, é recomendável que você use um mecanismo de Agrupamento (Grouping) para o atributo HTML class
.
1 2 3 4 |
<article class="[ card ] [ section box ] [ bg-base color-primary ]" data-state="reversed" ></article> |
Ordem do Agrupamento
Não exite ordem fixa para o Agrupamento; o importante é que classes relacionadas essejam agrupadas.
Mas uma ordem recomendada é a seguinte:
- Classe de Bloco principal
- Quaisquer classes subsequentes de Bloco
- Classes de Utilitário
- Classes de Utilitários de design token
Não precisa ser colchetes
Se você não gostou da sintaxe com colchetes, pode usar algo como pipes:
1 2 3 4 |
<article class="card | section box | bg-base color-primary" data-state="reversed" ></article> |
O nome do jogo é: consistência
Quer você escolha colchetes, pipes ou unicórnios, a prioridade é consistência e facilidade de leitura.
HTML e CSS suportam a maioria das opções, portanto, encontrar um equilíbrio entre a experiência do desenvolvedor (DX) e a comunicação da equipe é o objetivo do Agrupamento.
Ferramentas úteis
Veja algumas ferramentas úteis para se trabalhar com CUBE CSS:
- Gorko é uma biblioteca Sass que gera classes de Utilitário com base em uma configuração de design token;
- Goron é semelhante ao Gorko, mas usa JSON e Node.js;
- Tailwind CSS é um framework e gerador de classes de Utilitários;
- Style Dictionary é um sistema de design token;
- Theo é um sistema de design token.
Conclusão
CUBE CSS é uma nova metodologia CSS, chegando ao cenário frontend de maneira nada modesta, já com bases sólidas, robustez, ferramental e até uma comunidade já se formando o redor.
Se este é seu primeiro contato com CUBE CSS, não se precipite ao julgá-lo bom ou ruim logo de cara. Releia o artigo algumas vezes, deixe os conceitos amadurecerem em sua mente, consulte recursos e projetos já feitos usando a metodologia e, o mais importante, brinque com CUBE CSS. :)
Fazer 1 ou 2 projetinhos por diversão ajudará a consolidar sua opinião sobre a CUBE CSS. Seja ela qual for.