Abstract amber glass software interface visual.
Back to blog
Coding3 min read

[Resolved] Safari broke my background video

My hero background video worked in Chrome, Edge, and Firefox, but Safari made it load inconsistently. The fix was a Safari fallback using a wrapper div and CSS background-image.

By Suryansh Kushwaha /

SafariFrontendDebuggingWeb Development
On this page

A few days after launching my website, I found a Safari-specific issue in the hero section.

The background video worked in Chrome, Edge, and Firefox. In Safari, it was inconsistent. Sometimes it played, sometimes it took too long to load, and sometimes the first viewport looked unfinished.

The video file was valid. The path was correct. The usual autoplay attributes were already present.

Original video setup
<video class="hero-video" autoplay muted loop playsinline>
  <source src="/hero-video.mp4" type="video/mp4" />
</video>

That setup is normally enough for a decorative background video:

  • autoplay starts the video automatically
  • muted allows autoplay in modern browsers
  • loop keeps the background moving
  • playsinline prevents mobile Safari from opening fullscreen playback

Safari still did not behave reliably.

The Fix

The solution was to add a fallback layer behind the normal <video> element. The fallback is a wrapper div that uses the same .mp4 file as a CSS background-image.

I found this approach through a Webflow forum trail that pointed to Avinash Kumar's Safari background video write-up. It looks unusual, but Safari can render video media through background-image, which makes it useful as a fallback for this specific issue.

Safari fallback structure
<section class="hero">
  <div class="hero-video-fallback" aria-hidden="true"></div>
 
  <video
    class="hero-video"
    autoplay
    muted
    loop
    playsinline
    preload="metadata"
    poster="/hero-poster.jpg"
    aria-hidden="true"
  >
    <source src="/hero-video.mp4" type="video/mp4" />
  </video>
 
  <div class="hero-content">
    <h1>Your hero content</h1>
  </div>
</section>
Safari fallback CSS
.hero {
  position: relative;
  min-height: 100vh;
  overflow: hidden;
}
 
.hero-video-fallback,
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
 
.hero-video-fallback {
  background-image: url('/hero-video.mp4');
  background-position: center;
  background-size: cover;
}
 
.hero-video {
  object-fit: cover;
}
 
.hero-content {
  position: relative;
}

The normal video element continues to work in browsers that handle it well. Safari has the fallback layer available when the video element is unreliable.

React / Next.js Note

In React and Next.js, use playsInline instead of playsinline.

React video element
<video
  autoPlay
  muted
  loop
  playsInline
  preload='metadata'
  poster='/hero-poster.jpg'
  aria-hidden='true'
>
  <source src='/hero-video.mp4' type='video/mp4' />
</video>

Small casing issue, very easy to miss.

Production Checklist

If a Safari background video is unreliable, I would check these first:

  1. Open the video file directly in Safari and confirm it loads.
  2. Add muted, autoplay, loop, and playsinline.
  3. Use playsInline when writing JSX.
  4. Add a poster image.
  5. Keep the video short and compressed.
  6. Check parent stacking, overlays, and overflow rules.
  7. Add the wrapper fallback with background-image: url('/video.mp4').
  8. Test desktop Safari and mobile Safari separately.

The fallback does not fix a heavy or badly encoded video. It only gives Safari a more reliable rendering path for this background-video use case.

Final Takeaway

For background videos, do not rely only on the <video> element if the first viewport matters.

Use the normal video tag, keep the correct autoplay attributes, add a poster, and give Safari a wrapper-based fallback.

That made the hero section reliable for me.

If you want this kind of browser testing and reliability handled properly for your own website, check out my Studio and send me a request. ;)