Responsive videos are, at times, tricky. Especially when you’re trying to embed a video from YouTube or Vimeo. You see, by default, YouTube videos “respond” by shrinking their width but keeping their height. Ultimately, this results in cropping the video down to a weird square.
Try resizing your browser. See how the video crops?
When you play the video, the inside will resize to the correct aspect ratio, so you have a lot of extra black space at the top and the bottom. Like when you were watching a “wide screen” movie on a square CRT TV in like, 2001.
This approach is perfectly functional. It doesn’t really inhibit the user from playing the video. It’s just butt-ugly. So for years, designers and developers have been coming up with better responsive video solutions.
Basic Responsive Video Embeds
The standard way to embed a video responsively is to put it some kind of container or wrapper that has a fixed aspect ratio (usually 16:9) and then absolutely position the video within the container, so it takes up all of the available space.
There are scripts, like FitVids, which use JavaScript to wrap embedded videos in a fluid-width container. Since it automatically detects where the videos are and inserts the video container, it requires no extra work on the user’s part.
But adding extra JavaScript to your website can slow it down. So, often times developers just include their own responsive video CSS and make sure that all added videos get wrapped in a special container so they respond properly.
Their CSS will look something like this:
/* Container/Wrapper Styles */ .video-wrap { position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden; max-width: 100%; } /* Actual Video Styles */ .video-wrap iframe, .video-wrap object, .video-wrap embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
And every time they add a video, they have to manually add the wrapper, like so:
<div class="video-wrap"> <iframe width="560" height="315" src="https://www.youtube.com/embed/d3sA5plF6kE" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe> </div>
This will resize the video on mobile, making sure it maintains it’s 16:9 aspect ratio and doesn’t crop into a weird square:
Whoo, no squares here!
And it really does look nice. On phones, you get a clean normal-looking video player, without the “wide screen” effect:
With very little CSS, you too can have videos that look normal on all screen sizes!
But it can be better.
The only problem with this method (well, besides manually requiring you to put each video in a wrapper) is that it doesn’t allow you to restrict the video’s width. The video is always going to be 100% of the parent container.
Which is fine, if that’s what you want. But once you get into large, full-width layouts, having a video that takes up the full screen might not be desirable.
For example – if your content area is 1200px wide, and you use this method, your video is going to be 675px tall. That’s a lot of screen real estate taken up by a video. It also looks a little wonky:
The obvious fix would be to restrict the .video-wrap
container to a maximum width. Change the line max-width: 100%;
to something smaller, say 700px. Easy fix, right?
Err… not exactly:
You see, in CSS, percentage-based padding is based on the parent container. And, confusingly, the top and bottom percentages are based on the parent container’s width.
So, the padding-bottom: 56.25%;
on the .video-wrap
is actually calculating 56.25% of the .video-wrap
‘s parent, which happens to be a 1200px content area. When restricting the width to 700px, the padding is still based off 1200px, and the entire thing gets weird.
There are ways around this. You could do a double video wrap, essentially wrapping your video in two containers: one with a fixed with, and one that makes it responsive. But that adds extra markup to your page and is going to be hard to remember.
Instead, you can do it all with CSS using the :before
pseudo element. First, set the .video-wrap
‘s maximum width (I added some styles here to center the video on the page).
.video-wrap { position: relative; margin: 0 auto 20px; max-width: 700px; }
Then, using the :before
pseudo element, create that 56.25% padding. Since :before
is a child of .video-wrap
, the padding will be calculated on the width of .video-wrap
.
.video-wrap:before { content: ''; display: block; position: relative; padding-bottom: 56.25%; }
Finally, just make sure to tell the video to fill up the wrapper’s available space:
.video-wrap iframe, .video-wrap object, .video-wrap embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
All together, the code looks like this:
/* Container */ .video-wrap { position: relative; margin: 0 auto 20px; max-width: 700px; } /* Before Element */ .video-wrap:before { content: ''; display: block; position: relative; padding-bottom: 56.25%; } /* Video */ .video-wrap iframe, .video-wrap object, .video-wrap embed { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
And the result looks like this:
And, of course, it’s mobile-friendly and looks good. That’s the whole point of “responsive video embeds”, right?
If you want to take this method of responsive videos for a spin, you can take a look at the live demo here.
If this was helpful, leave a comment!
Was this helpful?
I hope it was! If you’re feeling generous, feel free to leave me a tip on my Ko-fi!
Ray Thomas says
A very nice solution Kyrie. Everything else I’ve seen displays the video at 100% which as you say, can look wonky on large displays and so much more elegant than the media queries I’ve been using.
My website is now 21 years old and going through it’s 4th redesign so I thought that this time I might try to get it right. 🙂
Donna says
I just wanted to say this is a lovely minimal solution, with complete and clear instructions. Glad I found it, and thank you so much.