Assinar
Voltar
Frontend

O @supports sempre testou sintaxe, não comportamento. O named-feature() testa, e a lista inteira tem dois nomes

A feature query do CSS nunca soube dizer se o navegador faz a coisa funcionar, só se ele consegue analisar a declaração. O named-feature() chegou ao Chrome 150 para resolver isso, com um registro fechado que o CSS Working Group promete aumentar raramente.

</>

O @supports tem uma limitação que quase todo mundo já esbarrou sem nomear: ele não testa se o navegador faz a coisa funcionar. Ele testa se o navegador consegue ler a declaração sem jogar fora. São coisas diferentes, e a distância entre as duas é onde mora um tipo de bug que nenhum fallback pega.

O caso clássico é align-content em display: block. A propriedade existe há anos, e por isso @supports (align-content: stretch) devolve verdadeiro em qualquer navegador moderno. O que mudou recentemente foi ela passar a ter efeito em contexto de bloco, e não existe consulta que separe um navegador do outro: os dois analisam a mesma sintaxe com sucesso.

A função named-feature(), que chegou ao Chrome 150 em 30 de junho, é a resposta do CSS Working Group para isso. A posição deste post: ela é uma correção honesta e bem desenhada, e ao mesmo tempo é a admissão pública de que detecção de recurso genérica não vai existir. A lista inteira de nomes reconhecidos tem duas entradas hoje, e o grupo escreveu na especificação que pretende aumentá-la raramente.

O problema que o @supports não resolve por construção

O explicador da proposta é direto sobre o motivo. O @supports dá conta quando o tratamento de erro do CSS já resolve, ou seja, quando a declaração nova é simplesmente descartada por quem não a conhece. Ele falha quando, nas palavras do documento, os desenvolvedores precisam que outros pedaços de CSS sejam ignorados junto com a sintaxe nova, para que os estilos funcionem em conjunto dependendo de o recurso ter suporte ou não.

A categoria de recurso indetectável é descrita assim: um pedaço de sintaxe CSS pode passar a funcionar numa situação nova, onde antes não funcionava, como num novo tipo de display ou num novo tipo de elemento. A sintaxe é a mesma. O comportamento é que mudou.

A saída óbvia seria uma consulta combinatória, algo como testar a propriedade junto com o contexto:

/* proposta que foi rejeitada */
@supports (align-content: stretch) with (display: block) { }

O explicador rejeita essa forma com um argumento de escala que é difícil de contestar: existem milhões de combinações e não existe fonte de dados que defina quais delas são significativas. Padronizar, implementar, testar e conseguir interoperabilidade em cima disso é inviável, e uma lista mal mantida de combinações seria pior que nenhuma.

A gramática, e a parte que decide tudo

A sintaxe é a mais simples possível:

<supports-named-feature-fn> = named-feature( <ident> )

O resultado é verdadeiro se o user agent suporta o recurso nomeado passado como argumento. E aqui vem a frase que define o caráter da função: se o recurso não estiver listado, o processador não suporta o recurso nomeado.

Ou seja, o identificador não é livre. Não é uma string que a engine interpreta contra o próprio comportamento, é uma chave de um registro fechado que vive na especificação. Um nome inventado por você não devolve erro de sintaxe nem verdadeiro por otimismo: devolve falso, sempre, em todo navegador.

Os dois nomes definidos hoje na CSS Conditional Rules Level 5 são:

  • anchor-position-follows-transforms, para saber se a ancoragem a elementos transformados leva as transformações em conta.
  • single-axis-scroll-container, para a capacidade de ter rolagem em um eixo com o outro recortado.

Uso real fica assim:

@supports named-feature(single-axis-scroll-container) {
  .galeria {
    overflow-x: auto;
    overflow-y: clip;
  }
}

@supports not named-feature(single-axis-scroll-container) {
  .galeria {
    overflow: auto;
  }
}

E a especificação declara a política de crescimento sem rodeio: o grupo pretende adicionar recursos a essa lista raramente, quando houver demanda real por testar algo específico.

Por que isso é a decisão certa e ainda assim frustra

É a decisão certa porque a alternativa é uma superfície de API infinita que nenhum fornecedor conseguiria implementar de forma consistente. Um @supports que responde qualquer pergunta é um @supports que responde errado em algum lugar, e feature query que mente é pior que ausência de feature query, porque o desenvolvedor confia nela.

E frustra porque a probabilidade de o seu caso concreto estar entre os dois nomes registrados é baixa. Na prática, para quase tudo, a resposta continua sendo a de sempre: escreva CSS que degrada bem, use @supports para o que é detectável por sintaxe, e aceite que comportamento novo em contexto antigo não tem detecção.

Vale reparar que a mesma seção da especificação traz funções vizinhas que muita gente vai usar mais no dia a dia: at-rule(), que devolve verdadeiro se o user agent suporta a at-rule passada como argumento, além de font-tech() e font-format(). Detectar @container ou @scope por at-rule(@container) resolve um incômodo bem mais comum que os dois nomes do registro.

Onde está cada navegador

O Chrome descreve a função como uma forma de consultar um pequeno conjunto de recursos nomeados que não é possível testar pelos outros mecanismos do @supports, mas cujo teste é considerado muito valioso. Ela está disponível a partir do Chrome 150, estável desde 30 de junho de 2026.

A proposta é de dbaron e foi levada aos dois outros fornecedores em 15 de janeiro de 2026. A Mozilla registrou posição positiva na issue 1340 do repositório de standards-positions. A issue 600 do repositório da WebKit segue sem posição declarada até agora.

Isso significa uma coisa prática: por enquanto named-feature() responde falso em Firefox e em Safari, o que é exatamente o comportamento correto para uma feature query e não te obriga a nada. O bloco @supports not named-feature(...) vira o caminho universal fora do Chrome, e o bloco positivo vira progressive enhancement de verdade. Diferente de outros recursos recém-chegados, aqui a falta de suporte não deixa nada quebrado: deixa você no fallback que já teria escrito.

Perguntas frequentes

Posso registrar um nome próprio para a minha biblioteca?

Não. O registro é da especificação. Qualquer identificador fora da lista avaliada pelo navegador devolve falso.

Vale usar hoje em produção?

Se o seu caso é um dos dois nomes, sim, e sem risco: a semântica de falso fora do Chrome já é o que você quer. Se não é, não há o que usar.

Isso substitui teste por JavaScript?

Para os casos registrados, evita o teste em JavaScript e o flash de layout que ele costuma causar. Para o resto, a detecção por medição no cliente continua sendo a única saída.

Fontes

Deixe um comentário

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