CSS moderno: a cor calculada, o :is() e o aninhamento
Há uma linha no CSS deste site que resume o que mudou no CSS da última década:
--cor-tag: oklch(0.45 0.13 var(--tom-tag, 144));Uma propriedade personalizada a servir de argumento a uma função de cor. Não é um valor com nome — é uma entrada num cálculo que o browser faz.
1. O que aquela linha resolve
Cada etiqueta do blogue guarda um número na base de dados: onde cai no círculo cromático, de 0 a 359. Mais nada. A luminosidade (0.45) e o croma (0.13) estão fixos no CSS, iguais para todas.
A consequência é a parte boa: quem cria uma etiqueta escolhe o tom, e não tem como escolher mal. O contraste está garantido para qualquer um dos 360 valores, porque os dois números que o determinam não estão à escolha de ninguém. E o 144 dentro do var() é o valor de recurso — o verde da casa, para quando o tom não está definido.
Isto só funciona em oklch. Em HSL, a mesma luminosidade dá cores com claridade percebida muito diferente conforme o tom — um amarelo a 50% salta, um azul a 50% afunda. No oklch a luminosidade é perceptual, e 0.45 pesa o mesmo em todo o círculo. É o que torna a garantia possível, e é a razão de ser do espaço de cor, não um detalhe de sintaxe.
E o que fica dito por omissão: não há JavaScript nenhum nisto. A cor é calculada onde devia ser, que é no CSS.
2. :is() e :where(), e a única diferença que importa
/* Em vez de tres seletores repetidos */
:is(h1, h2, h3) > code { font-size: 0.9em; }Encurtam listas, o que é cómodo. O que interessa é a diferença entre os dois: o :is() assume a especificidade mais alta dos seus argumentos; o :where() tem especificidade zero, sempre.
Daí a regra prática: :where() para estilos de base, que se querem fáceis de sobrepor; :is() quando se quer mesmo ganhar. Escrever :is() onde se queria :where() produz aquela folha que obriga a um !important três meses depois.
3. Aninhamento, agora nativo
.cartao {
border: 1px solid var(--border);
&:hover { background: var(--accent); }
h3 { font-weight: 600; }
}Deixou de ser preciso um pré-processador para isto. Com o aviso que o Sass já devia ter ensinado: o aninhamento é a nova especificidade. Três níveis produzem um seletor que ninguém sobrepõe sem brigar, e a profundidade esconde-o — na folha parecem três linhas arrumadas.
Dois níveis, e o & para estados. Daí para baixo, uma classe nova sai mais barato.
4. Container queries: a pergunta certa
Uma media query pergunta pelo tamanho da janela. Quase sempre, o que o componente precisa de saber é o seu próprio tamanho — e as duas coisas só coincidem enquanto ele ocupar a largura toda.
.lista { container-type: inline-size; }
@container (min-width: 24rem) {
.cartao { display: grid; grid-template-columns: auto 1fr; }
}Este site ainda não as usa, e há um sítio onde dariam jeito imediato: os cartões do «Continuar a ler», que aparecem numa coluna em ecrã pequeno e em duas no resto. Hoje a decisão está escrita em função da janela; o cartão é que sabe se tem 300 ou 600 píxeis.
A diferença de fundo é que um componente passa a poder ser colocado em qualquer sítio e adaptar-se — em vez de trazer consigo um conjunto de suposições sobre onde é que vai aparecer.
5. Duas de uma linha cada
color-mix()— misturar duas cores no CSS, sem gerar variantes à mão:color-mix(in oklab, var(--cor) 20%, transparent)é um fundo esbatido da mesma cor, sem uma variável nova.:has()— o seletor que faltava, e que já teve artigo próprio: permite estilizar um elemento pelo que ele contém.
O resumo
O que estas peças têm em comum não é serem novas — é tirarem lógica ao JavaScript. Uma propriedade personalizada dentro de uma função de cor transforma um número guardado na base numa cor com contraste garantido, sem uma linha de código a correr no browser. É aí que o CSS moderno paga, e não nas chaves que poupa.