Entendendo o Safari - Limitações do navegador e como superá-las

Um meme que compara o Internet Explorer com o Safari utilizando os textos “como começou” e “como está a correr”

Não é nenhuma novidade quando dizemos que o Safari é o novo Internet Explorer. Esta comparação é feita porque o Safari tem uma faixa importante do mercado de navegadores e tem uma experiência inferior à dos seus concorrentes, semelhante com o que aconteceu com o Internet Explorer na década de 2010.

Embora não considere que todos os navegadores devam ser um fork do Chromium e que as engines WebKit e Gecko contribuam para um ecossistema diverso, acredito que o tipo de navegadordeve ser, pelo menos, algo que devemos ter liberdade de escolha.

É importante reconhecer o trabalho que os parceiros da Igalia e das pessoas do time the Web Interoperability da Apple fazem para melhorar o WebKit.

Dito isso, eu já encontrei inúmeros problemas ou comportamentos diferentes que aconteceram apenas no Safari e então estou tentando reuni-los em uma lista nesse artigo. Esqueci de algum ou tem alguma experiência para compartilhar? Me mande uma mensagem ou um PR.

Eu espero que este artigo fique desatualizado em breve.

Problemas

Dispositivo

Não é possível solucionar problemas específicos do Safari se você não tiver um Macbook. Simples assim. Não há como instalar o Safari em uma máquina Windows ou Linux. Dá pra instalar algumas alternativas como o WebKitGTK or usar o WebKit através do Playwright CLI.

Agora pra o Safari iOS, além do MacBook você também precisa também ter um iPhone cas queira debuggar problemas lá ou ter que pagar por ferramentas como o [BrowserStack] (https://www.browserstack.com/) que permite usar um dispositivo real dentro do seu navegador por alguns minutos.

Filtros CSS

Qualquer elemento que utilize um filtro CSS não será renderizado no Safari, a menos que você adicione um translate3d(0, 0, 0.01) junto com o filtro que deseja aplicar.

Imagens sendo baixadas múltiplas vezes

Nota: A maioria dos frameworks já lida com isso, como Next.js identificou em 2021.

Existe um bug no Safari na criação de tags de imagem usando a combinação de srcset e sizes. Se o atributo sizes aparecer depois do srcset, o Safari baixa todas as imagens desconsiderando o atributo sizes.

Problema em components Slider

Originalmente reportado nos repositorios do material-ui e react-range no GitHub.

Em componentes Slider como o MUI acima, há um bug para o navegador móvel Safari no evento onChange onde ele é exeuctado duas vezes. Precisamos literalmente verificar se é iOS e prevenir isso manualmente:

const isIOS = () => {
	// função que verifica o user agent para possíveis dispositivos iOS
}

const handleChange = (event, newValue) => {
	if (isIOS() && event.type === 'mousedown') {
		return
	}
	// Caso contrário, manipule execute o onChange normalmente
}

Múltiplas streams de áudio

Por padrão, Safari permite dar play em apenas uma faixa de áudio por vez. Se precisar de reproduzir mais do que uma faixa de áudio simultaneamente, você precisa controlar o atributo muted das duas tags audio, iniciando-os com um valor true e, em seguida, alternando-o sempre que você quiser reproduzir ou pausar um deles. No exemplo abaixo funciona, mas somente com essa manipulação do muted.

Vale a pena mencionar também esta outra solução de Matt Harrison que usa Web Audio API.

Funcionalidades que estão faltando

API de Informação da Conexão

Nota: Também não funciona no Firefox.

Esta API acessível a partir de navigator.connection fornece informações úteis sobre a conexão de internet do usuário e pode ser utilizada para proporcionar uma experiência de personalizada ou otimizar as métricas de SEO. Por exemplo, se o usuário estiver conectado ao seu site em uma conexão lenta, você pode renderizar uma mesma imagem de qualidade inferior para não prejudicar a experiência.

API de URLPattern matching

Nota: Também não funciona no Firefox.

Esta API tem a intenção de funcionar como o Node Express Router faz como em:

app.get('/users/:userId/books/:bookId', (req, res) => {
	res.send(req.params) // espera que userId e bookId estejam definidos
})

com o objetivo de identificar padrões específicos no URL. Isso pouparia muito código obscuro que precisa executar gambiarras do tipo como const book = url.split('/')[3] para obter o valor de uma fatia específica do URL que você está procurando.

Posicionamento da âncora CSS

Nota: Também não funciona no Firefox.

Esta funcionalidade CSS permite-nos posicionar declarativamente elementos relativamente a outros utilizando a função anchor().

Comportamentos diferentes

Estilos padrão do sistema operacional

Em todos os navegadores, o sistema operativo tem um estilos único para todos os elementos de UI. Para remover as diferenças variáveis entre eles, a recomendação é usar algum tipo de reset/normalizador de CSS como modern-normalize ou normalize.css.

De qualquer forma, isto pode pegar desprevenido se o projeto em que está a trabalhar não os aplicar ou os aplica parcialmente.

folha de estilos padrão para botões de envio de formulário no sistema operacional iOS

No exemplo da captura de tela acima, você pode ver que a Apple define um preenchimento vertical padrão de 1em para elementos de botão de envio de formulário, e abaixo o Chrome define um 0.5em para eles.

folha de estilos padrão para botões de envio de formulário no sistema operacional Android

Problema em components Slider

Issues: https://github.com/tajo/react-range/issues/180, https://github.com/mui/material-ui/issues/31869

Em componentes Slider como o MUI acima, há um bug para o navegador móvel Safari do evento onChange onde ele dispara duas vezes. Precisamos literalmente verificar se é iOS e prevenir isso manualmente:

const isIOS = () => {
	// função que verifica o user agent para possíveis dispositivos iOS
}

const handleChange = (event, newValue) => {
	if (isIOS() && event.type === 'mousedown') {
		return
	}
	// Caso contrário, manipule execute o onChange normalmente
}

Suporte a PWA

A Apple opta deliberadamente por atrasar funcionalidades relacionadas a PWA há já algum tempo. A última notícia é do iOS 17.4 que matou a já ruim instalação de apps PWA mas que foi revertida rapidamente devido a pressão da comunidade.

Já em questão de funcionalidades, o Safari vem se atualizando e correndo atrás de funcionalidades que até pouco tempo atrás não eram possíveis lá, como notificações push e sincronização em segundo plano. Uma bom recurso nessa área é o WhatCanPWACanDoToday, que é uma página que mostra o estado atual das funcionalidades de PWA em diferentes navegadores e plataformas.