Blog von Marc Hinse, Webdesigner und Webentwickler aus Karlsruhe.

made my day.every day.

Height equals width with pure CSS

I was looking for a solution for flexible elements which remain the aspect ratio when resized. Until now I used some Javascript for resizing the elements. But using the resize event and recalculate the height of an element is some kind of nasty and never felt right. Recently I found a solution in an article from A List Apart and a topic on StackOverflow, which works quite well.

Examples (resize your browser to see the remaining ratios)

Aspect ratio of 1:1
Aspect ratio of 2:1
Aspect ratio of 1:2
Aspect ratio of 4:3
Aspect ratio of 16:9

Single page demo

Description

If you have an image with a certain aspect ratio you can easily keep the proportion with the "auto" value. Like:

img{
	min-width: 100%;
	height: auto;
}

The problem is that you can't use the "auto" value for the height property of a block element like a DIV or alike. It will always resize depending on the inner content/elements.

The trick

I found a solution which was already posted four years ago on A List Apart. Also a kind of follow-up on Stack Overflow. This is so brilliant that I want to share the beauty (NERD!) of that solution with you:

HTML

<div class='box'> 
	<div class='content'>Aspect ratio of 1:1</div> 
</div>

We need two block elements to achieve the desired behaviour. No images, no Javascript.

CSS

.box{
	position: relative;
	width: 50%;		/* desired width */
}
.box:before{
	content: "";
	display: block;
	padding-top: 100%; 	/* initial ratio of 1:1*/
}

So, what's this? We define a pseudo element for our box and give it a margin-top of 100%. Since this 100% value relates to the element's width... you get it (height: 0; padding-bottom: 100%; would also work, but then you have to adjust the padding-bottom value every time you change the width).

So our box is already as high as wide. If you only want to display some colored tiles, you are already done. But since the user experience is way better if you also provide some content we add a content element to our box.

The content

And here is the trick: We just position the content element as absolute with all four orientations set to 0. This just covers the parent element completely, no matter which size it has.

.content{
	position:  absolute;
	top: 0;
	left: 0;
	bottom: 0;
	right: 0;
}

That's it. Brilliant, isn't it? Even a padding doesn't break it, no need for box-sizing: border-box here.

Other aspect ratios

If you want to create other ratios just change the padding-top value of the pseudo element (see example):

/* Other ratios */
.ratio2_1:before{
	padding-top: 50%;
}
.ratio1_2:before{
	padding-top: 200%;
}
.ratio4_3:before{
	padding-top: 75%;
}
.ratio16_9:before{
	padding-top: 56.25%;
}

IE7 and below

Since IE is IE and especially IE7 is everything but a browser, you have to create the pseudo element yourself in your markup if you like to support that shit. Or throw some Javascript on it until it hopefully breaks. Forever.

Nach oben