Use @supports at-rule(@<at-rule name>) {…} para aplicar condicionalmente determinadas regras ou declarações CSS somente se uma determinada regra at for compatível com o navegador.
Ela pode conter regras inteiras ou ser usada em conjunto com o aninhamento de CSS para aplicar condicionalmente determinadas declarações.
.foo {
background: var(--accent-color);
@supports at-rule(@property) {
background-image: var(--rainbow-gradient);
animation: sliding-rainbow 1s linear infinite;
}
}
NÃO use @supports at-rule() para aplicar condicionalmente a regra @ que está sendo detectada e nada mais.
/* BAD: CSS already ignores rules the browser doesn't understand, so this is unnecessary */
@supports at-rule(@starting-style) {
@starting-style {
/* ... */
}
}
Como detectar a compatibilidade com regras @ quando @supports at-rule() não é adequado
Quando at-rule() não é uma opção, seja devido à compatibilidade do navegador ou porque é necessária uma detecção mais profunda, use as orientações abaixo.
Tente usar propriedades, valores ou seletores primeiro
O @supports já pode detectar propriedades, valores e seletores (com @supports selector(...)).
Em muitos casos, é possível usá-los para detectar o suporte a um recurso sem precisar verificar a regra @ em si.
Por exemplo, em vez de @supports at-rule(@function) para detectar compatibilidade com funções personalizadas, use @supports (color: --foo()).
Em outros casos, pode haver pseudoclasses ou pseudoelementos que só estão disponíveis quando uma determinada regra at é aceita, o que pode ser usado para detectar a compatibilidade.
Como detectar tipos de consulta de contêiner
at-rule() SÓ permite a detecção de regras @ por nome.
Ele NÃO permite a detecção de outras sintaxes ou descritores.
Por exemplo, isto não vai funcionar:
@supports at-rule(@container style(--a: 1)) {
/* ... */
}
Para muitos tipos de consultas de contêiner, é possível usar container-type com um valor adequado.
Por exemplo, @supports (container-type: scroll-state) para consultas de estado de rolagem ou @supports (container-type: size)container-type: anchoredforanchored()`.
No entanto, não há container-type para consultas de estilo.
IMPORTANTE: NÃO tente usar @supports (container-type: style) para detectar a compatibilidade com consultas de estilo, porque isso não vai funcionar.
Em vez disso, tente uma consulta de estilo que seja sempre verdadeira:
@container style(--a: 1) or (not (style(--a: 1))) {
/* Rules here will only be applied if style queries are supported */
}
Isso vai funcionar em qualquer navegador que ofereça suporte a consultas de estilo, independentemente do nome ou valor da propriedade que você usar, desde que sejam iguais em ambos.
Propriedades personalizadas registradas (@property)
Em alguns casos, se o CSS condicional a ser aplicado puder ser reduzido a uma única propriedade, use uma propriedade personalizada dedicada registrada para essa finalidade:
/* Use a custom property to conditionally include the dash animation */
@property --progress-dash-animation {
syntax: "*";
inherits: false;
initial-value: , progress-dash 3s ease-in-out infinite;
}
.spinner {
/* The dash animation is only included if @property is supported */
animation:
progress-spin var(--_used-spinner-duration) linear infinite
var(--progress-dash-animation, );
}
Para uma solução de uso geral, registre uma propriedade não herdada e defina-a como (um espaço) no elemento raiz:
{# Testcase: https://codepen.io/leaverou/pen/KwWzpVr #}
@property --supports-atproperty {
syntax: "*";
inherits: false;
}
:root {
--supports-atproperty: ;
}
body {
/* The background is only applied if @property is supported */
background: var(--supports-atproperty, green);
}
Observações:
- Ambas só funcionam se o espaço em branco for uma alternativa aceitável. Para outros casos, use o JS conforme descrito abaixo.
- A solução de uso geral depende da não herança, portanto, não funciona para declarações no elemento raiz.
Como usar o JavaScript como último recurso
Para regras at completas, verifique a presença de determinadas interfaces em JavaScript.
Por exemplo, se globalThis.CSSFunctionRule estiver definido, @function será compatível.
Se você precisar de testes mais detalhados (por exemplo, para determinados prelúdios, regras aninhadas, descritores), configure um teste e verifique como ele foi analisado:
const sheet = new CSSStyleSheet();
sheet.replaceSync(`
@page {
@top-left {
content: "test";
}
}
`);
const SUPPORTS_PAGE_MARGINS = Boolean(sheet.cssRules[0]?.cssRules?.[0]);
IMPORTANTE:
- Ao usar JS para detectar suporte a recursos CSS, NÃO aplique os estilos diretamente do JS. Em vez disso, aplique uma classe ao elemento raiz e ramifique-a no CSS.
- As consultas de contêiner são analisadas mesmo que o prelúdio não seja reconhecido, e não há como detectar suporte para determinados tipos de consultas de contêiner na estrutura do CSSOM.
- NÃO use
CSS.registerPropertypara detectar a compatibilidade com@property, já que ela é um pouco mais ampla.
Estratégias de fallback
A menos que isso esteja dentro da sua meta de suporte, use @supports (at-rule()) APENAS para detectar regras @ com suporte mais restrito do que o próprio recurso @supports (at-rule()).
Para aplicar CSS condicionalmente com base no suporte a regras at que foram lançadas antes desse recurso, use as orientações na seção acima.
Para detectar a compatibilidade com o recurso @supports at-rule() em si, use uma regra at que certamente existe em todos os navegadores compatíveis com @supports at-rule(), como @supports at-rule(@media) { ... }.