36

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
.sized {
  height: 100%;
  position: relative;
  background: #eee;
  overflow:hidden;
  padding:0;
}
.sized iframe {
  position:absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
@media (min-width: 320px) {
  height: 200%;
  top: -50%;
}
@media (min-width: 640px) {
  height: 180%;
  top: -40%;
}
<div class="sized">
  <iframe src="https://player.vimeo.com/video/135335257?autoplay=false" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
</div>

<h3>Original video</h3>
<iframe src="https://player.vimeo.com/video/135335257?autoplay=false" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>

As I get a cookies same origin error in the snippets result, here is a mirror:

https://jsfiddle.net/07Lffw5x/2/embedded/result/

[edit] Maybe this is a better demo, if you compare to this one, there is not much difference... why? [/edit]

I'm trying to reproduce a background-size cover for an iframe.

The thing is that it seems to rescale the video, for bigger sizes only,

Question,

Can the rescales take effect on every breakpoint? or the vimeo player might rescale by it's own anyway?

Toni Michel Caubet
  • 17,157
  • 49
  • 178
  • 335
  • I'm not entirely clear what you are asking for, do you want to keep the `iframe` at the correct aspect ratio so there are no black bars? Would you be able to provide a image showing exactly what you after, it may help clarify things. – Hidden Hobbes Nov 03 '15 at 12:28
  • There's a snippet. Does it not work for you? (But removing the black spaces is more important than the perfect aspect ratio) – Toni Michel Caubet Nov 03 '15 at 12:41
  • The snippet works but I'm not 100% clear what your desired result is. To check if I am on the right lines, is this what you are after? https://jsfiddle.net/ysgsaqs8/ – Hidden Hobbes Nov 03 '15 at 12:48
  • I need the same as you, with a fixed height. Any thoughts? thanks! ( that's why i think we need to rescale and reposition ) – Toni Michel Caubet Nov 03 '15 at 12:49
  • 2
    Right, I think I understand, so you want the video to fill the whole `iframe` but rather than stretching the video you want parts of the video to be cut off (if required)? – Hidden Hobbes Nov 03 '15 at 12:51
  • That is correct! excuse my english.. ! – Toni Michel Caubet Nov 03 '15 at 12:56
  • so you want a iframe that covers the intire page? –  Nov 03 '15 at 20:10
  • just the entire container, but yes! (well, not the iframe; the video of the iframe; no black borders or anything, even if we have to miss some of it (just like in my jsfiddle, but for all resolutions) – Toni Michel Caubet Nov 03 '15 at 20:17
  • have you tried setting a fixed height (example: height:200px;) and overflow:hidden; ? – Eduardo La Hoz Miranda Nov 03 '15 at 20:25
  • @EduardoLaHozMiranda the thing is I need it responsive... I don't think its a say to go.. ( rembember I'm trying to get rid of the black bars..) – Toni Michel Caubet Nov 03 '15 at 20:26
  • You could use media queries to handle the height at all your screen requirements. – Eduardo La Hoz Miranda Nov 03 '15 at 20:28
  • I tried, but being an iframe and not a video, it doesn't work; the iframe must resize the video with media querys allready? – Toni Michel Caubet Nov 03 '15 at 20:29
  • Why not adjust the div element instead of the iframe; is it possible to within your site design to set the height of the containing div element to be zero and use a padding hack to keep the video aspect ratio? For example setting the padding-top or padding-bottom to the inverse of the video aspect ratio (56.25% for a 16:9 video) removes the black bars. – AndW99 Nov 04 '15 at 10:40
  • You didnt understan my issue... I want a fixed height for the container – Toni Michel Caubet Nov 04 '15 at 10:41
  • Ok, understand now, if you have a fixed div requirement have you tried looking at a jQuery solution? One that I have used in the past works in any div element (I used it for background video) is a plugin called bigvideo.js http://dfcb.github.io/BigVideo.js/ – AndW99 Nov 04 '15 at 11:22
  • Interesting! i might consider If question expires without a CSS solution! thank you ! – Toni Michel Caubet Nov 04 '15 at 11:40

2 Answers2

45

Similar to Alvaro Menendez's answer, credit needs to go to this answer stackoverflow.com/a/29997746/3400962 by Qwertman. I got as far as using the "padding percentage" trick, but this answer's clever use of viewport units is crucial to this working.

The key to implementing this behaviour is to ensure two things:

  1. That the iframe always maintains the same aspect ratio as its video content 16 : 9. This will ensure that no black "padding" is present around the outside of the video
  2. That the iframe always fills the height or width depending on the size of the viewport

One way to maintain the aspect ratio of an element is to use the "padding percentage" trick which takes advantage of the fact that top and bottom padding uses the width of the element as the basis for their value. Using the formula B / (A / 100) = C% we can calculate the required percentage for the padding. Given the video has a 16 : 9 ratio this translates to 9 / (16 / 100) = 56.25.

The only problem is that in your case the calculation is required for both the horizontal and vertical axis (as we don't know what dimensions the viewport will be) and this trick will not work with left and right padding to get the aspect ratio in relation to the height.

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}
.container {
    background: #eee;
    height: 100%;
    overflow: hidden;
    padding: 0;
    position: relative;
}
.inner {
    left: 50%;
    min-height: 43.75%;
    padding-top: 56.25%;
    position:absolute;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
}
.container iframe {
    bottom: 0;
    height: 100%;
    left: 0;
    position:absolute;
    right: 0;
    top: 0;
    width: 100%;
}
<div class="container">
    <div class="inner">
        <iframe src="https://player.vimeo.com/video/135335257?autoplay=false" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
    </div>
</div>

https://jsfiddle.net/w45nwprn/ (Snippet doesn't show video, please see fiddle)

Luckily, in your case you want the video to fit the entire screen so viewport units can be used to calculate the aspect ratio instead of percentages. This allows use to calculate the width in relation to the height and vica versa:

  • left: 50%;, top: 50%; and transform: translate(-50%, -50%); are required to center the iframe in .container
  • min-height: 100%; and min-width: 100%; are required to ensure that the height and width are never smaller than that of .container
  • height: 56.25vw; will set the height in relation to the width of the viewport. This is calculated by doing 9 / (16 / 100) = 56.25
  • width: 177.77777778vh; will set the width in relation to the height of the viewport. This is calculated by doing 16 / (9 / 100) = 177.77777778

Because the height and width can never be below 100% but the must remain in the correct aspect ratio the video will always cover the whole viewport.

html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}
.container {
    background: #eee;
    height: 100%;
    overflow: hidden;
    padding: 0;
    position: relative;
}
iframe {
    box-sizing: border-box;
    height: 56.25vw;
    left: 50%;
    min-height: 100%;
    min-width: 100%;
    transform: translate(-50%, -50%);
    position: absolute;
    top: 50%;
    width: 177.77777778vh;
}
<div class="container">
    <iframe src="https://player.vimeo.com/video/135335257?autoplay=false" frameborder="0" webkitallowfullscreen="" mozallowfullscreen="" allowfullscreen=""></iframe>
</div>

https://jsfiddle.net/qk00ehdr/ (Snippet doesn't show video, please see fiddle)

Viewport units are widely supported, so as long as you are not targeting old browsers this method should work.

Hidden Hobbes
  • 12,696
  • 3
  • 30
  • 59
  • That's a clever use of css to achieve the solution. While I don't like (yet) the use of `vw` and `hw`I know it's the future (and a close one). You have my upvote and you may get the bounty if the op doesn't need much full "a bit older" brower compatibility. – Alvaro Menéndez Nov 09 '15 at 23:24
  • Thanks @AlvaroMenéndez. Between this and your answer I think we've got Toni's problem covered pretty well. I haven't had much use for viewport units either but it looks like they could come in handy every now and then. If IE8 support is required it should be possible to detect if viewport units are supported and switch to the JavaScript method when necessary. – Hidden Hobbes Nov 10 '15 at 09:24
  • Now the problem is mine because I don't know who to award to... haha! – Toni Michel Caubet Nov 10 '15 at 10:14
  • It's fine. Don't worry. You acepted the answer that works better for you as It should be. Gl with your project – Alvaro Menéndez Nov 10 '15 at 15:46
  • 1
    I had a custom sized web view in an iOS application and the iframe would not scale to fit properly. This did it for me. Thank you! – Alex Nguyen Feb 27 '18 at 17:55
  • Glad I could help @AlexNguyen. – Hidden Hobbes Feb 28 '18 at 10:53
7

Ok. The merit is NOT mine as I got the jquery here

I remembered that question as I used it on one of my old projects and I wanted to check if it would work the same with an iframe. It does.

basically with this css:

.container {
    position: absolute;
    top: 0;
    overflow: hidden;
}

and this jquery:

var min_w = 300; // minimum video width allowed
var vid_w_orig;  // original video dimensions
var vid_h_orig;

jQuery(function() { // runs after DOM has loaded

    vid_w_orig = parseInt(jQuery('iframe').attr('width'));
    vid_h_orig = parseInt(jQuery('iframe').attr('height'));

    jQuery(window).resize(function () { resizeToCover(); });
    jQuery(window).trigger('resize');
});

function resizeToCover() {

    // set the video viewport to the window size
    jQuery('.container').width(jQuery(window).width());
    jQuery('.container').height(jQuery(window).height());

    // use largest scale factor of horizontal/vertical
    var scale_h = jQuery(window).width() / vid_w_orig;
    var scale_v = jQuery(window).height() / vid_h_orig;
    var scale = scale_h > scale_v ? scale_h : scale_v;

    // don't allow scaled width < minimum video width
    if (scale * vid_w_orig < min_w) {scale = min_w / vid_w_orig;};

    // now scale the video
    jQuery('iframe').width(scale * vid_w_orig);
    jQuery('iframe').height(scale * vid_h_orig);
    // and center it by scrolling the video viewport
    jQuery('.container').scrollLeft((jQuery('iframe').width() - jQuery(window).width()) / 2);
    jQuery('.container').scrollTop((jQuery('iframe').height() - jQuery(window).height()) / 2);
};

You get this: JSFIDDLE

(I know you were looking for a pure css solution, which I don't think it's possible but I can be wrong, but I have posted this answer because it could help other people with same issue)

Community
  • 1
  • 1
Alvaro Menéndez
  • 7,646
  • 3
  • 30
  • 53
  • I was affraid of not finding a CSS solution, I'll give the bounty it's time, but this seems the way to go! (not plugins or anything, looks good!). And it seems that the trick is play with scrollLeft and scrollTop, not left & top! – Toni Michel Caubet Nov 07 '15 at 14:57
  • In the same link I posted where I got this script there are some css solutions. I have just checked them but I think none will work with an iframe but again... I may be wrong. I don't have time atm to propely checked them in a fiddle. maybe you want to give it a try. – Alvaro Menéndez Nov 07 '15 at 21:34