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:
1 2 3 |
@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:
1 2 3 4 5 |
@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:
1 2 3 4 5 6 |
@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:
1 2 3 4 5 6 7 8 9 10 11 |
/* 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:
1 2 3 4 5 |
/* 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:
1 |
var supportsFlex = CSS.supports( 'display', 'flex' ); |
O segundo método de uso inclui simplesmente fornecer a seqüência inteira a ser analisada:
1 |
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:
1 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
.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.