50

I would like to use a video as background in CSS3. I know that there is no background-video property, but is it possible to do this behavior. Using a fullsize video-tag doesn't give the wanted result, cause there is content that need to be displayed over the video.

It need to be non JS. If it is not possible then I need to do changes on my serverside an give as result also a screenshot of the video.

I need the video to replace the colored boxes:

Boxes

The colored boxes are atm just, CSS boxes.

5
  • possible duplicate of stackoverflow.com/questions/18911766/… Commented Dec 28, 2013 at 20:11
  • I need a non JS version
    – Knerd
    Commented Dec 28, 2013 at 20:13
  • 2
    Google to the rescue? benkaminski.com/2013/05/26/… Commented Dec 28, 2013 at 20:21
  • Doesn't work, cause I need to display text over the video.
    – Knerd
    Commented Dec 28, 2013 at 20:23
  • @ZachSaucier Sry, that I didn't respond, it may take a little time, cause there are atm more important parts, I'll try to check it today :)
    – Knerd
    Commented Dec 29, 2013 at 19:30

3 Answers 3

54

Pure CSS method

It is possible to center a video inside an element just like a cover sized background-image without JS using the object-fit attribute or CSS Transforms.

2021 answer: object-fit

As pointed in the comments, it is possible to achieve the same result without CSS transform, but using object-fit, which I think it's an even better option for the same result:

.video-container {
    height: 300px;
    width: 300px;
    position: relative;
}

.video-container video {
  width: 100%;
  height: 100%;
  position: absolute;
  object-fit: cover;
  z-index: 0;
}

/* Just styling the content of the div, the *magic* in the previous rules */
.video-container .caption {
  z-index: 1;
  position: relative;
  text-align: center;
  color: #dc0000;
  padding: 10px;
}
<div class="video-container">
    <video autoplay muted loop>
        <source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4" />
    </video>
    <div class="caption">
      <h2>Your caption here</h2>
    </div>
</div>


Previous answer: CSS Transform

You can set a video as a background to any HTML element easily thanks to transform CSS property.

Note that you can use the transform technique to center vertically and horizontally any HTML element.

.video-container {
  height: 300px;
  width: 300px;
  overflow: hidden;
  position: relative;
}

.video-container video {
  min-width: 100%;
  min-height: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateX(-50%) translateY(-50%);
}

/* Just styling the content of the div, the *magic* in the previous rules */
.video-container .caption {
  z-index: 1;
  position: relative;
  text-align: center;
  color: #dc0000;
  padding: 10px;
}
<div class="video-container">
  <video autoplay muted loop>
    <source src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" type="video/mp4" />
  </video>
  <div class="caption">
    <h2>Your caption here</h2>
  </div>
</div>

10
  • 2
    This is clever thinking. I was able to add scale(2) to the transform, and add an overflow: hidden; to the container div to achieve the full size responsive clipped video background I was looking for.
    – lakewood
    Commented May 16, 2019 at 15:43
  • 7
    This is actually the correct answer to this question!
    – stamat
    Commented Jun 18, 2019 at 12:23
  • 2
    @vars you can use object-fit: cover; on the video tag to make it fullscreen. This way you can easily position the video as well (object-position: center center;)
    – ElBrm
    Commented Dec 17, 2019 at 14:06
  • 2
    I had to add the following to get this working: width: 100%; height: 100%; object-fit: cover;
    – Andy P
    Commented Sep 10, 2020 at 14:32
  • 2
    The way to go: width: 100%; height: 100%; object-fit: cover; object-position: center center;
    – pixelearth
    Commented Feb 10, 2021 at 7:01
26

Why not fix a <video> and use z-index:-1 to put it behind all other elements?

.video-container {
  position: fixed;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}


/* Demo-only styles */

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

.content {
  margin-top: 300px;
  background: black;
  color: white;
}
<div class="video-container">
  <video muted autoplay poster="http://media.w3.org/2010/05/sintel/poster.png" style="width:100%; height:100%">
      <source id="mp4" src="http://media.w3.org/2010/05/sintel/trailer.mp4" type="video/mp4">
      <source id="webm" src="http://media.w3.org/2010/05/sintel/trailer.webm" type="video/webm">
      <source id="ogv" src="http://media.w3.org/2010/05/sintel/trailer.ogv" type="video/ogg">
      <p>Your user agent does not support the HTML5 Video element.</p>
    </video>
</div>
<div class='content'>
  I'm content!! :D
</div>

If you want it within a container you have to add a container element and a little more CSS:

.vidContain {
  width: 300px;
  height: 200px;
  position: relative;
  display: inline-block;
  margin: 10px;
}

.vid {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: -1;
}


/* Demo-only styles */

html,
body {
  width: 100%;
  height: 100%;
  margin: 0;
  padding: 0;
}

.content {
  position: absolute;
  top: 0;
  left: 0;
  background: black;
  color: white;
}
<div class='vidContain'>
  <div class='vid'>
    <video muted autoplay preload="none" poster="http://media.w3.org/2010/05/sintel/poster.png" style="width:100%; height:100%">
            <source id="mp4" src="http://media.w3.org/2010/05/sintel/trailer.mp4" type="video/mp4"/>
            <source id="webm" src="http://media.w3.org/2010/05/sintel/trailer.webm" type="video/webm"/>
            <source id="ogv" src="http://media.w3.org/2010/05/sintel/trailer.ogv" type="video/ogg"/>
            <p>Your user agent does not support the HTML5 Video element.</p>
    </video>
    <div class='content'>
      I'm content!! :D
    </div>
  </div>
</div>

<div class='vidContain'>
  <div class='vid'>
    <video muted autoplay preload="none" poster="http://media.w3.org/2010/05/sintel/poster.png" style="width:100%; height:100%">
            <source id="mp4" src="http://media.w3.org/2010/05/sintel/trailer.mp4" type="video/mp4"/>
            <source id="webm" src="http://media.w3.org/2010/05/sintel/trailer.webm" type="video/webm"/>
            <source id="ogv" src="http://media.w3.org/2010/05/sintel/trailer.ogv" type="video/ogg"/>
            <p>Your user agent does not support the HTML5 Video element.</p>
        </video>
    <div class='content'>
      I'm more content!! :D
    </div>
  </div>
</div>

10
  • Doesn't work, I need the video to replace the colored boxes, see my edit :)
    – Knerd
    Commented Jan 2, 2014 at 20:59
  • 1
    @Knerd So use the same approach but add a container. I updated my answer Commented Jan 5, 2014 at 23:45
  • Oh sry, I just forgot again, but it does work now :) Thank you very much :) I just have a padding in my grid thing, but doesn't matter.
    – Knerd
    Commented Jan 24, 2014 at 19:32
  • Looks broken in Chrome.
    – AturSams
    Commented Jul 11, 2017 at 14:42
  • @zehelvion It still works just fine. The videos are not clickable, but that's not part of the question. You can add the autoplay attribute to see the video working. Commented Jul 11, 2017 at 15:00
19

I believe this is what you're looking for. It automatically scaled the video to fit the container.

DEMO: http://jsfiddle.net/t8qhgxuy/

Video need to have height and width always set to 100% of the parent.

HTML:

<div class="one"> CONTENT OVER VIDEO
    <video class="video-background" no-controls autoplay src="https://dl.dropboxusercontent.com/u/8974822/cloud-troopers-video.mp4" poster="http://thumb.multicastmedia.com/thumbs/aid/w/h/t1351705158/1571585.jpg"></video>
</div>

<div class="two">
    <video class="video-background" no-controls autoplay src="https://dl.dropboxusercontent.com/u/8974822/cloud-troopers-video.mp4" poster="http://thumb.multicastmedia.com/thumbs/aid/w/h/t1351705158/1571585.jpg"></video> CONTENT OVER VIDEO
</div>

CSS:

body {
    overflow: scroll;
    padding:  60px 20px;
}

.one {
    width: 90%;
    height: 30vw;
    overflow: hidden;
    border: 15px solid red;
    margin-bottom: 40px;
    position: relative;
}

.two{
    width: 30%;
    height: 300px;
    overflow: hidden;
    border: 15px solid blue;
    position: relative;
}

.video-background { /* class name used in javascript too */
    width: 100%; /* width needs to be set to 100% */
    height: 100%; /* height needs to be set to 100% */
    position: absolute;
    left: 0;
    top: 0;
    z-index: -1;
}

JS:

function scaleToFill() {
    $('video.video-background').each(function(index, videoTag) {
       var $video = $(videoTag),
           videoRatio = videoTag.videoWidth / videoTag.videoHeight,
           tagRatio = $video.width() / $video.height(),
           val;

       if (videoRatio < tagRatio) {
           val = tagRatio / videoRatio * 1.02; <!-- size increased by 2% because value is not fine enough and sometimes leaves a couple of white pixels at the edges -->
       } else if (tagRatio < videoRatio) {
           val = videoRatio / tagRatio * 1.02;
       }

       $video.css('transform','scale(' + val  + ',' + val + ')');

    });    
}

$(function () {
    scaleToFill();

    $('.video-background').on('loadeddata', scaleToFill);

    $(window).resize(function() {
        scaleToFill();
    });
});
1
  • 1
    Is it available without JavaScript? I would like a pure HTML and JS solution for the problem.
    – Knerd
    Commented Jan 28, 2015 at 9:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.