CSS Supports

CSS Supports

O CSS hoje já possui um bom mecanismo para graceful degradation, apenas ignorando as regras que não consegue interpretar. Mas isso as vezes não é suficiente, como, por exemplo, quando várias regras são interdependentes e apenas não as interpretar pode quebrar o layout inteiramente, como no uso de um novo layout engine — flexbox, grid.

E quando queremos trabalhar com progressive enhacement, ou seja, usando novas features quando disponíveis, isso é normalmente feito com um feature detection via JavaScript. O que, na maioria das vezes, não nos dá uma experiência ótima pois pode causar alguns blinks no layout da página.

Com o CSS supports temos uma solução nativa para teste de suporte de features, podendo escrever códigos de fallback dentro de condicionais de um modo muito similar ao nosso já conhecido e amado CSS Media Queries.

Sintaxe

Sua sintaxe é, como dito acima, semelhante ao CSS Media Queries. Primeiro usamos a nova at-rule  @supports e, entre parênteses, a regra (junto com o valor) que queremos verificar se o navegador suporta. Como no exemplo abaixo.

@supports (propriedade:valor) {
  /*
  este código só irá ser interpretado caso
  o navegador dê suporte a propriedade testada
  */
}

Usando a sintaxe descrita acima podemos verificar se um navegador suporta transform com rotate da seguinte forma:

@supports (transform: rotate(45deg)) {
  /*
  este código só será interpretado caso o navegador
  suporte transform rotate com 45 unidades expressas em graus
  */
}

Reparem que no trecho de código acima estamos verificando se o navegador dá suporte à regra transform e, além disso, se ele suporta o valor rotate com 45 unidades, sendo essas unidades expressas em graus.

Podemos também usar condicionais como or, not e and para verificarmos regras em conjunto ou verificar se o navegador não suporta uma dada feature, facilitando a escrita de códigos de fallback.

@supports (display: flexbox) or (display: -webkit-flex) {
  /* aqui temos suporte ao flexbox */
}
@supports (not (display: flexbox) or (display: -webkit-flexbox)) {
  /* aqui não temos suporte ao flexbox */
}
@supports ((display: flexbox) and (not (display: inline-grid))) {
  /* aqui não temos suporte ao inline-grid, mas temos ao flexbox */
}

É importante lembrar também de testar pelas regras prefixadas. Como fizemos acima ao testar o suporte à regra flexbox.

JavaScript API

Também é fornecida uma API em JavaScript que podemos usar de forma muito parecida ao CSS. No objeto global CSS temos um novo método supports em que nele podemos passar dois argumentos, sendo o primeiro a regra e o segundo o valor a serem testados, ou apenas 1 argumento sendo este uma string ta qual usaríamos em CSS.

if (CSS.supports('display', 'flex')) {
  // temos suporte ao flexbox
} else {
  // aqui não temos suporte ao flexbox
}

if (CSS.supports('(display: flexbox) and (not (display: inline-grid))')) {
  // temos suporte ao flexbox, mas não ao inline-grid
}

Suporte

@supports28--22--12.1
CSS.supports28--22--12.1

Aqui vem a parte meta do post. Vamos falar do suporte de uma feature que testa o suporte de outras features. Por ser uma spec relativamente nova, ela atualmente roda apenas no Chrome 28+, Firefox 22+ e Opera 12.1+.

#59