CSS @supports (CSS Feature Queries): detecção nativa de suporte a propriedades CSS
A detecção de recursos via JavaScript é uma prática recomendada no lado do cliente, mas, infelizmente, essa mesma funcionalidade não está disponível em CSS. O que dá para fazer é repetir as mesmas propriedades várias vezes com cada prefixo de navegador. Que nojo… Mas eis que (finalmente) surge uma solução: CSS @supports!
Firefox, Chrome e Opera recentemente adicionaram suporte para CSS @supports (CSS) e CSS.supports (JavaScript) para detectar o suporte de navegador para uma determinada propriedade de estilo. Vejamos como isso funciona.
CSS @supports
A diretiva @supports de CSS funciona mais ou menos da mesma maneira que media queries:
@supports (propriedade: valor) { /* regras */}CSS @supports permite aos desenvolvedores verificarmos o suporte a estilo de várias maneiras diferentes.
Checagem de propriedades básicas
É possível checar propriedades básicas de CSS como no exemplo:
@supports (display: flex) { div { display: flex; }}Esse é o uso mais básico possível do @supports.
Palavra-chave not
Tal como em media queries, CSS @supports pode usar a palavra-chave **not** para checar um não-suporte:
@supports not (display: flex) { /* Estilos alternativos */ div { float: left; }}Checagem múltipla e condicionais
Se for preciso checar múltiplas propriedades CSS, isso pode ser feito ao usar as palavras-chave and ou or encadeadas:
/* or */@supports (display: -webkit-flex) or (display: -moz-flex) or (display: flex) { /* Regras CSS */}
/* and */@supports (display: flex) and (-webkit-appearance: caret) { /* Algo muito louco aqui */}Assim como em linguagens de programação, é possível encadear múltiplas condições com parênteses:
/* and e or */@supports ( (display: -webkit-flex) or (display: -moz-flex) or (display: flex) ) and (-webkit-appearance: caret) { /* Estilos aqui */}Como dito, o padrão condicional da estrutura de @supports coincide com o padrão condicional de @media.
JavaScript CSS.supports
A contrapartida JavaScript para CSS @supports é window.CSS.supports. A especificação CSS.supports fornece 2 métodos de uso.
O primeiro inclui fornecer 2 argumentos, um para a propriedade e outro para o valor:
var supportsFlex = CSS.supports( 'display', 'flex' );O segundo método de uso inclui simplesmente fornecer a seqüência inteira a ser analisada:
var supportsFlexAndAppearance = CSS.supports( '(display: flex) and (-webkit-appearance: caret)' );É muito bom que haja opções e seja possível verificar o suporte de CSS através de qualquer método — isso evita a verificação de propriedade em nós transitórios e construção de seqüências de caracteres para verificar o suporte.
Antes de usar o método JavaScript de CSS suporte, é importante detectar o recurso primeiro — o Opera usa um nome de método diferente, então é preciso ficar atento:
var supportsCSS = !!( (window.CSS && window.CSS.supports) || window.supportsCSS || false );Uso de @supports
Na maioria dos casos, a melhor maneira de usar @supports é configurando um conjunto mais antigo de estilos como backup e, em seguida, “cancelando” esses estilos e aprimorando se uma determinada propriedade é suportada — Progressive Enhancement, baby!
Um caso de uso brilhante para @supports é em layouts. Veja um exemplo envolvendo Flexbox:
section { float: left;}
@supports (display: -webkit-flex) or (display: -moz-flex) or (display: flex) { section { display: -webkit-flex; display: -moz-flex; display: flex; float: none; }}Exemplo prático: usando flow-root
Atualmente (na data de publicação deste artigo) o suporte para flow-root é quase nulo, conseguindo somente seus modestos 0,2% — se não souber do que se trata, leia um artigo a respeito.
Mas, graças a @supports, é possível usar o novo valor da propriedade CSS display e se livrar de uma vez por todas do famoso hack clearfix. E de uma maneira simplíssima:
.left,.right { width: 50%;}
.left { float: left; margin-bottom: 2em;}
.right { float: right;}
.wrapper::after { content: ''; display: block; clear: both;}
@supports (display: flow-root) { .wrapper { display: flow-root; }
/* IE 11 */ .wrapper::after { content: none; }}Ou seja, tal como de costume em projetos que seguem a filosofia progressive enhancement, especifica-se um valor que se tem certeza que funciona amplamente e, logo em seguida, valendo-se dos efeitos de cascata das folhas de estilo, verifica-se o suporte a flow-root com @supports para escrever a regra usando as novas capacidades de CSS.
Conclusão sobre @supports
Na verdade, @supports não é nenhuma grande novidade no mundo CSS, mas, infelizmente, ainda não é muito usado para verificações de suporte e desenvolvimento progressive enhancement.
Na data de publicação deste artigo, é possível ver que o suporte global de navegadores para @supports já é excelente, ultrapassando a casa dos 92%:
@supports revela-se como uma diretiva importante de verificação de estilos, indispensável quando o projeto web segue progressive enhancement. De escrita simples e rápida, @supports deveria estar muito, muito mais presente nas linhas de código CSS do que é possível encontrar atualmente.