Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scale and reposition iframe like background-size: cover

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?

like image 668
Toni Michel Caubet Avatar asked Oct 31 '15 12:10

Toni Michel Caubet


People also ask

What is cover background size?

Pretty sure background-size: cover; means the image will fill the element while maintaining its aspect ratio, while background-size: 100%; will just make the image fill 100% width of the element.

What is difference between cover and contain in background size?

cover tells the browser to make sure the image always covers the entire container, even if it has to stretch the image or cut a little bit off one of the edges. contain , on the other hand, says to always show the whole image, even if that leaves a little space to the sides or bottom.

How do you cover a video in HTML?

If the video's parent element is set to cover the entire page (such as position: fixed; width: 100%; height: 100vh; ), then the video will, too. Of course, vw , vh , and transform are CSS3, so if you need compatibility with much older browsers, you'll need to use script. This is the best answer.


2 Answers

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.

like image 116
Hidden Hobbes Avatar answered Sep 23 '22 19:09

Hidden Hobbes


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)

like image 33
Alvaro Menéndez Avatar answered Sep 22 '22 19:09

Alvaro Menéndez