CSS: centering an elemenent vertically and horizontally

I had already written an article about this quite some time ago. The problem with this approach is that it only works with elements having a fix size. So I’ve written an article specific to the horizontal centering of variable width DIVs last year. The problem with this approach is that although it works I have no clue why and feel it might break some time in the future. Also this approach only works for centering horizontally. Luckily, since then, I’ve able to use another approach which seems cleaner and also doesn’t require my components to have a fix size and works both vertically and horizontally, without using any strange hacks.

First let’s start with a non-centered element:

<html>
	<body>
		<div style="background-color:green;width:35%;height:35%">
	</body>
</html>

It’s green and it has a height and width of 35% (so no fixed size). As expected, it’s displayed in the upper left corner:

not centered

Obviously, the first thing you’d try and is giving it a top and left margin of 50% to center it:

<html>
	<head>
		<style>
		.centered {
			margin-left: 50%;
			margin-top: 50%;
		}
		</style>
	</head>
	<body>
		<div class="centered" style="background-color:green;width:35%;height:35%">
	</body>
</html>

Unfortunately, this will move the element past the center. You’ll also notice that it’s off by a lot vertically but less horizontally:

margins 50 percent

This is because margin-top doesn’t use the height of the container to compute percentages to pixels but just like margin-left, it uses the width. So if your container is square, you won’t see a difference but otherwise, it’s a problem. So using margin-top is no option. Instead, we’ll set the position to relative and set top to 50%. Ok, we’d implement it without hacks but this one not really a bad one…

<html>
	<head>
		<style>
		.centered {
			margin-left: 50%;
			top: 50%;
			position: relative;
		}
		</style>
	</head>
	<body>
		<div class="centered" style="background-color:green;width:35%;height:35%">
	</body>
</html>

This now looks better but it’s still not properly centered:

better 50 percent

As you can probably guess now, the problem is that the upper left corner of the element is centered both vertically and horizontally. Not the center of the element. In order to correct this, we need some CSS properties which unlike the margin-xxx or top do not take into account the dimensions of the container but the dimensions of the element. Actually there aren’t so many properties like this. Luckily CSS transformations do work with the dimensions of the element. So a translation of -50% both vertically and horizontally will center the element:

<html>
	<head>
		<style>
		.centered {
			margin-left: 50%;
			top: 50%;
			position: relative;
			-webkit-transform: translate(-50%, -50%);
			-moz-transform: translate(-50%, -50%);
			-o-transform: translate(-50%, -50%);
			-ms-transform: translate(-50%, -50%);
			transform: translate(-50%, -50%);
		}
		</style>
	</head>
	<body>
		<div class="centered" style="background-color:green;width:35%;height:35%">
	</body>
</html>

Now it looks exactly the way it’s supposed to:

centered