Maintaining aspect ratio of of iframe - javascript

I have an iframe that I want to maintain the aspect ratio at 16:9 (height/width) right now there is an box below the iframe that I don't want the iframe to ever overlap. So I can't use the padding bottom trick because it causes the video to overlap the box. How can I get the maximum width and height that the iframe can attain in the remaining space?
So for example let's say I have a window that is 1200px by 600px, 50px is used for a box. I want the iframe to take the maximum width and height on the remaining 1200px by 550px and still keep its aspect ratio and not ever go below the box at the bottom of the page. How can I do that using jquery? Also as the window resizes the iframe should keep its aspect ratio
I'm asking for the formula that embedded videos use to maintain their aspect ratio in an iframe. When I embed an iframe that has a video in it the video always maintains its aspect ratio by adding black boxes around it.
Here's the HTML:
<div class="iframe-container">
<iframe></iframe>
</div>
<div class="box"></div>

This is pretty straightforward and can be done with CSS, if you know the expected aspect ratio. For video embeds at 16:9 (56.5%), it's done like this.
You can add max-height and max-width properties to the container just as you would any other element. The height is 0 and the padding is simply set according to the aspect ratio you want. The iframe is set to fill the container width and height so it will conform to the aspect ratio based on the padding.
.iframe-container {
position: relative;
padding-bottom: 56.5%;
height: 0;
}
.iframe-container iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Update: You can do this much better with vw units.
This will work if your iframe is intended to be the full width of the browser. Otherwise you can do some calculations on it. But, for a full width iframe that you want to preserve aspect ratio on, it goes as follows (for 16:9 aspect ratio):
iframe {
width: 100vw;
height: 56.5vw;
}

Maintaining an aspect ratio is pretty straightforward with some conditional math, over time.
Generally, we have a container, a thing contained, and a known ratio (16/9). The height or the width can be determined by trapping the thing in the container (checking for out of bounds) and computing the other value from the ratio.
Update : once you have the new values, check for out of bounds. In this case, a min height and a max width.
A bit like so:
// if the iframe height (container width / ratio) is greater than the container height
if ( (cW / RATIO) > cH){
h = cH; // set the height equal to the container
w = cH * RATIO; // set the width equal to the container height * ratio
} else {
w = cW; // set the width equal to the container
h = cW / RATIO; // set the height equal to the container width / ratio
}
// Ok so, now that the iframe is scaled up, check for out of bounds
if ( iH < MIN_HEIGHT ){
iH = MIN_HEIGHT; // set the height to the const
iW = iH * RATIO; // use the same basic formula, but use the new value
}
if (iW > MAX_WIDTH){
iW = MAX_WIDTH; // set the width to the const
iH = iW / RATIO; // same formula, new value
}
- Working fiddle with some discussion.
- Updated fiddle with some out of bounds checks.
You can, obviously, work some extra math into the computation to make space for a control bar, or whatever. This is just the basic principle, in a very simple state. I almost always have some additional checks against max width, or do some positioning or whatever. But this should be a good start.
Cheers -

Related

Canvas element not maintaining height of parent Div

I have a <canvas> in a div and in order to keep its bounds equal to the div I'm using the following code (I'm creating some of my html/css using Javascript for unrelated reasons, I assume doing in JS should be equivalent).
when I create and add the canvas:
this.canvas = document.createElement("canvas")
this.canvasContainerDiv.appendChild(this.canvas)
this.canvas.style.backgroundColor = "orange"
this.canvas.style.width = "100%"
this.canvas.style.height = "100%"
this.canvas.width = this.canvasContainerDiv.clientWidth
this.canvas.height = this.canvasContainerDiv.clientHeight
Then in the window resize callback:
window.onresize = (e) => {
this.canvas.width = this.canvasContainerDiv.clientHeight
this.canvas.height = this.canvasContainerDiv.clientHeight
}
Unfortunately, the canvas doesn't quite fill the bounds of the parent div. It leaves a few pixels of missing height. So that if I resize the window such that the parent div is 522, the canvas' clientHeight will be 518 or something. In addition, as I resize the window's height, the canvas will grow in height monotonically.
I have many questions about this. 1) is assigning the parent div's clientHeight to the canvas' height property the right way to keep the canvas' height matching it? 2), can I size the canvas' element to its parent div with css width/height alone? 3) why does the canvas grow and grow when I resize the window? 4) why does the canvas' clientHeight not its height (although that is wrong too) wind up coming out slightly smaller than the parent div's clientHeight? the width's match fine?
Some extra information. If I replace the canvas with a div element, I don't see either of the problems I mentioned. The div now spans the exact height of its parent, and doesn't suffer from that infinite height growth issue. This leads me to believe that the sizing issues are related to the canvas' own functionalities like context/drawing size/height properties, etc..
I've run into this before. Try adding the following styles:
html, body { padding: 0; margin: 0; width: 100%; height: 100%; }
I think this has helped me before as well:
body { overflow: hidden; }
If those don't do the trick, there are all kinds of other weird things that can cause undesirable/unexplainable space, sometimes setting line-height: 0, font-size: 0 helps
I just remembered something else that might work without any of the above. Make your canvas { position: absolute; top: 0; left: 0 }

How to set side bar between two div and it should fit in the any browser window based on resize

I am having two grid one div is header another one is footer between the two grid, I am using sidebar in left side.
Here is my JavaScript code
function resize()
{
var heights = window.innerHeight;
document.getElementById("left").style.height = heights + "px";
}
resize();
window.onresize = function() {
resize();
};
I want to show this full content with in the page without show any browser scroll bar.
Here is my demo
Click here to see my demo
You can use pure CSS: there are a few ways to determine the behavior of CSS to adjust to screen size. I think that a good method for this is to use the viewport units: vw and vh, this will let you achieve responsive design easily...
vw stands for "viewport width" and vh is for "viewport height". and,
you can use it with CSS like in this example:
div {
width: 100vw;
height: 100vh;
}
This guide may be helpful to understand this method better...
You can also set px for pixels and other CSS sizing units instead of % and also use vmin and vmax for minimum and maximum size adjustment, or just use min-height/width like in this example:
.sidebar {
min-width: 30%;
min-height: 30%;
}
Another more modern way is to do it with flexbox...
Using Jquery:
You take the browser screen height
$(window).height()
& then reduce the height of header & footer
$(window).height() - $('header').outerHeight() - $('footer').outerHeight()
Using JS
window.innerWidth - document.getElementById('header').offsetHeight - document.getElementById('footer').offsetHeight;
Instead of offsetHeight you can also use clientHeight. Difference is:
clientHeight includes padding.
offsetHeight includes padding, scrollBar and borders.
Updated
Update your function resize() as:
document.getElementById('inner').style.maxHeight = window.innerWidth - document.getElementById('header').offsetHeight - document.getElementById('footer').offsetHeight;

change image manually as window sizes

I used js to set image width and height according to window size. But in some cases when the browser is very wide, the image's hight exceeds all its father element's height. As a result, the bottom part of the image is not shown. How can I solve this?
I used bootstrap and swiper in this project and the image I want to change is inside my swiper division. I set and all the image's father elements' height to 100%. Here is my js code to change is image dymanically. The image size is 2560*1440.
if(winWidth/winHeight < 2560/1440) {
imgHeight = winHeight;
imgWidth = winHeight/1440 * 2560;
}else {
imgWidth = winWidth;
imgHeight = winWidth/2560 * 1440;
}
attr = "width:" + imgWidth + 'px;height:' + imgHeight + 'px;margin-left: -' + imgWidth/2 + 'px;margin-top:-' + imgHeight/2 + 'px';
$('.main .swiper-slide > img').attr('style',attr);
PS:
Sorry I didn't make it clear. The following methods you provided scale the image down in vertical view and so leaves much blank in the page. Actually I want my image's height to occupy the whole window's height, no matter in vertical window or horizontal window. And if the window is wide enough, image's width equals the window's width, otherwise cut the image in width and make it equals the window's width too.
#patstuart is correct, this is much better handled directly through CSS. It's pretty amazing how many styling issues (go figure) can be solved without writing a single line of JavaScript. So to answer your second question, let's figure out how it can be done with CSS. Without seeing a fiddle or your actual page / image, I'll just shoot from the hip here. If I understand correctly, you want the full image to display at its correct ratio no matter what the width / height of the screen is. If that's the case, here's a nice little trick:
.main .swiper-slide {
width: 100%;
height: 0;
/* Padding bottom should be the height's ratio to the width.
Which in this case, would be 56.25% */
padding-bottom: 56.25%;
}
.main .swiper-slide > img {
width: 100%;
}
That is how aspect ratio can be handled with CSS. Let me know if that resolves your issue or if you have any other questions. CSS was made for styling so always look for a solution there first.

Canvas width and height calculation is off

I'm using some script I found on Git that generates a snow effect. Somewhere in the code I have to set the width and the height of the canvas in which the snow is generated. I'm setting the canvas to the window full width / height :
canvas.width = $(window).width();
canvas.height = $(window).height();
But when rendered in the browser there are on both height and width some extra pixels adding scrollbars to the window. You can see the behavior here : Canvas ; I'm not quite sure why the width / height is calculated wrong or if there's something else interfering with those calculations that it makes it bigger than the actual window width / height. Maybe someone has a different view of the behavior or encountered it before ?
The canvas element is displayed inline by default, you can read here about similar problem.
The solution is quite simple :) Add following css code to the canvas element:
display: block;
and scrollbars should disappear.
old answer:
$(window).width() works properly but i don't know why $(window).height() returns too large value. It cause also showing vertical scrollbar because earlier computed width don't include the size of horizontal scrollbar.

How do I get the new dimensions of an element *after* it resizes due to a screen orientation change?

I'm working on a mobile web app, and in my page I have a div element with its width set to 100%.
I need to set the height of this div so that the height is correct for a set aspect ratio. So for example, if the screen was sized to 300 pixels wide and the ratio was 3:2, my script should grab the width of the div (which at this point should be 300px) and set the height to 200px.
On first load, this works perfectly. However, if I rotate the screen of my phone to landscape, the width of the div obviously changes, so I need to reset its height in order to keep the correct ratio.
My problem is that I can't find an event which fires after the elements are resized. There is an orientationchange event built into jQuery Mobile, which helpfully fires when the screen is rotated from portrait to landscape and vice-versa:
$(window).bind('orientationchange', function (e) {
// Correctly alerts 'landscape' or 'portrait' when orientation is changed
alert(e.orientation);
// Set height of div
var div = $('#div');
var width = div.width();
// Shows the *old* width, i.e the div's width before the rotation
alert(width);
// Set the height of the div (wrongly, because width is incorrect at this stage)
div.css({ height: Math.ceil(width / ratio) });
});
But this event seems to fire before any of the elements in the page have resized to fit the new layout, which means (as mentioned in the comments) I can only get the pre-rotation width of the div, which is not what I need.
Does anyone know how I can get the div's new width, after things have resized themselves?
A few methods for you to try:
(1) Set a timeout inside your orientationchange event handler so the DOM can update itself and the browser can draw all the changes before you poll for the new dimension:
$(window).bind('orientationchange', function (e) {
setTimeout(function () {
// Get height of div
var div = $('#div'),
width = div.width();
// Set the height of the div
div.css({ height: Math.ceil(width / ratio) });
}, 500);
});
It won't make too big of a difference but note that Math.ceil takes a lot longer to complete (relatively) than Math.floor since the latter only has to drop everything after the decimal point. I generally just pass the browser the un-touched float number and let it round where it wants to.
(2) Use the window.resize event instead to see if that updated fast enough for you:
$(window).bind('resize', function (e) {
// Get height of div
var div = $('#div'),
width = div.width();
// Set the height of the div
div.css({ height: Math.ceil(width / ratio) });
});
On a mobile device this will fire when the orientation changes since the size of the browser view-port will also change.
(3) If you are updating the size of this <div> element because it holds an image, just apply some CSS to the image to make it always be full-width and the correct aspect ratio:
.my-image-class {
width : 100%;
height : auto;
}

Categories