Depois de anos combinando @media, @supports e variáveis para simular lógica condicional em CSS, chegou uma função que faz isso diretamente dentro do valor de uma propriedade: a if(). Ela já roda no Chrome e no Edge (a partir da versão 137) e está documentada no MDN, mas ainda não é Baseline: Safari e Firefox ainda não implementam. Vale entender a sintaxe agora, porque ela resolve um problema real de verbosidade em CSS moderno.
O problema que o if() resolve
Hoje, para aplicar um valor diferente dependendo de um breakpoint, de suporte a uma feature ou do estado de um elemento, o caminho comum é duplicar a regra inteira dentro de um bloco condicional:
.card {
background-color: white;
}
@media (prefers-color-scheme: dark) {
.card {
background-color: black;
}
}
Para uma única propriedade, isso significa reescrever o seletor inteiro só para trocar um valor. Com if(), a condição fica embutida no próprio valor da propriedade, sem duplicar a regra:
.card {
background-color: if(
media(prefers-color-scheme: dark): black;
else: white;
);
}
Sintaxe: pares condição-valor, separados por ponto e vírgula
A estrutura geral é uma lista de pares condição: valor, terminando opcionalmente em um else que funciona como padrão quando nenhuma condição bate:
propriedade: if(
condicao-1: valor-1;
condicao-2: valor-2;
else: valor-padrao;
);
Repare que o separador entre os pares é ponto e vírgula, não vírgula, e isso evita ambiguidade quando o próprio valor já usa vírgulas, como em rgb(0, 0, 0) ou em uma lista de font-family. Também não pode haver espaço entre if e o parêntese que abre a função, senão o parser não reconhece como chamada de função.
Três tipos de condição: media(), supports() e style()
O if() aceita três formas de teste, cada uma reaproveitando a sintaxe de uma regra at-rule já existente:
- media(…): mesma sintaxe de uma media query, para testar viewport,
prefers-color-scheme, orientação etc.
- supports(…): mesma sintaxe de
@supports, para testar se o navegador entende uma propriedade ou valor específico.
- style(…): mesma sintaxe de uma style query de container, testando o valor de uma custom property no próprio elemento ou em um ancestral.
A combinação com style() é a mais interessante para componentes reativos a estado, porque dá para guardar o “estado” em uma custom property (por exemplo, via atributo data-* ou classe) e ler esse estado direto na declaração:
.progress-card {
border-color: if(
style(--status: pending): orange;
style(--status: complete): green;
else: gray;
);
}
O if() não substitui @media ou @supports como blocos. Ele resolve o caso comum de “só quero trocar um valor”, sem precisar reabrir o seletor inteiro.
Suporte de navegador: ainda não é Baseline
Em julho de 2026, o suporte real ainda é parcial: Chrome e Edge implementam if() a partir da versão 137, enquanto Safari e Firefox ainda não têm suporte. O Can I Use reporta cobertura global em torno de 68% dos navegadores em uso, o suficiente para experimentar, insuficiente para depender dele sem plano B em produção. A própria documentação do MDN, atualizada em abril de 2026, marca a feature como não-Baseline justamente por essa lacuna entre navegadores.
Como usar hoje sem quebrar quem não suporta
A recomendação da comunidade é tratar if() como progressive enhancement: declare primeiro um valor de fallback “normal” e, depois, sobrescreva com if() dentro de um bloco @supports que testa a própria função:
.card {
background-color: white; /* fallback para quem não suporta if() */
}
@supports (background-color: if(media(width > 0px): red; else: blue)) {
.card {
background-color: if(
media(prefers-color-scheme: dark): black;
else: white;
);
}
}
Esse padrão, testar a própria sintaxe do if() dentro de um @supports, é necessário porque navegadores antigos simplesmente ignoram a declaração inteira quando não reconhecem a função, então sem o fallback declarado antes, o elemento fica sem nenhum valor para essa propriedade nesses navegadores.
Vale adotar agora?
Para times que controlam o ambiente de execução (aplicações internas, PWAs corporativas, extensões restritas a Chromium) o if() já reduz CSS duplicado hoje. Para sites públicos com audiência ampla, o caminho mais seguro é observar a evolução do suporte no Safari e no Firefox e, enquanto isso, usar o padrão de fallback com @supports, ou continuar com @media/@supports tradicionais, que continuam funcionando e não vão a lugar nenhum.
Combinando com container queries
Um uso prático que já aparece em experimentos da comunidade é combinar style() com container queries existentes: um componente dentro de um container-type: inline-size pode ler tanto o tamanho do container quanto uma custom property de tema, resolvendo em uma única declaração uma combinação que hoje exigiria aninhar @container dentro de @supports dentro de uma classe condicional aplicada via JavaScript. É esse tipo de aninhamento que o if() promete eliminar. Não a lógica em si, mas a duplicação de seletores para expressá-la.
Vale também lembrar que if() é uma função de valor, não de seletor: ela não substitui o :has() nem outras formas de seleção condicional, e sim o “qual valor essa propriedade recebe” dentro de uma regra que já existe.
Fontes