Solução de problemas

Correções para as peculiaridades do Safari no iOS, reprodução de vídeo, tela cheia e navegação por teclado.

iOS Safari

A área visível não preenche a tela / faixa preta embaixo

A barra de endereços retrátil do Safari deixa 100vh maior que a área realmente visível. Use 100dvh:

css
.slider-container {
  height: 100dvh; /* not 100vh */
}

Rolagem horizontal / conteúdo transbordando

No iOS, 100vw inclui a largura da barra de rolagem e empurra o conteúdo para fora da borda. Use 100% e trave a rolagem horizontal:

css
html, body {
  overflow-x: hidden;
}

.slider-container {
  width: 100%; /* not 100vw */
}

Puxar para atualizar / efeito elástico

O gesto de puxar para atualizar e o efeito elástico do Safari brigam com os deslizes verticais. Não coloque overscroll-behavior: none em html, body: isso mata a rolagem normal da página. ReelPlayerOverlay, LightboxOverlay e StoriesPlayerOverlay já cuidam disso nos próprios contêineres. Em layouts personalizados, limite o escopo:

css
.slider-container {
  overscroll-behavior: none;
}

Caso especial do SwipeToClose para baixo. Qualquer SwipeToClose com direction="down" (lightbox, stories player, overlays personalizados) é interceptado no Safari do iOS — o navegador dispara o puxar para atualizar a partir do documento antes que o wrapper receba o toque. O overlay trava a rolagem do corpo, mas quem controla o arrasto vertical na raiz ainda é o navegador. Aplique overscroll-behavior-y: contain em <html> somente enquanto o overlay estiver aberto e restaure ao fechar:

tsx
useEffect(() => {
  if (!isOpen) return;
  const html = document.documentElement;
  const prev = html.style.overscrollBehaviorY;
  html.style.overscrollBehaviorY = 'contain';
  return () => {
    html.style.overscrollBehaviorY = prev;
  };
}, [isOpen]);

O gesto de pinça atrapalha os demais

Desative o zoom para que a pinça e o toque duplo não disparem durante os deslizes:

html
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover" />

viewport-fit=cover estende seu layout até a área segura da Dynamic Island / do entalhe.

Layout quebrado depois que o teclado some

Às vezes o Safari deixa a área visível comprimida depois que o teclado fecha. Force a recomposição no blur:

tsx
// React
<input
  onBlur={() => {
    window.scrollTo(0, 0);
    apiRef.current?.adjust();
  }}
/>

// Angular
(blur)="onInputBlur()"

onInputBlur() {
  window.scrollTo(0, 0);
  this.reelApi?.adjust();
}

Geral

Os slides aparecem com tamanho 0×0

Sem a prop size, o slider lê as dimensões do contêiner pelo ResizeObserver. Um contêiner sem altura definida no CSS mede 0×0, e aí nada aparece. Passe size ou dê dimensões ao contêiner:

css
/* The parent must have a height for auto-sizing to work */
.slider-container {
  width: 100%;
  height: 100dvh;
}

Vídeo

O vídeo não inicia sozinho

Os navegadores bloqueiam a reprodução automática com som. O ReelKit define muted e playsInline em todo elemento de vídeo. Os vídeos começam sem som; o leitor ativa o áudio no botão de som depois de um toque. Confira se um slide personalizado seu não está sobrescrevendo esses atributos.

A miniatura / captura de quadro sai em branco

A captura desenha o vídeo em um <canvas>. Vídeos de outra origem contaminam o canvas, e o desenho falha em silêncio. Sua CDN de vídeo precisa devolver os cabeçalhos de CORS:

text
Access-Control-Allow-Origin: *

O ReelKit define crossOrigin="anonymous" por padrão. Se você usa um elemento de vídeo próprio, acrescente o atributo você mesmo.

Tela cheia

O botão de tela cheia não faz nada no Safari

O ReelKit desativa a Fullscreen API no Safari. No iOS, o Safari restringe a tela cheia a elementos <video>. No desktop, o Safari quebra overlays com position: fixed em tela cheia: os elementos perdem o contexto de empilhamento ou somem. No Safari, requestFullscreen() termina sem fazer nada.

Navegação por teclado

As setas pararam de navegar depois de informar onNavKeyPress

onNavKeyPress substitui a navegação padrão por teclado. O ReelKit deixa de chamar next()/prev() e entrega o controle a você. Chame esses métodos você mesmo:

tsx
<Reel
  onNavKeyPress={(increment) => {
    // Your custom logic here
    console.log('Nav key:', increment);
    // You must trigger navigation yourself:
    apiRef.current?.[increment === 1 ? 'next' : 'prev']();
  }}
/>

A tecla Escape não fecha o overlay

O controlador de teclado cuida apenas das setas. ReelPlayerOverlay e LightboxOverlay escutam o Escape por conta própria. Se você montar um overlay personalizado, trate o Escape dentro do seu onClose.