Adjust and resize video backgrounds within parent elements on iframes

Consider the code snippet below:

<div class="viewport">
    <iframe src="youtube.com/blabla"></iframe>
</div>

Accompanied by this CSS:

.viewport {
    height: 100vh;
    width: 100%;
}

iframe {
    position: absolute;
}

If we take into account that the video playing within the iframe has an aspect ratio of 16:9, can a script be written to stretch the iframe beyond its parent's size so that it overflows and hides the black bars present?

To illustrate, let's look at two scenarios that the script should address:

https://i.sstatic.net/3CsGH.png https://i.sstatic.net/iRiuJ.png

In the first scenario, where black bars are visible on the left and right sides of the video, the script would need to stretch the iframe both wider and taller until the black bars disappear. Similarly, in the second scenario with black bars appearing on the top and bottom, the iframe must be stretched accordingly.

While attempting to solve this issue by adjusting the width and height dynamically based on the viewport dimensions, there are cases where the black bars reappear as the aspect ratio changes. The provided script attempts to handle these situations but may not cover all scenarios effectively.

    var block = $('.viewport');
    var block_h = block.outerHeight();
    var block_w = block.outerWidth();

    var ratio = block_w / block_h;

    // If viewport is landscape (black bars on left/right)
    if( ratio >= 1.77777778 ) {
        var video_w = (block_h * 16) / 9; // Get width of video within iframe
        var total_black_bar_w = block_w - video_w; // Black bar total width
        var new_iframe_w = (block_w + total_black_bar_w); // New width of the iframe needed to stretch the video wide enough to hide the black bars
        var adjustment_percentage = new_iframe_w / block_w; // If we adjusted the width by 10% for example, then we also need to apply that percentage to the height

        var new_iframe_h = (block_h * adjustment_percentage) + 30;

        var pull_left = total_black_bar_w / 2; // how far to pull left to center the iframe outside of the parent container
        var pull_top = (new_iframe_h - block_h) / 2; // same for top
    }
    // Portrait viewport (black bars on top/bottom)
    else {
        var video_h = (block_w * 9) / 16;
        var total_black_bar_h = block_h - video_h;
        var new_iframe_h = (block_h + total_black_bar_h);
        var adjustment_percentage = new_iframe_h / block_h;

        var new_iframe_w = (block_w * adjustment_percentage) + 30;

        var pull_left = total_black_bar_w / 2;
        var pull_top = (new_iframe_h - block_h) / 2;
    }

    block.find('iframe').css({
        'width': new_iframe_w,
        'height': new_iframe_h,
        'left': '-' + pull_left + 'px',
        'top': '-' + pull_top + 'px'
    });

Answer №1

To simplify your code, you can resize the entire iframe to match the viewport while maintaining its ratio.

You can achieve this by using CSS positioning and transformations to center it on the screen.

Check out the example below with a smaller viewport (highlighted in red border) to see it in action:

jQuery(function($) {
  var viewport = $('.viewport'),
    frame = viewport.find('iframe'),
    frameRatio = 16 / 9;

  $(window).on('resize', function() {
    var width = viewport.outerWidth(),
      height = viewport.outerHeight(),
      ratio = width / height,
      targetWidth = width,
      targetHeight = height;

    if (ratio > frameRatio) {
      // viewport is wider than video
      // adjust the height
      targetHeight = width / frameRatio;
    } else {
      // viewport is taller than video
      // adjust the width
      targetWidth = height * frameRatio;
    }

    frame.css({
      width: targetWidth,
      height: targetHeight
    });
  }).trigger('resize');
});
.viewport {
  height: 50vh;
  width: 50vw;
  position: relative;
  border: 1px solid red;
  margin: 10% 25%;
}

iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: -1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="viewport">
  <iframe src="//www.youtube.com/embed/1La4QzGeaaQ?autoplay=1"></iframe>
</div>

View the live demo at http://jsfiddle.net/agrxtwn7/embedded/ (click on "Result") since embedding YouTube videos directly may be restricted on certain platforms.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it possible for an SVG to derive its dimensions from the containing element?

I am currently in the process of transitioning a Vue/Vuetify application from using web fonts for Material Design Icons to utilizing SVG icons instead. With the web font, an example of a heading that includes an icon looks like this: <template> &l ...

Updating an event listener during the $(document).ready() function and handling ajax requests

In my Rails 4 application, there is an event listener that I have repeated in three different places. The event listener looks like this: $('.remove-tag-button').on('click', function () { $.ajax({ type: "POST", data: {i ...

Guide to implement the remember me feature in a jQuery AJAX login system

view: login.php <script> $(document).ready(function(){ $("#login").click(function(e){ e.preventDefault(); elogin = $("#elogin").val(); plogin = $("#plogin").val(); remember_me = $("#remembe ...

What could be the reason for Python requests giving me a different text output compared to when I manually visit the website?

I'm in the process of creating a basic 'stock-checker' for a T-shirt that I have my eye on. The link to the product is available here: https://i.stack.imgur.com/usSJN.jpg Upon visiting the page, I noticed that it displays 'Coming Soon ...

Is it possible for the ImageListItem Img to occupy the entire Card Space?

I am faced with the challenge of making an ImageListItem occupy all available space within a card. The goal is to have a rounded Card with an image background and a text bar at the bottom. However, I am struggling to get the ImageListItem to expand beyond ...

Identify when users reach the end of a webpage through scrolling using mousewheel actions and scroll events

I want to track when a user reaches the end of a page and tries to scroll further, even though there is no more content to see. One of my usability metrics includes identifying dead scrolls, so I need a reliable way to detect when users attempt to scroll ...

Is there a way I can decrease the width of the input field on the left side?

body { background: white; font-family: 'Ubuntu', sans-serif; } .cas { display: inline-block; border: 2px solid #0C8346; background: #0C8346; font-weight: 300; font-size: 20px; padding: 5px; width: 200px; text-align: center; ...

How to make an Ajax "POST" request to the server using jQuery or AngularJS without sending any parameter data

"Execute a 'POST' request to the server by using the code provided below However, the parameter data is not being sent to the server. I have attempted both the jQuery Way and var request = $.ajax({ url: baseUrl, type:'post', da ...

Utilizing Jquery.validate() for personalized checkbox validation

My struggle lies in integrating jQuery.validate() with custom-designed checkboxes. I am unable to achieve the desired outcome where, upon clicking SUBMIT without selecting any checkboxes, an error should be displayed in the respective label. Despite having ...

Uploading files using C# and data streaming

I am exploring the various methods of file uploading in .NET, such as using HttpPostedFile and a HttpHandler. I want to delve into the technical details of how this process actually works. Specifically, I am curious about how the data is written to a file ...

What is the best way to create a new variable depending on the status of a button being disabled or enabled

Imagine a scenario where a button toggles between being disabled when the condition is false (opacity: 0.3) and enabled when the condition is true (opacity: 1). Let's set aside the actual condition for now -- what if I want to determine when the butt ...

A sleek and modern fixed navigation bar in Bootstrap 4 featuring two elegantly stacked rows, with a striking brand image perfectly centered

I need help creating a Bootstrap 4 fixed navigation bar with 2 rows. The first row should have a centered brand image like the one on (with the image size changing after scrolling down), and the second row should contain the navigation menu. Thank you i ...

Server response not being awaited by Ajax call

Currently running WAMP v.2.5 on a Windows10 system for my PHP project connected to a MySQL DB that involves multiple AJAX calls, all functioning correctly. However, there is one specific call that keeps throwing an 'Unexpected end of input' error ...

Stop the page from scrolling

I'm trying to find a way to disable page scrolling, so I used this style for the body: overflow: hidden; Surprisingly, it worked perfectly on desktop but had no effect on mobile devices. After checking out this resource, it seems that creating a ch ...

Placing jQuery in the lower part of my HTML templates lacks adaptability

Lately, I've been optimizing my templates by placing the jQuery code link at the end of the template files to ensure fast page load speeds. Along with that, I have specific javascript modules reserved for certain pages that are included within the con ...

Arranging elements in a list according to their position on the canvas using AngularJS

I am currently working on drawing rectangles on an html5 canvas using the JSON format provided below. My goal is to sort the array based on the x and y locations of each element. { "obj0": { "outerRects": [ { "outerRectRoi": { "x1": 0, " ...

What is the best way to extract the elements within a form using Angular and automatically add them to a list?

Recently, I started learning Angular and decided to create a simple list feature. The idea is to input an item name and price, then click "Add item" to see it added to the list below. I have all the code set up correctly, but for some reason the name and ...

Load media upon the click of an image

I'm currently in the process of designing a team page for our website. Each team member's photo is displayed in a grid layout, with two boxes positioned below containing various content. Box 1: This box consists of basic text information. Box 2: ...

Main Article Holder containing Image overlaid with Post Details

I'm struggling to achieve something seemingly simple but can't quite get it to work. My goal is to display article previews on my website in a tiled format. For example, the tiles would have a fixed height and width, say 300px by 300px. I&apos ...

Finding dynamic elements with Selenium WebDriver is an essential skill for any automation tester

<div id="button" data-testid="widgetButton" class=" chat-closed mobile-size__large"> It seems there is an issue with locating elements that have special characters in their names. I'm attempting to click on a specific item, but I've tried ...