50

I have a YouTube video I want to put on my web page.

I want to scale the video to fit to a percent of the users browser but also to keep the aspect ratio.

I have tried this:

<iframe width="87%" height="315" src="http://www.youtube-nocookie.com/embed/dU6OLsnmz7o" frameborder="0" allowfullscreen></iframe>

But that does only make the player wider, not higher.

Does I have to resort to JavaScript (or non-standard CSS)?

Frank
  • 2,640
  • 2
  • 21
  • 21

15 Answers15

78

What i believe to be the best CSS solution.

.auto-resizable-iframe {
  max-width: 420px;
  margin: 0px auto;
}

.auto-resizable-iframe > div {
  position: relative;
  padding-bottom: 75%;
  height: 0px;
}

.auto-resizable-iframe iframe {
  position: absolute;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
}
<div class="auto-resizable-iframe">
  <div>
    <iframe frameborder="0" allowfullscreen="" src="http://www.youtube.com/embed/_OBlgSz8sSM"></iframe>
  </div>
</div>

Demo http://jsfiddle.net/46vp592y/

Darwin
  • 4,686
  • 2
  • 30
  • 22
  • 8
    Best solution by far. Fully responsive. Works like a champ. Though I'd set `padding-bottom` to 60% for widescreen videos. – Daniel Hanrahan Jun 09 '14 at 19:23
  • The credits link points to a page that shows now a date 28 aug 2014, whereas this answer was given in 2013. Moreover that page does not mention what is written here. I reckon the link is no longer relevant. – Marco Faustinelli Feb 08 '15 at 13:45
  • That's great, thank you. I was trying the other solutions, and they would allow me to either make the video look good on mobile or on desktop, but I couldn't make it look good on both mobile and desktop. This answer solved my problem. Thank you. – Overloard Sep 16 '18 at 01:30
  • Dropping that `max-width: 420px;` and setting `padding-bottom: 60%;` as suggested above got me exactly what I needed. Thanks! – Inphinite Phractals Sep 19 '19 at 19:25
  • 1
    56.25% for 16:9 videos – colemars Nov 09 '19 at 02:20
  • Still clips it. Not a solution. – doublejosh Sep 15 '21 at 18:55
  • 2021 this does not work anymore – user1034912 Dec 13 '21 at 07:37
  • 1
    @user1034912 if you follow the jsfiddle link you can see a working example. If I am wrong please tell me what does not work. – Darwin Feb 22 '22 at 13:44
  • Works great, but if you happen to have any menu that would be overlaying over the video then you have another problem as the video will always sit on top (playing with the z-index won't work). – cavpollo Apr 29 '23 at 19:41
16

I hit a similar issue with my site when developing some responsive CSS. I wanted any embedded Youtube objects to resize, with aspect, when switching from the desktop CSS to something smaller (I use media queries to re-render content for mobile devices).

The solution I settled on was CSS and mark-up based. Basically, I have three video classes in my CSS thus:

.video640 {width: 640px; height: 385px}
.video560 {width: 560px; height: 340px}
.video480 {width: 480px; height: 385px}

… and I assign one of these to the Youtube content I include, depending on its original size (you may need more classes, I just picked the most common sizes).

In the media query CSS for smaller devices, these same classes are simply re-stated like so:

.video640 {width: 230px; height: 197px}
.video560 {width: 230px; height: 170px}
.video480 {width: 240px; height: 193px}

I appreciate this requires some mark-up "up-front" when including videos in your HTML (i.e. adding a class), but if you don't want to go down the Javascript route, this works pretty well -- you could re-state your video classes for as many different sizes as you require. Here's how the Youtube mark-up looks:

<object class="video640" type="application/x-shockwave-flash" value="YOUTUBE URL">
  <param name="movie" value="YOUTUBE URL"></param>
</object>
Ben
  • 7,548
  • 31
  • 45
  • Ah, I did not think about media queries for this - My mind was fixated at smooth scaling, but it really does not have to! (How often does you resize your browser? I may do that like 7 times a day tops) Just it fits roughly and looks okay - I'm happy. I'll try it myself before accepting you answer (And giving a chance to someone who might have an better idea, but I doubt that) - thank you :) – Frank Oct 13 '11 at 09:14
12

Quite easy with some javascript.

jQuery(function() {
    function setAspectRatio() {
      jQuery('iframe').each(function() {
        jQuery(this).css('height', jQuery(this).width() * 9/16);
      });
    }

    setAspectRatio();   
    jQuery(window).resize(setAspectRatio);
});
Darwin
  • 4,686
  • 2
  • 30
  • 22
  • 1
    This is a great suggestion for Widescreen Ratio. For standard ratio instead of 9/16(16:9) use 3/4(4:3). – raphie Jul 03 '13 at 15:43
  • I must be missing something, what does the timelineheight var do? Why's it being added to the width? – Eric Jan 15 '14 at 19:35
  • When i wrote this embeded youtube videos where shown with a timeline at the bottom that was 3 pixels high. I have now removed it from the answer as it didn't add anything. – Darwin Jan 16 '14 at 09:40
12

Modern Solution (2022) - aspect-ratio

With the introduction of the aspect-ratio property in CSS, it's now very simple to scale a YouTube video without resorting to CSS hacks or JS.

Example:

iframe {
    aspect-ratio: 16 / 9;
    height: auto;
    width: 100%;
}

The aspect-ratio property is widely supported across browsers making it suitable for the vast majority of sites: https://caniuse.com/mdn-css_properties_aspect-ratio

Nathan Dawson
  • 18,138
  • 3
  • 52
  • 58
11

This jQuery plugin has been making the rounds of late, it's called FitVids and does exactly what you need, resizes videos based on browser size whilst maintaining aspect ratio.

http://fitvidsjs.com/

Ben Everard
  • 13,652
  • 14
  • 67
  • 96
  • This doesn't work with the Youtube HTML5 player if the screen is resized. Youtube sets .html5-video-content div. Otherwise, yes it works great. – Adam S May 07 '12 at 00:58
  • For some reason my ad-blocker (hostsblock) is blocking the fitvidsjs domain. Here's its [github page](https://github.com/davatron5000/FitVids.js) for anyone who needs it. – Daniel Hanrahan Jun 09 '14 at 19:33
7

These work a treat no JS. Responsive for both single palyer and list player modified from somewhere not sure, no credit sorry. Load your iframe Youtube player inside a container div, the iframe style sets the player specific sizing, 100% will fill the container to any size, src= your-youtube-ID, add own player options https://jsfiddle.net/jcb01/04sf3byz/

    <div style=" position: relative; padding-bottom: 56.25%;">
<!--- load iframe Youtube player inside this div -->
<iframe 
style="border: 1; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" 
src="https://www.youtube-nocookie.com/embed/?
list=PL590L5WQmH8fmto8QIHxA9oU7PLVa3ntk;
&autoplay=0&enablejsapi=1&index=0&
listType=playlist&loop=1&modestbranding=1" 
allowfullscreen scrolling="no" 
allow="encrypted-media; accelerometer; 
gyroscope; picture-in-picture">
</iframe>

</div>
jcb01
  • 87
  • 1
  • 4
  • That is perfect. Works with min and max width constraints in %. Personally I use media queries in the meta tags but ultimately in todays society, I use 99% percentage based height and width on top of shifting css files. – JSG Feb 14 '21 at 17:42
  • this doesn't work with max width – user1034912 Dec 13 '21 at 07:33
  • If you want to use max-width, I have found enclosing the whole thing inside an additonal container
    auto margins will center the outer container where ever you put it https://jsfiddle.net/jcb01/3su4twvx/
    – jcb01 Dec 14 '21 at 12:14
2

The trick to make a youtube video autoresize is to make the iframe width 100% and put it in a div with a "padding-bottom" equal to the aspect ratio in percentage. E.g.

But the problem is - you would have a lot of pages with embedded YoutTube videos already. Here's a jquery plugin that will scan all videos on the page and make them resizable automatically by changing the iframe code to be as above. That means you don't have to change any code. Include the javascript and all your YouTube videos become autoresizing. https://skipser.googlecode.com/files/youtube-autoresizer.js

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
arunskrish
  • 417
  • 6
  • 13
1

Old question, but I think the @media CSS 3 tags would be helpful in this instance.

Here is my solution to a similar problem.

The CSS:

@media only screen and (min-width: 769px) {
    .yVid {
        width: 640px;
        height: 360px;
        margin: 0 auto;
    }
}

@media only screen and (max-width: 768px) {
    .yVid {
        width: 560px;
        height: 315px;
        margin: 0 auto;
    }
}

The HTML:

<div class="yVid">
    <iframe width="100%" height="100%" frameborder="0" allowfullscreen="" src="http://www.youtube.com/embed/_OBlgSz8sSM"></iframe>
</div>

This basically adds a breakpoint at 768px where the video resizes itself. You could also add breakpoints at 992 and 1280 for an even more repsonsive video size. (numbers based on Bootstrap standard sizes).

Mr Lister
  • 45,515
  • 15
  • 108
  • 150
todd.pund
  • 689
  • 2
  • 11
  • 36
1

This is what worked for me. This is slightly modified code from the YouTube Embed Code Generator.

The CSS:

.video-container {
    position: relative;
    width: 100%;
    height: 0;
    padding-bottom: 56.27198%;
    }
.video-container iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    }

The HTML:

<div class="video-container">
    <iframe width="560px" height="315px" src="https://www.youtube.com/embed/XXXXxxxx?&theme=dark&autohide=2&iv_load_policy=3"><iframe>
</div>
Lenwood
  • 1,371
  • 16
  • 36
0

In addition to Darwin and Todd the following solution will

  1. avoid the bottom margin
  2. maximize the width for large screens
  3. minimize the height in mobile view
  4. keep a fixed size for @media none compatible browsers

The HTML:

<div class="video_player">
  <div class="auto-resizable-iframe">
    <div>
      <iframe frameborder="0" allowfullscreen="" src="http://www.youtube.com/embed/_OBlgSz8sSM">        </iframe>
    </div>
  </div>
</div>

The CSS:

.videoplayer{

    text-align: center;
    vertical-align: middle;

    background-color:#000000;

    margin: 0;
    padding: 0;

    width: 100%;
    height:420px;

    overflow:hidden;

    top: 0;
    bottom: 0;

}

.auto-resizable-iframe {
    width:100%;
    max-width:100%;
    margin: 0px auto;
}

.auto-resizable-iframe > div {
    position: relative;
    padding-bottom:420px;
    height: 0px;
}

.auto-resizable-iframe iframe {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 100%;
}


//full screen
@media (min-width:0px) {

    .videoplayer{
        height:100%;
    }

    .auto-resizable-iframe > div {
        padding-bottom:100%;
    }           

}

//mobile/pad view
@media (min-width:600px) {

    .videoplayer{
        height:420px;
    }

    .auto-resizable-iframe > div {
        padding-bottom:420px;
    }       

}       
RafaSashi
  • 16,483
  • 8
  • 84
  • 94
  • You should update your code to fix: 1. class name mix-match between the css and the html, 2. wrong code comment style for css. Otherwise, good job. – mr1031011 Dec 30 '17 at 04:11
0

You could use two classes that would scale the size of the video based on the size of the wrapping div. Consider this example:

<div class="content-wrapper">
    <div class="iframe-wrapper res-16by9">   
        <iframe src="https://www.youtube.com/embed/pHsYFURtzzY" frameborder="0" allowfullscreen></iframe>
    </div>
</div>

Now look at the css.

.content-wrapper{
  max-width: 800px;
  margin: 0 auto;
  background-color: #fff;
}

.iframe-wrapper{
  width: 100%;
  position: relative;
}

.res-4by3{
  padding-bottom: 75%;
}

.res-16by9{
  padding-bottom: 56.25%;
}

.iframe-wrapper iframe{
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

Note that you will have to wrap the iframe in a div who's width is set to 100% and position is set to relative. You have to also add a bottom-padding to iframe wrapper. This padding will define the height of a video. I recommend to create two classes that will represent the image ratio.

It is quite easy to calculate the right bottom-padding for wrappers that represent certain resolution. For example for res 4 by 3 and 16 by 9 would have bottom-padding equal to:

[4/3 res]

100 / 4 * 3 = 75%;

[16/9 res]

100 / 16 * 9 = 56.25%

Then position the iframe as absolute and push it to the top left corner of the wraping div. Also meke sure to set iframe width and height to 100%. You are done.

Add the class that fits the right resolution for you. It will scale the image width and height respectively keeping the right proportions in place.

The example above works for any iframe. Thats mean you can also use it for google maps iframe.

DevWL
  • 17,345
  • 6
  • 90
  • 86
0

There are a few suggestions on the list of answers to use js to modify the structure of generated iframe. I think there is a risk with that because when you wrap the iframe inside other elements it's possible that the YouTube API will lose 'connection' with the iframe (especially if you pass the element in as a node instead of using specific id like me). It's rather to get around it actually, use javascript to modify the content before you actually trigger the youtube player.

a snippet from my code:

/**
 * Given the player container, we will generate a new structure like this
 *
 * <div class="this-is-the-container">
 *      <div class="video-player">
 *          <div class="auto-resizable-iframe">
 *              <div>
 *                  <iframe frameborder="0" allowfullscreen="" src="http://www.youtube.com/embed/_OBlgSz8sSM">        </iframe>
 *              </div>
 *          </div>
 *      </div>
 * </div>
 *
 * @return {Node} the real player node deep inside
 */
YouTube.renderResizable = function (playerContainer) {
    // clean up the content of player container
    playerContainer.textContent = '';

    var playerDiv = document.createElement('div');
    playerDiv.setAttribute('class', 'video-player');

    playerContainer.appendChild(playerDiv);

    // add the auto-resizable-frame-div
    var resizeableDiv = document.createElement('div');
    resizeableDiv.setAttribute('class', 'auto-resizable-iframe');

    playerDiv.appendChild(resizeableDiv);

    // create the empty div
    var div = document.createElement('div');
    resizeableDiv.appendChild(div);

    // create the real player
    var player = document.createElement('div');
    div.appendChild(player);

    return player;
};
mr1031011
  • 3,574
  • 5
  • 42
  • 59
0

Just set iframe height and width with CSS vw metric. It uses device width as parameter:

.videoWrapper iframe {
    height: 36.6vw;
    width: 65vw; 
}
Karl Zillner
  • 581
  • 7
  • 16
0

You can use style="max-width: %87; max-height: %87;"

Umur Kontacı
  • 35,403
  • 8
  • 73
  • 96
-2

Add JavaScript code to give each youtube iFrame a class:

$('iframe[src*="youtube"]').addClass('youtube')

Then in the Media Queries use the you tube class to set a different size.

.youtube {
   /* Do stuff here */
}

Easier and optimized to CMS than the manual way.

grmmph
  • 781
  • 2
  • 8
  • 17
  • not really relevant answer. Also you just duplicate selector, nothing else. You can do `iframe[src*="youtube"] {}` in css. [As documented here](https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors) – Eduard Jacko Nov 29 '17 at 13:23