full-width, centered content, 1 element

on
October 25, 2011

Earlier this week I started reworking the html/css of my blog. Only two tags far in this endeavor I already got stuck. Creating a full-width visual row with centered content (to see what I mean, check my header) using only one structural element wasn't as easy as I had imagined. So I strolled the internet for solutions, what follows is a small summary of tips and tricks to accomplish this particular visual effect.

1. using two structural elements

.parent {background:();} .parent .child {width:(); margin:0 auto;}

The easy way is to use two structural elements instead of one. The parent will function as a wrapper for the background, the child will be used for horizontal centering using margins and for defining the width of the centered element. Of course it would be much easier if we could center the containing content, but sadly that is not possible yet (unless I missed something vital of course).

This works fine in most cases, but if your code should be flexible enough to allow for visual rows within the page content, things will get a little tricky. Once a container is centered using margins, its children won't be able to break out easily, especially not if they'll need to span the entire width of the browser canvas. On top of that, I wasn't very happy with using two structural elements for such a minor visual detail. So let's ditch this method and look for something smarter.

2. using ::before and ::after

body {overflow:hidden;} .element {position:relative; width:(); margin:0 auto; background:();} /* pseudo-elements */ .element::before {content:" "; position:absolute; right:100%; width:999em; top:0; bottom:0; background:(); z-index:-1} .element::after{content:" "; position:absolute; left:100%; width:999em; top:0; bottom:0; background:(); z-index:-1}

If you lack structural elements, the popular way these days is to abuse your pseudo-elements. And sure enough, with the code above you'll get the intended effect.

The trick is to give the pseudo-elements a large width, pull them on either side of your centered element (using left/right:100%) and cut the remaining parts off using an overflow:hidden on the body (if not, you'll get scrollbars). Mind that the z-index of the pseudo-elements should be set to -1 so they don't overlap the content of your element. Even though they are positioned to the left and right, they might still overlap any drop shadows or other parts sticking out from your content.

The problem with this method is that you'll need to fake the background using three elements. If you want to add an inner shadow to your visual row, you might hit a wall once again. Visual requirements may differ though, and if you need to have different colors for left/right flaps or you need transparency in your centered area then this is definitely the way to go.

On a side note, if you want ie8 to play along, make sure to use the :before and :after syntax, rather than ::before and ::after.

3. using only ::before

body {overflow:hidden;} .element {position:relative; width:(); margin:0 auto; background:();} /* pseudo-element */ .element::before {content:" "; position:absolute; left:-500em; width:999em; top:0; bottom:0; background:(); z-index:-1}

This third and last method uses only one pseudo-element and removes the need for multiple background declarations to fake one single background. Just pull your pseudo-element to the left using a big (negative) left value and make sure it is wide enough as to span the entire browser canvas. It's not a very pretty fix, but it does the trick.

If you want an ie7 fallback, you can always insert one extra structural elements using javascript, applying the same css as used for the pseudo-element in this example. I haven't checked ie6 myself, but when ie6 compatibility is required I assume you might be better off using the second method (inserting two structural elements using javascript), I figure it's quite plausible ie6 won't be liking that negative z-index.

conclusion

Mind that the solutions listed above are not necessarily my own. I remember reading about this some time ago but could not relocate the article, so I'm not sure if it differs much from what was written there (I just remember the pseudo-elements trick).

Even though the above methods work pretty well, they are still hacks (or at least crappy solution to a rather simple problem). It would be a lot nicer if we could leave these pseudo-elements for their intended purpose and simply size and position the inner content of an element using css, but I still haven't found a decent solution to do this.

For now though, the solutions above will be able to help you out where needed and will offer enough flexibility to encounter most common issues.