57

I usually use a similar solution to this one. Something like:

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

But this time I have no access to the HTML or JavaScript code so I can't use a wrapper to prevent the height:0.

Is there a way to make an iframe responsive (and to keep the ratio) with only CSS?

Tried this (works with the iframe but not with its content):

iframe {
    width: 100%;
    background: red;
    height: 0;
    padding-bottom: 33%;    
}

fiddle

Any thoughts? No need to support old browsers so even a CSS3 solution would be great.

Toni Michel Caubet
  • 19,333
  • 56
  • 202
  • 378

7 Answers7

87

Here is a Fiddle for a solution, that is based on a CSS2 secret: https://jsfiddle.net/59f9uc5e/2/

<div class="aspect-ratio">
  <iframe src="" width="550" height="275" frameborder="0"></iframe>
</div>

<style>
/* This element defines the size the iframe will take.
   In this example we want to have a ratio of 25:14 */
.aspect-ratio {
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: 56.25%; /* The height of the item will now be 56.25% of the width. */
}

/* Adjust the iframe so it's rendered in the outer-width and outer-height of it's parent */
.aspect-ratio iframe {
  position: absolute;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
}
</style>

It is explained by how percentage-values for padding are handled:

The percentage is calculated with respect to the width of the generated box's containing block, even for 'padding-top' and 'padding-bottom'.

https://www.w3.org/TR/CSS2/box.html#padding-properties

radu122
  • 2,865
  • 24
  • 24
SimonSimCity
  • 6,415
  • 3
  • 39
  • 52
  • Please add a reason why I got downvoted, so I can improve my answer. – SimonSimCity Mar 29 '16 at 14:05
  • I haven't see a result on your jsfiddle link – Kemal Duran Apr 05 '16 at 12:18
  • @KemalDuran I do ... please confirm you can see iframes and have access to the youtube video. If you can't, just test it using another iframe ;) I bed your browser is one of the modern ones, right ..? – SimonSimCity Apr 05 '16 at 13:10
  • 2
    "But this time I have no access to the html code or the javascript so I can't use a wrapper to prevent the height:0" – Toni Michel Caubet Feb 20 '17 at 12:28
  • 1
    It may be worth noting that it won't work when `.aspect-ratio`/wrapper has set `display: grid`. With `display: block` it works just fine! – kamyl Nov 22 '17 at 13:01
  • 2
    Way more flexible than the selected answer, as this will adjust to any container size, not just the viewport! – panepeter Sep 10 '18 at 07:09
  • @panepeter +1, this one works great for embedding videos in online documentation where there are sidebars for navigation. You can see an example of it in use here: https://docs.netsyms.com/docs/BinStack/Locations%20and%20Categories/ – Skylar Ittner Sep 15 '18 at 00:57
  • 1
    I had trouble with this answer b/c I believe something's missing. You need a parent container for the aspect-ratio div. This parent's only purpose is to set a width. It's needed b/c padding-bottom within the aspect-ratio div is actually based off the parent container's width. Your code only works b/c you've set the aspect-ratio div's width to 100% which is conveniently the same as the parent container's (the body). If you change its width (let's say 50% for half the screen), the aspect ratio's lost. But with a parent container width of 50% it works! That's why it's needed for responsiveness. – Jordy Jan 21 '20 at 14:57
54

Use the new CSS viewport units vw and vh (viewport width / viewport height)

FIDDLE

iframe {
    width: 100vw; 
    height: 56.25vw; /* 100/56.25 = 560/315 = 1.778 */
    background:red;  
}

Browser support is also good: IE9+ (caniuse)

Danield
  • 121,619
  • 37
  • 226
  • 255
  • @ToniMichelCaubet I updated the fiddle to mremove unnecesarry scrollbars – Danield Aug 14 '14 at 09:12
  • 20
    That only works if you want iframe to match the viewport size. However, if you need something that adapts to available width (that is, the content width of parent element of the iframe element) then you need to view the answer by SimonSimCity. – Mikko Rantalainen Feb 18 '16 at 11:41
  • I don't like that solution because of what @MikkoRantalainen said. But instead of working with padding i'd prefer the use of images (data-uri) to make sure the aspect ratio keeps correct. See Fly1nP4nda's answer + my comment for that one. Or check that fiddle: https://jsfiddle.net/kfafrz57/ – rcd Aug 24 '16 at 07:49
  • 1
    @MikkoRantalainen you can always use `width: calc(100vw -20%)` asuming it's using only 80% of the viewport width. Probably also calc with the height would be needed. – Toni Michel Caubet Feb 07 '19 at 18:22
14

With css aspect-ratio it's easy.

iframe {
  height: auto;
  width: 100%;
  aspect-ratio: 16 / 9;
}
jontro
  • 10,241
  • 6
  • 46
  • 71
13

Calc function makes it much more readable:

.iframe-video {
    width: 755px;
    height: 424px;
    max-width: 100%;
    max-height: calc((100vw - 40px) / (16/9));
}
  • width and height is size for desktop and also fallback to ancient browsers
  • 40px is margin (20 px between iframe border and viewport border on both sides)
  • 16/9 is ratio of video (if you have edge-to-edge player)
Bobík
  • 1,828
  • 20
  • 19
  • if you use this one with CSS iframe, it also works without a wrapper div and scales on all devices. The height and width don't really matter anymore, it scales automatically to the width of the div it is in. Very usable for Bootstrap packages and the likes. Excellent trick this one! – KJS Jan 24 '21 at 20:20
1
<div>
  <div style="position:relative;padding-top:56.25%;">
    <iframe src="https://www.youtube.com/embed/nckseQJ1Nlg" frameborder="0" allowfullscreen
      style="position:absolute;top:0;left:0;width:100%;height:100%;"></iframe>
  </div>
</div>

Please add this styling to the web url content you are trying to load. It will keep the 16:9 aspect ratio.

Mahesh Paul
  • 49
  • 10
1

I had the same issue and this worked for me:

.wrapper iframe{
 
width: 100%; /* This Forces video to 100% of parent's width */
height:unset; /* This Overwrites the height attribute of Youtube's embed code */
aspect-ratio: 16 / 9; /* This adjusts video height to keep the desired aspect ratio*/

}
0

This is kind of hackish however you can use images to preserve the aspect ratio of a video. For example I went to paint and saved an image of 1280 x 720 resolution to use for a 16:9 aspect ratio (in here I will just grab a blank image off the internet somewhere).

This works because if you change the width of an image while leaving height auto, vise-versa the image will automatically scale - keeping proportions.

img {
  display: block;
  height: auto;
  width: 100%;
}
iframe {
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
}
.wrapper {
  float: left;
  position: relative;
}
<div class="wrapper">
  <img src="http://www.solidbackgrounds.com/images/1280x720/1280x720-ghost-white-solid-color-background.jpg" alt=""/>
  <iframe width="560" height="315" src="https://www.youtube.com/embed/HkMNOlYcpHg" frameborder="0" allowfullscreen></iframe>
</div>
Fly1nP4nda
  • 188
  • 1
  • 4
  • 3
    Using images is the best solution, because you can easily change the size of the iframe to 50% of the viewport (or 20%, or whatever you responsive website needs). But instead of loading an image over http i'd use a data-uri with an empty 16:9 image: `` – rcd Aug 24 '16 at 07:44
  • Just saw the data-uri method, that is a solid idea +1. I also want to mention that this and the image scaling method works in older browsers (mainly IE) when certain CSS3 (more awesome) properties may not be supported yet. – Fly1nP4nda Sep 10 '16 at 19:20
  • 1
    "But this time I have no access to the html code or the javascript so I can't use a wrapper to prevent the height:0" – Toni Michel Caubet Feb 20 '17 at 12:29
  • 1
    Or consider using SVG for the placeholder: ``. – Константин Ван Nov 12 '19 at 02:39