I want to create a div
that can change its width/height as the window's width changes.
Are there any CSS3 rules that would allow the height to change according to the width, while maintaining its aspect ratio?
I know I can do this via JavaScript, but I would prefer using only CSS.
This is an improvement on the accepted answer:
You can use the flux layout (FWD).
https://en.wikipedia.org/wiki/Adaptive_web_design
It will scale and maintain the layout, its a bit complex but allows for a page to resize without pushing the content like (RWD).
It looks like responsive but it is scaling. https://www.youtube.com/watch?v=xRcBMLI4jbg
You can find the CSS scaling formula here:
http://plugnedit.com/pnew/928-2/
Say that you to maintain Width: 100px and Height: 50px (i.e., 2:1) Just do this math:
I stumbled upon a smart solution using
<svg>
anddisplay:grid
.Grid element allows you to occupy the same space with two (or more) elements, without needing to specify which one sets the height. Which means that, out of the box, the taller one sets the ratio.
This means you can use it as is when you know the content will never be tall enough to fill the entire "ratio" and you're simply looking for a way to position the content in this space (i.e. to center it on both directions use
display:flex; align-items:center; justify-content:center
).It's pretty much the same as using a transparent
<img>
withdisplay:block
and predetermined ratio, except the<svg>
is lighter and considerably easier to modify (to change the ratio responsively, should you need to).All you need to do is change the
<svg>
s ratio:<svg viewBox="0 0 4 3"></svg>
<svg viewBox="0 0 16 9"></svg>
See it working:
If you need a solution where the content element is not allowed to set the ratio when it's taller (with overflow hidden or auto), you need to set
position:relative
on the grid andposition:absolute; height:100%; overflow-y: auto;
on the content. Example:While most answers are very cool, most of them require to have an image already sized correctly... Other solutions only work for a width and do not care of the height available, but sometimes you want to fit the content in a certain height too.
I've tried to couple them together to bring a fully portable and re-sizable solution... The trick is to use to auto scaling of an image but use an inline svg element instead of using a pre-rendered image or any form of second HTTP request...
Notice that I have used big values in the width and height attributes of the SVG, as it needs to be bigger than the maximum expected size as it can only shrink. The example makes the div's ratio 10:5
If you want to fit a square inside the viewport on either portrait or landscape view (as big as possible, but nothing sticking outside), switch between using
vw
/vh
on orientationportrait
/landscape
: