Background Video CSS

A video playing in the background spanning the entire browser window creates a captivating visual effect when text overlays it, a unique feature not commonly encountered. This is primarily due to the limitation in CSS where a video file cannot be directly set as the background image. Overcoming this challenge will necessitate employing some clever layout techniques.

Of course, a background film taking up the entire page would be a bit much. It is possible to do it tastefully, I would say. I am more interested in the how-to of finishing it, if necessary, and various potential patterns it may take than in debating design philosophy here (maybe later).

The fundamentals of tastefulness are still important to note here:

  • No sound. By default, at least. Opt-in audio is appropriate.
  • Be mindful of your bandwidth. Video content is the heaviest item you can put on a website. Please take note that this is a video that was not specifically requested.
  • Make it available. Since you will most likely be overlaying text on top of the video, ensure the contrast is sufficient for legibility.

In celebration of the upcoming journey with Media Temple and ZaneRay, let's tackle this Montana-style.

The How-To of Full-Page Background Video

Fortunately, we are in a favorable position. Dudley Story has conducted numerous investigations on this subject in the past and has shared a helpful configuration with us. Additionally, he has a sample webpage available for reference.

Sure thing, we need to embed the video onto the webpage, so here it is: ```

<video playsinline autoplay muted loop poster="mixkit-white-sand-beach-background-1564-medium" id="bg">

<source src="https://placehold.co/300x300/1abc9c/ffffff?text=Sample+Image" type="video/webm">

<source src="https://placehold.co/400x300/1abc9c/ffffff?text=Sample+Image" type="video/mp4">

</video>

Example


<video playsinline autoplay muted loop poster="mixkit-white-sand-beach-background-1564-medium" id="bg">

<source src="https://placehold.co/300x300/1abc9c/ffffff?text=Sample+Image" type="video/webm">

<source src="https://placehold.co/400x300/1abc9c/ffffff?text=Sample+Image" type="video/mp4">

</video>

Example


When a video loads at a slow pace or fails to load entirely, the poster attribute offers an image for visual representation. It may also be beneficial to incorporate a background using CSS.

The autoplay attribute is present to initiate video playback automatically. It is a thoughtful feature that eliminates the need for manual intervention from the user. In scenarios where playback controls are absent, the user's ability to start or stop the video is restricted. To enable autoplay on iOS devices, the playsinline attribute should be utilized. Furthermore, the muted attribute is vital for iOS to support autoplay, which is a prudent decision especially when the video content does not require audio. Once these attributes are set, the loop attribute ensures continuous playback of the video content.

You can achieve this by maximizing the video to occupy the entire screen.

video {

object-fit: cover;

width: 100vw;

height: 100vh;

position: fixed;

top: 0;

left: 0;

}

Example


You will be provided with a comprehensive video tutorial for that! Excellent!

Now, let's explore some patterns. A full-page video can be managed using a single approach, whereas there are multiple alternative methods available.

### Just One Viewport

We have arranged the video in its position. We can now overlay any elements on top of it.

Take some text like this:

<header class="viewport-header">

<h1>

Explore

beach

</h1>

</header>

Example


It can be situated in relation to the video and positioned above it. Then, apply a slight centering adjustment:

.viewport-header {

align-items: centre;

justify-content: centre;

text-align: centre;

display: flex;

position: relative;

height: 100vh;

}

Example


We have the simplest possible effect:

Html:

<video src="https://placehold.co/800x200/1abc9c/ffffff?text=Banner" autoplay loop playsinline muted></video>

<header class="viewport-header">

<h1>

Explore

beach

</h1>

</header>

<main>

[[[https://mixkit.co/free-stock-video/white-sand-beach-background-1564/]]]

</main>

Example


video {

object-fit: cover;

width: 100vw;

height: 100vh;

position: fixed;

top: 0;

left: 0;

}

html, body {

height: 100%;

}

html {

font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";

font-size: 150%;

line-height: 1.4;

}

body {

margin: 0;

}

.viewport-header {

position: relative;

height: 100vh;

text-align: center;

display: flex;

align-items: center;

justify-content: center;

}

h1 {

font-family: 'Syncopate', sans-serif;

color: #4a3a27;

text-transform: uppercase;

letter-spacing: 3vw;

line-height: 1.2;

font-size: 3vw;

text-align: center;

span {

display: block;

font-size: 10vw;

letter-spacing: -1.3vw;

}

}

main {

display: none;

width: 80vw;

left: 10%;

height: 40vh;

overflow: auto;

background: rgba(black, 0.66);

color: white;

position: relative;

padding: 1rem;

}

Example


Other elements that we prefer could potentially be located anywhere within the webpage. While it may not be considered trendy, there is also the option to eliminate a scrolling text segment to maintain the overall impression of a complete page.

HTML:

<video src="https://placehold.co/800x200/1abc9c/ffffff?text=Banner" autoplay loop playsinline muted></video>

<header class="viewport-header">

<h1>

Explore

beach

</h1>

</header>

<main>

[[[https://mixkit.co/free-stock-video/white-sand-beach-background-1564/]]]

</main>

Example


video {

object-fit: cover;

width: 100vw;

height: 100vh;

position: fixed;

top: 0;

left: 0;

}

html, body {

height: 100%;

}

html {

font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";

font-size: 150%;

line-height: 1.4;

}

body {

margin: 0;

}

.viewport-header {

position: relative;

height: 50vh;

text-align: center;

display: flex;

align-items: center;

justify-content: center;

}

h1 {

font-family: 'Syncopate', sans-serif;

color: #4a3a27;

text-transform: uppercase;

letter-spacing: 3vw;

line-height: 1.2;

font-size: 3vw;

text-align: center;

span {

display: block;

font-size: 10vw;

letter-spacing: -1.3vw;

}

}

main {

width: 80vw;

left: 10%;

height: 40vh;

overflow: auto;

background: rgba(black, 0.66);

color: white;

position: relative;

padding: 1rem;

}

JS:

/*

  • Fallback bokuh
  • webm?
  • poster=""
  • Full page always
  • Full page, then scroll
  • Just header
  • Browser compat

*/

Example


### One Viewport Header, Scrolls Away

Other elements may disappear from view while the video is playing in full-screen mode. The main content remains unchanged, while the header, which remains fully visible within the screen, smoothly moves out of sight. Moreover, it maintains a semi-transparent quality, enabling the video content to remain visible through it.

HTML:

<video src="https://placehold.co/800x200/1abc9c/ffffff?text=Banner" autoplay loop playsinline muted></video>

<header class="viewport-header">

<h1>

Explore

Montana

</h1>

</header>

<main>

[[[https://mixkit.co/free-stock-video/white-sand-beach-background-1564/]]]

</main>

Example


video {

object-fit: cover;

width: 100vw;

height: 100vh;

position: fixed;

top: 0;

left: 0;

}

html, body {

height: 100%;

}

html {

font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";

font-size: 150%;

line-height: 1.4;

}

body {

margin: 0;

}

.viewport-header {

position: relative;

height: 100%;

text-align: center;

display: flex;

align-items: center;

justify-content: center;

}

h1 {

font-family: 'Syncopate', sans-serif;

color: white;

text-transform: uppercase;

letter-spacing: 3vw;

line-height: 1.2;

font-size: 3vw;

text-align: center;

span {

display: block;

font-size: 10vw;

letter-spacing: -1.3vw;

}

}

main {

background: rgba(black, 0.66);

color: white;

position: relative;

padding: 1rem;

p {

max-width: 600px;

margin: 1rem auto;

}

}

Example


/*

  • Fallback bokuh
  • webm?
  • poster=""
  • Full page always
  • Full page, then scroll
  • Just header
  • Browser compat

*/

Example


### One Viewport Header, Content Scrolls Over Header

The text may scroll past the heading located above the video or remain stationary. Employing margin-top: 100vh to anchor the video and heading in place while guaranteeing that the main content is shifted out of view is a method to achieve this effect.

HTML:

<header class="video-header">

<video src="https://placehold.co/800x200/1abc9c/ffffff?text=Banner" autoplay loop playsinline muted></video>

<h1>

Explore

beach

</h1>

</header>

<main>

[[[https://mixkit.co/free-stock-video/white-sand-beach-background-1564/]]]

</main>

Example


@mixin coverer {

width: 100vw;

height: 100vh;

position: absolute;

top: 0;

left: 0;

}

.video-header {

position: absolute;

text-align: center;

width: 100vw;

height: 100vh;

&, video, .viewport-header {

@include coverer;

}

video {

background: brown;

object-fit: cover;

}

.viewport-header {

display: flex;

align-items: center;

justify-content: center;

}

}

html, body {

height: 100%;

overflow-x: hidden;

}

html {

font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";

font-size: 150%;

line-height: 1.4;

}

body {

margin: 0;

}

h1 {

font-family: 'Syncopate', sans-serif;

color: white;

text-transform: uppercase;

letter-spacing: 3vw;

line-height: 1.2;

font-size: 3vw;

text-align: center;

span {

display: block;

font-size: 10vw;

letter-spacing: -0.6rem;

}

}

main {

background: white;

position: relative;

padding: 1rem;

margin-top: 100vh;

&::before {

content: "";

@include coverer;

top: -100vh;

}

p {

max-width: 600px;

margin: 1rem auto;

}

}

Example


Enhancing the user experience, we can implement a feature where the header text gradually fades into the background as the user scrolls. This effect can be achieved by incorporating opacity and scale modifications based on the scroll position. Leveraging CSS custom attributes simplifies the implementation of this functionality. Feel free to explore this concept in action by checking out the provided demo.

HTML:

<header class="video-header">

<video src="https://placehold.co/800x200/1abc9c/ffffff?text=Banner" autoplay loop playsinline muted></video>

<h1>

Explore

Montana

</h1>

</header>

<main>

[[[https://mixkit.co/free-stock-video/white-sand-beach-background-1564/]]]

</main>

Example


:root {

--headerOpacity: 1;

--headerScale: 1;

}

@mixin coverer {

width: 100vw;

height: 100vh;

position: absolute;

top: 0;

left: 0;

}

.video-header {

position: absolute;

text-align: center;

width: 100vw;

height: 100vh;

&, video, .viewport-header {

@include coverer;

}

video {

background: brown;

object-fit: cover;

}

.viewport-header {

display: flex;

align-items: center;

justify-content: center;

opacity: 1;

opacity: var(--headerOpacity);

transform: scale(var(--headerScale));

}

}

html, body {

height: 100vh;

overflow-x: hidden;

}

html {

font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";

font-size: 150%;

line-height: 1.4;

}

body {

margin: 0;

}

h1 {

font-family: 'Syncopate', sans-serif;

color: white;

text-transform: uppercase;

letter-spacing: 3vw;

line-height: 1.2;

font-size: 3vw;

text-align: center;

span {

display: block;

font-size: 10vw;

letter-spacing: -1.3vw;

}

}

main {

background: white;

position: relative;

padding: 1rem;

margin-top: 100vh;

&::before {

content: "";

@include coverer;

top: -100vh;

}

p {

max-width: 600px;

margin: 1rem auto;

}

}

Example


var viewportHeader = document.querySelector(".viewport-header");

document.body.addEventListener("scroll", function(event) {

var opacity = (document.body.offsetHeight - document.body.scrollTop) / document.body.offsetHeight;

var scale = (document.body.offsetHeight - document.body.scrollTop) / document.body.offsetHeight;

document.documentElement.style.setProperty('--headerOpacity', opacity);

document.documentElement.style.setProperty('--headerScale', scale);

});

Example


Input Required

This code uses input(). Please provide values below: