CSS Blocks: introdução à API

Veja neste artigo uma introdução à API de CSS Blocks e comece a entender porque este é um dos melhores compiladores CSS da atualidade.

CSS Blocks logo

No primeiro artigo sobre CSS Blocks (o primeiro brasuca, aliás!) apresentamos o otimizador de CSS da LinkedIn, explicando um pouco sobre o porquê de sua existência e seus princípios-base. Agora, vamos a mais algumas explicações de código para entender melhor o que CSS Blocks é capaz de fazer.

Como uma breve recapitulação, CSS Blocks é um compilador inspirado em CSS Modules, BEM e Atomic CSS que, usando o OptiCSS, promete entregar estilos bem mais enxutos e performáticos. No momento da publicação deste artigo, é possível usá-lo nas templating languages JSX/React e Glimmer (com WebpackBroccoli ou Ember-CLI) — por se tratar de um projeto open source, a tendência é que mais e mais opções surjam bem rapidamente.

O que é um “Bloco”?

O nome da coisa é CSS Blocks, “Blocos CSS”; mas, segundo a metáfora de desenvolvimento escolhida, o que seria um “Bloco”?

Um Bloco é uma folha de estilo isolada, escrita em seu próprio arquivo, que contém todos os conjuntos de regras para quaisquer elementos e seus vários modos e estados de interação para uma unidade discreta de estilo — como um componente, por exemplo.

Normalmente, um único bloco conterá estilos para um componente ou conceito específico, mas é totalmente natural — e incentivado — um template usar vários Blocos e os compor juntos na marcação.

Um Bloco pode conter:

  • Seletor :scope
  • Seletores de classe
  • Seletores de estado
  • Seletores de sub-estado

Seletor :scope

O conjunto de regras de escopo contém estilos aplicados à raiz da sub-árvore de estilo com escopo. Trocando em miúdos, todos os outros elementos atribuídos a estilos de um Bloco devem estar contidos na sub-árvore do documento de um elemento atribuído ao escopo desse Bloco. Usa-se a pseudo-classe :scope para representar esses estilos.

O seletor :scope pode conter a propriedade especial block-name que torna possível fornecer um nome específico para o Bloco para um debugging mais fácil e respectiva geração de classe BEM. Se nenhum nome de bloco for fornecido, infere-se o nome do bloco a partir do nome do arquivo.

Por exemplo:

Seletores de classe

Blocos podem conter outras classes que podem ser aplicadas a elementos dentro da sub-árvore de estilo escopada. São apenas seletores de classe comuns, mas são locais para esse Bloco e isolados de todas as outras classes com nomes iguais em outros Blocos.

Juntos, o seletor :scope e todos os seletores de classe (.class) declarados definem a interface completa dos elementos estilizados disponíveis para quem vai usar um Bloco.

Seletores de Estado

Estados representam um modo ou estado de interação no qual :scope ou uma classe — denominada Elemento Originário do Estado — pode estar. Os Estados são gravados como seletores de atributos com o namespace especial state.

Seletores de sub-estado

Estados no seletor :scope ou um seletor de classe podem conter sub-estados para um estilo mais granular. Os sub-estados de um Estado são mutuamente exclusivos, ou seja, um elemento só pode estar em um sub-estado de um Estado por vez.

Restrições na API de CSS Blocks

CSS Blocks implementa um subconjunto estrito de CSS. Isso significa que alguns dos recursos que normalmente poderiam ser usados em um arquivo em um arquivo de Bloco foram intencionalmente restringidos para garantir que a compilação final possa gerar estilos da maneira mais otimizada possível.

Para ficar claro:

  • Permitido:
  • Proibido (por enquanto):
    • !important (você já deveria tê-lo banido, de qualquer maneira)
    • tag, [attribute] que não seja de Estado, #id e seletores *
    • Os Combinadores Lógicos :matches(), :not(), :something() e :has()
    • Importante: seletores devem se manter rasos (shallow)

No contexto de CSS Blocks, “seletores rasos” significa:

Apenas 1 combinador por seletor

Seletores de Combinadores Hierárquicos (” “ e “>“) devem ser um estado de :scope, sub-estados ou pseudo-classes

Seletores de irmão (“+” e “~“) devem ter como target a mesma classe ou :scope usado no seletor-chave

Como todo o código é analisado e compilado estaticamente (statically) antes de atingir o navegador, obviamente um erro bastante útil será gerado caso alguma dessas restrições de sintaxe seja violada.

Conclusão

É difícil tentar decorar todas essas peculiaridades; com o tempo de uso de CSS Blocks, naturalmente isso vai se internalizar. De qualquer maneira, é bom saber que existe uma tabela bem útil mostrando o que é permitido e proibido na API — que, devido à incipiência de CSS Blocks, deve ser alterada (para melhor) bem rapidinho e com bastante frequência.

Para ficar claro, eis o que acontece na fase de Compilação de CSS Blocks:

CSS Blocks: exemplo de compilação de código

O processo de otimização vai além; existem mais passos até que o output final aconteça — ou você achou que CSS Blocks servia só para escrever BEM de maneira mais complicadinha? Mas isso já é assunto para outro artigo…

Fique ligado nas novidades do desenvolvimento para web para não perder nada!