Assinar
Voltar
Frontend

CSS if(): condicionais nativas sem JavaScript nem @supports aninhado

Chrome e Edge 137 já implementam a função if() do CSS, que condiciona valores a media queries, feature queries e style queries dentro da própria declaração. A sintaxe, o fallback e por que ainda não dá para depender dela.

</>

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

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *