Centre absolute elements

CSS can be frustrating at times when things don’t work as you expect (or as the specs say they should work) but usually with a little lateral thinking you can still achieve the desired result.

I’ve run into the following quirk a number of times now and previously have coded around it to avoid the bug but today decided to tackle and squash it. :smile:

The problem stems from a little known behaviour of absolute elements in that you can easily centre an absolute element that has a width defined without resolving to left:50% and negative margins of half the element’s width (which is a disastrous approach as the element slides out of the viewport at small screen sizes).

The secret is to use left:0 and right:0 plus a width plus margin:auto. That’s all you need and indeed will vertically align the element if you use top and bottom also.

Here is the minimum code:

.test{
	position:absolute;
	left:0;
	right:0;
	width:1000px;
	height:200px;
	background:red;
	margin:auto;	
}


<div class="test">testing</div>

That will work back to IE8 without problem.

Now to get to the point of my post you may instead not want a fixed width but a max-width instead (much more useful in a responsive layout). As you may expect you can simply substitute max-width for width and the element will still be centred and then collapse with the viewport nicely without causing a scrollbar. The problem arises that IE9, IE10 and IE11 don’t understand this and the element with max-width now sticks to the side of the viewport.

Oddly enough IE8 doesn’t have this problem and works fine. Therefore if we want to use this method we have to lose ie9,10 and 11 which may be too much to lose at this time. In the past I have merely adopted another more convoluted approach but have not been happy with it.

The solution it turns out is pretty simple and instead of a max-width we used the fixed width (1000px in my example) but then as the viewport gets down to 1000px we throw in a media query and set the element to auto width and thus effectively replicate max-width.

All good you may think but IE8 doesn’t understand media queries so is now stuck with a fixed width so we need to use a conditional comment for IE8 to remove the fixed width and fineally we have a working version from IE8 upwards plus all other modern browsers (afaik).

Here is a demo and the revised code:

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<style>

.test{
	position:absolute;
	left:0;
	right:0;
	width:1000px;
	max-width:1000px;
	height:200px;
	background:red;
	margin:auto;	
}
@media screen and (max-width:1000px){
	.test{width:auto}
}

</style>
<!--[if lt IE 9]>
<style>
.test{width:auto}
</style>
<![endif]-->
</head>

<body>
<div class="test">testing</div>
</body>
</html>

Hope you find it useful :smile:

3 Likes

interesting…as it is I’ve taken the above approach thinking it would be fine…yet to test in diff viewports

Since IE8 is the only one of those browsers that understands conditional comments isn’t simply having the conditional comment without specifically testing for less than 9 sufficient?

IE9 understands conditional comments and thus needs to be excluded from that extra rule also.:slight_smile:

I keep forgetting that IE9 understands conditional comments since the only place in JScript you’d need to conditional comments IE9 doesn’t understand the JScript version of the code and has to be given the JavaScript code instead.