Resize a Div Based on Height but Retain Aspect Ratio (almost got it) Strange Reload bug
Asked Answered
P

1

7

There are lots of solutions for maintaining aspect ratio when resizing videos based on the width of the parent div. Most of them depend on the fact that "padding-top" and "padding-bottom" are calculated based on width rather than height.

I'm trying to do something similar, but I want to resize my video based on the height of the parent div.

To do this I need to create a div that keeps an aspect ratio regardless of height. This may be sort of a lame way to do it, but I decided to use an image to do this because I can set the height of the image with the appropriate aspect ratio to 100% and let the height sort itself out.

I am very close to making this work. As of now, I have been able to make the inner div do exactly what I want it to do, except that it will not redraw on window resize. However, if I resize the window then reload, it works. Any ideas?

Here's the demo (it's not a codepen issue I've done it locally as well)

Psychosurgery answered 31/7, 2013 at 19:5 Comment(0)
R
4

Good thought using an image and height: 100%. That definitely will get the box to the same aspect ratio as the image, but doesn't reflow the box on window resize for whatever reason.

Here's a demo with slightly cleaner CSS and the Javascript hack to fix the reflowing on window resize.

In the demo, I use a 16px by 9px data uri image to set the aspect ratio, preventing a needless HTTP request. If you need a different ratio image, use this site to convert your image to a data uri: http://dataurl.net/#dataurlmaker

I managed to solve the reflowing issue with very basic jQuery. On $(window).resize(), I toggle a class on the body that makes the ratio images go from text-align: left to text-align: justify which tricks the browser into reflowing the box.


Browser Support

Works in Chrome, Safari, Mobile Safari, Firefox, and IE9+. The resizing is quite smooth overall, but Safari stutters a bit.

IE6/7 don't support display: inline-block so the box is 100% width and the correct height. (not a bad fallback!)

IE8 sizes the box's height correctly, but the width is only as wide as the original image (16px). The only way I found around this is using the HTML5Boilerplate style IE conditional tags to just set the embed parent to display: block like in this demo


CSS Only

If you have to have a CSS only solution, setting an animation on the ratio image to toggle a small amount of padding works in Chrome, Safari and Firefox. However, this is continually forcing the browser to re-render the page layout, which is grossly inefficient compared to only rendering the page layout on window resize.

.Ratio { animation: myfirst 1s infinite; }
@keyframes myfirst {
    from { padding-top: 1px; }
    to { padding-bottom: 1px; }
}

Hope that helps!

Rematch answered 8/10, 2013 at 17:31 Comment(4)
This solution works well except in Firefox since FF measures the "natural" size of the base64 encoded image instead of the scaled size. This causes the video in your example to render at 16x9 pixels. I suppose you would work around this by using a larger base64 encoded image and scale it down. BTW I tested using FF 35.0.1.Unspent
If you’re only targeting browsers which support SVG, you can use <svg viewBox="0 0 16 9" version="1.1" class="ratio"></svg> instead of the PNG.Adolescence
@Adolescence I actually have a whole blog post on this idea! codepen.io/shshaw/post/responsive-placeholder-image You should be able to drop the version="1.1" for an even smaller snippet, and if you need an actual <img> element, you can convert the SVG to a data-uri like described in my blog post.Rematch
@Adolescence I should also mention that IE9-11 has issues scaling SVG up & down unless you give them width & height attributes and some styles: codepen.io/tomByrer/pen/qEBbzw?editors=110Rematch

© 2022 - 2024 — McMap. All rights reserved.