Um guia para suporte a CSS em navegadores

Publicados: 2022-03-10
Resumo rápido ↬ Pode ser frustrante quando você deseja usar um recurso e descobre que ele não é compatível ou se comporta de maneira diferente entre os navegadores. Neste artigo, Rachel Andrew detalha os diferentes tipos de problemas de suporte do navegador e mostra como o CSS está evoluindo para facilitar o tratamento deles.

Nunca viveremos em um mundo onde todos que visualizam nossos sites têm um navegador e uma versão de navegador idênticos, assim como nunca viveremos em um mundo onde todos têm o mesmo tamanho de tela e resolução. Isso significa que lidar com navegadores antigos — ou navegadores que não suportam algo que queremos usar — ​​faz parte do trabalho de um desenvolvedor web. Dito isso, as coisas estão muito melhores agora do que no passado e, neste artigo, vou dar uma olhada nos diferentes tipos de problemas de suporte ao navegador que podemos encontrar. Vou mostrar algumas maneiras de lidar com eles, e também ver coisas que podem vir em breve e que podem ajudar.

Por que temos essas diferenças?

Mesmo em um mundo onde a maioria dos navegadores é baseada no Chromium, esses navegadores não executam a mesma versão do Chromium que o Google Chrome. Isso significa que um navegador baseado em Chromium, como o Vivaldi, pode estar algumas versões atrás do Google Chrome.

E, é claro, os usuários nem sempre atualizam rapidamente seus navegadores, embora essa situação tenha melhorado nos últimos anos com a maioria dos navegadores atualizando-se silenciosamente.

Há também a maneira pela qual os novos recursos chegam aos navegadores em primeiro lugar. Não é o caso de que novos recursos para CSS sejam projetados pelo CSS Working Group, e uma especificação completa entregue aos fornecedores de navegadores com instruções para implementá-lo. Muitas vezes, é apenas quando uma implementação experimental acontece que todos os detalhes mais sutis da especificação podem ser trabalhados. Portanto, o desenvolvimento de recursos é um processo iterativo e requer que os navegadores implementem essas especificações no desenvolvimento. Embora a implementação aconteça hoje com mais frequência atrás de uma bandeira no navegador ou disponível apenas em uma versão noturna ou de visualização, uma vez que um navegador tenha um recurso completo, é provável que ele seja ativado para todos, mesmo que nenhum outro navegador ainda tenha suporte.

Tudo isso significa que – por mais que gostemos – nunca existiremos em um mundo onde os recursos estão magicamente disponíveis em todos os desktops e telefones simultaneamente. Se você é um desenvolvedor web profissional, seu trabalho é lidar com esse fato.

Mais depois do salto! Continue lendo abaixo ↓

Bugs versus falta de suporte

Existem três problemas que enfrentamos em relação ao suporte ao navegador:

  1. Sem suporte de um recurso
    O primeiro problema (e mais fácil de lidar) é quando um navegador não suporta o recurso.
  2. Lidando com “Bugs” do navegador
    A segunda é quando o navegador afirma oferecer suporte ao recurso, mas o faz de maneira diferente da maneira como outros navegadores oferecem suporte ao recurso. Esse problema é o que costumamos chamar de “bug do navegador” porque o resultado final é um comportamento inconsistente.
  3. Suporte parcial de propriedades CSS
    Este está se tornando mais comum; uma situação em que um navegador oferece suporte a um recurso — mas apenas em um contexto.

É útil entender com o que você está lidando quando vê uma diferença entre os navegadores, então vamos dar uma olhada em cada um desses problemas.

1. Sem suporte de um recurso

Se você usar uma propriedade ou valor CSS que um navegador não entende, o navegador irá ignorá-lo. Isso é o mesmo se você usar um recurso sem suporte ou criar um recurso e tentar usá-lo. Se o navegador não entender essa linha de CSS, ele simplesmente a ignora e continua com a próxima coisa que entende.

Este princípio de design do CSS significa que você pode usar alegremente os novos recursos, sabendo que nada de ruim acontecerá a um navegador que não tem suporte. Para alguns CSS, usados ​​puramente como um aprimoramento, isso é tudo que você precisa fazer. Use o recurso, certifique-se de que, quando esse recurso não estiver disponível, a experiência ainda seja boa, e pronto. Essa abordagem é a ideia básica por trás do aprimoramento progressivo, usando esse recurso da plataforma que permite o uso seguro de coisas novas em navegadores que não as entendem.

Se você quiser verificar se um recurso que está usando é compatível com os navegadores, consulte o site Posso usar. Outro bom lugar para procurar informações de suporte detalhadas é a página para cada propriedade CSS no MDN. Os dados de suporte do navegador tendem a ser muito detalhados.

O novo CSS entende o CSS antigo

À medida que novos recursos CSS são desenvolvidos, toma-se cuidado em termos de como eles interagem com o CSS existente. Por exemplo, na especificação Grid e Flexbox, ele é detalhado em termos de como display: grid e display: flex lidam com cenários como quando um item flutuante se torna um item de grade ou um contêiner multicol é transformado em uma grade. Isso significa que certos comportamentos são ignorados, ajudando você a simplesmente sobrescrever o CSS para o navegador não compatível. Essas substituições são detalhadas na página de Aprimoramento progressivo e Layout de grade no MDN.

Detectando suporte com consultas de recursos

O método acima só funciona se o CSS que você precisa usar não precisar de outras propriedades para acompanhá-lo. Você pode precisar adicionar propriedades adicionais ao seu CSS para navegadores mais antigos, que também seriam interpretados pelos navegadores que suportam o recurso também.

Um bom exemplo disso pode ser encontrado ao usar Grid Layout. Enquanto um item flutuante que se torna um item de grade perde todo o comportamento de flutuação, é provável que, se você estiver tentando criar um fallback para um layout de grade com flutuação, tenha adicionado larguras percentuais e possivelmente margens aos itens.

 .grid > .item { width: 23%; margin: 0 1%; } 
Um layout de quatro colunas
Usando floats podemos criar um layout de quatro colunas, larguras e margens precisam ser definidas em % . (Visualização grande)

Essas larguras e margens ainda serão aplicadas quando o item flutuante for um item de grade. A largura se torna uma porcentagem da trilha da grade em vez da largura total do contêiner; qualquer margem será então aplicada, bem como uma lacuna que você possa ter especificado.

 .grid > .item { width: 23%; margin: 0 1%; } .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; } 
Um layout de quatro colunas com colunas esmagadas
A largura agora é uma porcentagem da trilha da grade - não do contêiner. (Visualização grande)

Felizmente, existe um recurso embutido no CSS e implementado em navegadores modernos que nos ajuda a lidar com essa situação. As consultas de recursos nos permitem perguntar diretamente ao navegador o que eles suportam e, em seguida, agir de acordo com a resposta. Assim como uma consulta de mídia — que testa algumas propriedades do dispositivo ou tela — as consultas de recursos testam o suporte de uma propriedade e valor CSS.

Teste para suporte

O teste de suporte é o caso mais simples, usamos @supports e, em seguida, testamos uma propriedade e valor CSS. O conteúdo dentro da Feature Query só será executado se o navegador responder com true, ou seja, ele suporta o recurso.

Teste sem suporte

Você pode perguntar ao navegador se ele não suporta um recurso. Nesse caso, o código dentro da Feature Query só será executado se o navegador indicar que não tem suporte.

 @supports not (display: grid) { .item { /* CSS from browsers which do not support grid layout */ } }

Teste para várias coisas

Se você precisar que mais de uma propriedade seja suportada, use and .

 @supports (display: grid) and (shape-outside: circle()){ .item { /* CSS from browsers which support grid and CSS shapes */ } }

Se você precisar de suporte de uma propriedade ou outra, use or .

 @supports (display: grid) or (display: flex){ .item { /* CSS from browsers which support grid or flexbox */ } }

Escolhendo uma propriedade e um valor para testar

Você não precisa testar cada propriedade que deseja usar - apenas algo que indicaria suporte para os recursos que você planeja usar. Portanto, se você quiser usar o Grid Layout, poderá testar display: grid . No futuro (e assim que o suporte a subgrade chegar aos navegadores), talvez seja necessário ser mais específico e testar a funcionalidade da subgrade. Nesse caso, você testaria grid-template-columns: subgrid para obter uma resposta verdadeira apenas dos navegadores que implementaram suporte a subgrade.

Se agora retornarmos ao nosso exemplo de fallback flutuante, podemos ver como as consultas de recursos resolverão isso para nós. O que precisamos fazer é consultar o navegador para descobrir se ele suporta layout de grade. Se isso acontecer, podemos definir a largura do item de volta para auto e a margem para 0 .

 .grid > .item { width: 23%; margin: 0 1%; } @supports(display: grid) { .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; column-gap: 1%; } .grid > .item { width: auto; margin: 0; } } 

Veja as consultas e grade de recursos da caneta por (Rachel Andrew) no CodePen.

Veja as consultas e grade de recursos da caneta por (Rachel Andrew) no CodePen.

Observe que, embora eu tenha incluído todo o código de grade dentro da minha consulta de recurso, não preciso. Se um navegador não entendesse as propriedades da grade, ele as ignoraria para que pudessem ficar fora da consulta do recurso com segurança. As coisas que devem estar dentro de uma consulta de recurso neste exemplo são as propriedades margin e width, pois elas são necessárias para o código do navegador antigo, mas também seriam aplicadas pelos navegadores de suporte.

Abrace a cascata

Uma maneira muito simples de oferecer fallbacks é utilizar o fato de que os navegadores ignoram o CSS que eles não entendem e o fato de que, onde todo o resto tem a mesma especificidade, a ordem de origem é levada em consideração em termos de qual CSS é aplicado a um elemento .

Você primeiro escreve seu CSS para navegadores que não suportam o recurso. Em seguida, teste o suporte da propriedade que você deseja usar, se o navegador confirmar que tem suporte para substituir o código de fallback pelo seu novo código.

Esse é praticamente o mesmo procedimento que você pode usar ao usar consultas de mídia para design responsivo, seguindo uma abordagem mobile-first. Nessa abordagem, você começa com seu layout para telas menores e, em seguida, adiciona ou substitui coisas para telas maiores à medida que avança pelos pontos de interrupção.

Posso usar consultas de recursos CSS? Dados sobre suporte para consultas de recursos CSS nos principais navegadores de caniuse.com.

A maneira de trabalhar acima significa que você não precisa se preocupar com navegadores que não suportam consultas de recursos. Como você pode ver em Can I Use , Feature Queries tem um suporte muito bom. Os navegadores de destaque que não os suportam são qualquer versão do Internet Explorer.

É provável, no entanto, que o novo recurso que você deseja usar também não seja suportado no IE. Então, no momento você quase sempre começará escrevendo CSS para navegadores sem suporte, então você testa com uma Feature Query. Esta Consulta de Recurso deve testar o suporte.

  1. Os navegadores que suportam Consultas de Recurso retornarão true se tiverem suporte e, portanto, o código dentro da consulta será usado, substituindo o código de navegadores mais antigos.
  2. Se o navegador suportar Consultas de Recurso, mas não o recurso que está sendo testado, ele retornará false. O código dentro da consulta de recurso será ignorado.
  3. Se o navegador não suportar Consultas de Recurso, tudo dentro do bloco Consulta de Recurso será ignorado, o que significa que um navegador como o IE11 usará o código do navegador antigo, o que provavelmente é exatamente o que você deseja!

2. Lidando com “Bugs” do navegador

Felizmente, o segundo problema de suporte do navegador está se tornando menos comum. Se você ler “What We Wished For” (publicado no final do ano passado), poderá fazer um pequeno tour por alguns dos bugs de navegador mais desconcertantes do passado. Dito isto, qualquer software é suscetível de ter bugs, os navegadores não são exceção. E, se adicionarmos a isso o fato de que, devido à natureza circular da implementação da especificação, às vezes um navegador implementou algo e a especificação mudou, então agora eles precisam emitir uma atualização. Até que essa atualização seja lançada, podemos estar em uma situação em que os navegadores fazem algo diferente entre si.

Consultas de recursos não podem nos ajudar se o navegador relatar suporte de algo que o suporta mal. Não existe um modo pelo qual o navegador possa dizer: “ Sim, mas você provavelmente não vai gostar ”. Quando um bug real de interoperabilidade aparece, é nessas situações que você pode precisar ser um pouco mais criativo.

Se você acha que está vendo um bug, a primeira coisa a fazer é confirmar isso. Às vezes, quando pensamos que vemos um comportamento de buggy e navegadores fazendo coisas diferentes, a culpa é nossa. Talvez tenhamos usado alguma sintaxe inválida ou estejamos tentando estilizar HTML malformado. Nesses casos, o navegador tentará fazer alguma coisa; no entanto, como você não está usando as linguagens como elas foram projetadas, cada navegador pode lidar de uma maneira diferente. Uma verificação rápida de que seu HTML e CSS são válidos é um excelente primeiro passo.

Nesse ponto, eu provavelmente faria uma pesquisa rápida e veria se meu problema já era amplamente compreendido. Existem alguns repositórios de problemas conhecidos, por exemplo, Flexbugs e Gridbugs. No entanto, mesmo apenas algumas palavras-chave bem escolhidas podem gerar postagens ou artigos do Stack Overflow que cobrem o assunto e podem oferecer uma solução alternativa.

Mas digamos que você não saiba realmente o que está causando o bug, o que torna muito difícil procurar uma solução. Assim, o próximo passo é criar um caso de teste reduzido do seu problema, ou seja, eliminar qualquer coisa irrelevante para ajudá-lo a identificar exatamente o que aciona o bug. Se você acha que tem um bug de CSS, você pode remover qualquer JavaScript ou recriar o mesmo estilo fora de um framework? Costumo usar o CodePen para reunir um caso de teste reduzido de algo que estou vendo; isso tem a vantagem adicional de me fornecer o código de uma maneira que eu possa compartilhar facilmente com outra pessoa se precisar perguntar sobre isso.

Na maioria das vezes, depois de isolar o problema, é possível pensar em uma maneira alternativa de alcançar o resultado desejado. Você descobrirá que outra pessoa criou uma solução astuta ou pode postar em algum lugar para pedir sugestões.

Com isso dito, se você acha que tem um bug no navegador e não consegue encontrar mais ninguém falando sobre o mesmo problema, é bem possível que você tenha encontrado algo novo que deve ser relatado. Com todo o novo CSS que chegou recentemente, às vezes podem aparecer problemas quando as pessoas começam a usar coisas em combinação com outras partes do CSS.

Confira este post de Lea Verou sobre como relatar esses problemas, “Ajude a comunidade! Reportar bugs do navegador!”. O artigo também tem ótimas dicas para criar um caso de teste reduzido.

3. Suporte Parcial de Propriedades CSS

O terceiro tipo de problema se tornou mais comum devido à maneira como as especificações CSS modernas são projetadas. Se pensarmos em Grid Layout e Flexbox, essas especificações usam as propriedades e os valores do Box Alignment Level 3, para fazer o alinhamento. Portanto, propriedades como align-items , justify-content e column-gap são especificadas para serem usadas em Grid e Flexbox, bem como em outros métodos de layout.

No momento em que escrevo, no entanto, as propriedades de gap funcionam no Grid Layout em todos os navegadores com suporte a grade, e column-gap funciona em Multicol; no entanto, apenas o Firefox implementou essas propriedades para o Flexbox.

Se eu usar margens para criar um fallback para o Flexbox, testar column-gap e remover as margens, minhas caixas não terão espaço entre elas em navegadores que suportam column-gap em Grade ou multicol, então meu espaçamento de retorno será removido.

 @supports(column-gap: 20px) { .flex { margin: 0; /* almost everything supports column-gap so this will always remove the margins, even if we do not have gap support in flexbox. */ } }

Esta é uma limitação atual das Consultas de Recurso. Não temos como testar o suporte de um recurso em outro recurso. Na situação acima, o que eu quero perguntar ao navegador é: “Você tem suporte para intervalo de coluna no Flexbox?” Dessa forma, posso obter uma resposta negativa para poder usar meu substituto.

Há um problema semelhante com as propriedades de fragmentação CSS break-before , break-after e break-inside . Como eles têm melhor suporte quando a página é impressa, os navegadores geralmente reivindicam suporte. No entanto, se você estiver testando o suporte em multicol, obterá o que parecem ser falsos positivos. Eu levantei uma questão no CSS Working Group para esta questão, no entanto, não é um problema simples de resolver. Se você tiver pensamentos, por favor, adicione-os lá.

Teste para suporte ao seletor

Atualmente, as Consultas de Recurso só podem testar propriedades e valores CSS. Outra coisa que gostaríamos de testar é o suporte de seletores mais novos, como os do Nível 4 da especificação de Seletores. Há uma nota explicativa e também uma implementação por trás de um sinalizador no Firefox Nightly de um novo recurso para Consultas de recursos que alcançará isso.

Se você visitar about:config no Firefox e habilitar o sinalizador layout.css.supports-selector.enabled , então você pode testar para ver se vários seletores são suportados. A sintaxe é atualmente muito direta, por exemplo, para testar o seletor : :has :

 @supports selector(:has){ .item { /* CSS for support of :has */ } }

Esta é uma especificação em desenvolvimento, no entanto, você pode ver como os recursos para nos ajudar a gerenciar os problemas sempre presentes de suporte ao navegador estão sendo adicionados enquanto falamos.

Leitura adicional

Pode parecer frustrante quando você deseja usar um recurso e descobre que ele não é suportado por um navegador importante ou se as coisas parecem estar se comportando de maneiras diferentes. Eu reuni algumas leituras adicionais práticas que podem ajudar.

  • “Usando CSS Grid: Supporting Browsers Without Grid” Opções para lidar com navegadores mais antigos e CSS Grid
  • Página de referência MDN "Consultas de recursos" para consultas de recursos
  • Guia MDN “CSS Grid And Progressive Enhancement” para aprimoramento progressivo de Grid
  • Guia MDN “Backwards Compatibility Of Flexbox” para suporte ao Flexbox, incluindo detalhes de implementações prefixadas mais antigas
  • “Pattern Library First” Como gerenciar o código de fallback usando uma biblioteca de padrões