How to Center Anything With CSS

by on 6th March 2013 with 34 Comments

screenshot

Recently, we took a dive into the very core concepts behind CSS layout and explored the differences between absolute and relative positioning. We’re going to follow that up with another CSS layout talk, this time based around a fundamental question that almost every new developer asks: how do you center something?

There are a bunch of different types of web elements and layout situations, each calling for a unique solution for centering (both vertically and horizontally). Today we’ll go over a bunch of these scenarios so you can wrap your mind around how they work and come away with the confidence to center anything!

Who’s This For?

I’ve gotten a lot of commenter feedback lately from designers who struggle with the basic methods and concepts of layout in CSS. The general consensus among many of those new to CSS is that they simply “fiddle” with the code until everything finally works.

Having been there quite a few times myself, I know that this is an immensely frustrating period of your professional growth. Knowing that the answer is right there in front of you and not being able to figure it out is excruciating and time consuming.

If this sounds familiar, hopefully I can help ease you out of this period with some solid and practical advice for how to handle some common layout scenarios. If you’re a CSS ninja who can code a website blindfolded, this article probably isn’t for you. If you’re a designer who just wants a better understanding of how to take what’s in your Photoshop file and turn it into CSS, you’re in the right place. Let’s get started.

Horizontally Center an Element

The first scenario that we’ll attack is by far one of the most common: centering an element horizontally in the viewport or browser window. To get started, let’s bust out a simple div and give it some basic styling.

screenshot

As you can see, by default, our div pops up in the top left of the viewport. The trick here is that we need the div to stay in the center of the window, no matter what the window’s size is currently. That means that we can’t use absolute positioning to place it at a specific point because that won’t be centered on any other possible window sizes.

Instead what we need to do is leverage the “auto” value that can be applied to margins. Here’s how this works:

screenshot

As you can see, applying a single line of CSS tossed our box straight to the center of its parent, which in this case is the body. To accomplish this, I used a bit of CSS shorthand. If you need a refresher, margin shorthand starts at the top and works its way around clockwise.

screenshot

You can shorten this even further if you only have two values that you need assigned. In this case, the first slot will apply to the top and bottom margins while the second slot will apply to the left and right margins. Here’s another look at our centered div, this time with the margins declared using three separate but perfectly equivalent methods.

screenshot

As you can see, our element is void of top and bottom margins, but the left and right are set to auto, which keeps the item perfectly centered.

Things To Keep In Mind

There are some important things to remember about using the auto margins trick. First of all, you must have a specific width declared for the element that you’re centering. The height declaration is not necessary, you can allow the content to determine the height if you wish, which is the default setting, but the width must always be set.

It’s important to note that while this trick will work on most block level elements, not just divs, it won’t help you out with vertical centering. As an example, let’s throw a paragraph inside of a div, then attempt to center that paragraph in the space.

div {
  height: 400px;
  width: 400px;
  background: #eee;
  margin: auto;
}

p {
  width: 60%;
  margin: auto;
  font: 14px/1.5 Helvetica, sans-serif;
}

screenshot

As you can see, I have auto margins set both on the paragraph and its parent div. This centered everything nicely horizontally, but it didn’t have any effect on the vertical position.

Center An Absolutely Positioned Element

The method above works to automatically center one item inside another, but the method assumes that you’re using the default positioning context: static. If you have absolute positioning applied, this method goes out the window.

Using the absolute and relative positioning methods we learned last week, we can apply a simply formula to solve this issue.

screenshot

Here we see that on an absolutely positioned item contained inside of a relatively positioned item, we need to set the left property by plugging some numbers into this formula. Here’s a test case:

.container {
  height: 300px;
  width: 300px;
  background: #eee;
  margin: 10px auto;
  position: relative;
}

.box {
  height: 100px;
  width: 100px;
  background: #222;
  position: absolute;
}

screenshot

Let’s see if we can center the black box horizontally. Using our formula, we can see that the left property needs to be set to 100px.

screenshot
.container {
  height: 300px;
  width: 300px;
  background: #eee;
  margin: 10px auto;
  position: relative;
}

.box {
  height: 100px;
  width: 100px;
  background: #222;
  position: absolute;
  left: 100px;
}

With this code, we’ve set the distance between the left side of the box and the edge of its parent container to 100px, which centers it perfectly.

screenshot
screenshot

With Fluid Width

The method above only works if the parent container has a static width. Given the popularity of responsive design though, more and more containers are going the fluid route lately. This means that we’ll need another way to center the child that isn’t dependent on the width of the parent.

To accomplish this, we need to use a percentage for the left value. The obvious answer is to use 50%, but that won’t really work because you’re not accounting for the width of the element that you’re centering. To make it work, we need to add in a negative left margin of half the width of the child element.

screenshot

Using this logic, we apply a left margin of negative fifty pixels along with a left value of 50% and our div is once again perfectly centered on the x-axis.

.container {
  height: 300px;
  width: 70%;
  background: #eee;
  margin: 10px auto;
  position: relative;
}

.box {
  height: 100px;
  width: 100px;
  background: #222;
  position: absolute;
  
  /*Centering Method 2*/
  margin: 0px 0 0 -50px;
  left: 50%;
}

screenshot

It’s important to note that this would also work if our child element had a fluid width. We use the same steps as before and come up with something like the following:

.container {
  height: 300px;
  width: 70%;
  background: #eee;
  margin: 10px auto;
  position: relative;
}

.box {
  height: 100px;
  width: 70%;
  background: #222;
  position: absolute;
  
  /*Centering Method 2*/
  margin: 0px 0 0 -35%; /* Half of 70% /*
  left: 50%;
}

screenshot

Dead Center an Element

Now that we have a few simple and complicated centering methods in our tool belt, it’s time to tackle the puzzle of perfectly centering an element both horizontally and vertically.

Fortunately, to pull this off, we can use the same method that we just learned, we just have to account for height. This time around we’re also going to center both the parent and the child both vertically and horizontally. Here’s the code to pull it off:

.container {
  height: 300px;
  width: 300px;
  background: #eee;
  position: absolute;
  
  margin: -150px 0 0 -150px;
  left: 50%;
  top: 50%;
}

.box {
  height: 100px;
  width: 100px;
  background: #222;
  position: absolute;
  
  /*Centering Method 2*/
  margin: -50px 0 0 -50px;
  left: 50%;
  top: 50%;
}

screenshot

There are a few things that you need to notice here. First, this time both the parent and the child are absolutely positioned. From here, I used our negative margins trick with the left property on the container div, then did the same for the box div.

The result is that our content is completely centered and will stay that way as the browser changes size in any direction (even vertically!). Click on the image below to tinker with a live demo.

screenshot

Centering Text

For my next trick, I’ll teach you something cool about centering text. We’ll start with a simple h1 element inside of a container div.

screenshot

Now, I’m sure that you already know how to center this text horizontally in the space. It’s typically one of the first things you learn in CSS. Just set the text-align property to center.

.container {
  height: 400px;
  width: 400px;
  background: #eee;
  margin: 50px auto;
}

h1 {
  font: 40px/1 Helvetica, sans-serif;
  text-align: center;
}

screenshot

Easy right? But now let’s say we want to center this line of text vertically as well. If this were a paragraph, we would probably take the methods above into account, but since it’s only a single line, we can use a nifty trick.

All we have to do is set the line-height property to the height of the container. I accomplished this below using the shorthand font syntax.

.container {
  height: 200px; /*Set line-height to this value*/
  width: 400px;
  background: #eee;
  margin: 150px auto;
}

h1 {
  font: 40px/200px Helvetica, sans-serif;
  text-align: center;
}

screenshot

Warning: This trick only works with a single line of text, and is a bit hacky so it may not be appropriate for all situations.

Centering a Background Image

The last thing that we’re going to learn to center is a CSS background image. To get started with this, we’ll create another container div, but this time we’ll keep in empty and toss in an image using CSS.

.container {
  height: 300px;
  width: 300px;
  margin: 150px auto;
  background: #eee url(http://lorempixum.com/100/100/nature/4) no-repeat;
}

As you can see, the default place for an image to appear if no repeat is set is the top left. It turns out though that you can move it to one of nine different preassigned slots. These are shown below:

screenshot
screenshot

We accomplish this movement through the use of the background-position property. Simply call this property and set any of the values listed above.

.container {
  height: 300px;
  width: 300px;
  margin: 150px auto;
  background: #eee url(http://lorempixum.com/100/100/nature/4) no-repeat;
  background-position: top center;
}

screenshot

As an alternative, we can use the shorthand syntax for this. Simply toss in one of the values at the end of your stream of values on the background property.

.container {
  height: 300px;
  width: 300px;
  margin: 150px auto;
  background: #eee url(http://lorempixum.com/100/100/nature/4) no-repeat center;
}

screenshot

Conclusion

There you have it! You should now be completely confident in your ability to tackle almost any centering situation with CSS, from dead centering a div to vertically centering a line of text within its container and beyond.

Reach out to us on Facebook or Twitter and let us know if you found this information to be helpful and if you have any questions.

Comments & Discussion

34 Comments

Comments & Discussion

34 Comments

  1. Yo Yehudi says:

    As is only kinda-addressed, entering text vertically with line-height can look entirely wonky if there’s more than one line of text…. enough that it’s worth a clear warning and demo of why NOT to bother doing it maybe?

  2. kingabel says:

    thanks for this wonderful post

  3. Gunisigi Balaban says:

    what about vertical centering an element with an unknown/dynamic height?

  4. I read this trick some where making parent object as “display: table” and then child object as “table: cell; vertical-align: middle;”

    Correct me if am wrong.

  5. Priit says:

    You just need this, it’s that simple, no need to know widths, heights, nothing:
    #center {
    position: absolute;
    top:0;
    left:0;
    right:0;
    bottom:0;
    margin: auto;
    }

  6. Thank you for this very good post ;)

  7. elgallorojo says:

    It’s great that the simple “center” tag has been made obsolete. One wouldn’t have the privilege of thinking complexly the way that the CSS arbiters have decreed everyone must think. Seriously, millions of non-full time web designers should be extremely grateful to be rid of the way-too-simple “center” tag.

  8. Jason Gross says:

    @Gunisigi Balaban and @Priit

    Sometimes the absolute positioning method doesn’t work well in the context of an actual HTML document where you want to center an element but respect the document flow of other objects outside of the parent you are working with.

    If that is the case (and it often is) check out the writeup that Chris Coyier put together, it makes a good compliment to these techniques and can be applied to an element of unknown height and width: http://css-tricks.com/centering-in-the-unknown/

  9. Complete info on centering things using CSS. Awesome article and its really worth sharing…

  10. Stefan says:

    Simple but important CSS Basics….thank you for this Summary

  11. Nimsrules says:

    Saved and bookmared. I’ve always had trouble in centering elements vertically. Thanks for clearing out my basic concepts.

  12. Great post, thanks for the thorough explanation.

  13. Riesen Dan says:

    Thanks for that wunderful article. Works fine in allmost all browsers!

  14. Bhuvanesh says:

    Cool article,and marvelous explanation !!

  15. Luis Paulo Lohmann says:

    @Waheed, “display: table” is not crossbrowser safe.

    @elgallorojo, sir, you simply didn’t understand yet the concept of CSS, or “to separate content from layout”.

  16. Adam says:

    how are you using to complete this task?

  17. Adam says:

    what are you using (program wise) to complete this task?

  18. bofaX4 says:

    Thank you. The responsively centred absolutely positioned div had me stumped. You really helped me out here! Lots of other great methods and applications here too. Awesome!

  19. GreLI says:

    “margin:0 auto” is dumb. Just write “margin:auto” unless you need non-zero top and bottom values.

    If you read the specification you’d know that “margin-top:auto” and “margin-bottom:auto” always computes to zero for non absolute positioned elements.

  20. Clain Dsilva says:

    Wonderful info… this really opened my eyes to the power of CSS margin property. I otherwise used it only for putting margins.

  21. Nico says:

    Did you test negative margin on iPad ? I had several rendering bugs with it. ;)

  22. _kud says:

    And what about inline-block method?

    http://jsfiddle.net/Wfrjt/

  23. Simon says:

    And the perfect way, completely crossbrowser:

    http://jsfiddle.net/mBBJM/1/

    Just position absolute and let the browser fix it or you.

  24. Joe says:

    Nice article! In the future please only use the variables x and y to mean the spatial coordinates if you are talking about something spatial. Using them to mean two different widths is very confusing IMHO… Thanks

  25. Varemenos says:

    change the title to “How to horizontally center Anything with CSS”…

  26. cahnory says:

    And to center any content, of any (unknown) size, horizontally and vertically, I came with this solution :

    http://cahnory.tumblr.com/post/16988618236/centrage-vertical-et-horizontal-delements-de-taille
    (dabblet demos don’t work anymore but here is a live exemple : http://cahnory.fr/css/xy-align.html)

  27. elisa says:

    gud for basic :)

  28. Ricardo says:

    That was a great read! I knew most of it but never knew about how to do it when its absolute. Thanks!

  29. canciller says:

    fantastic article, and comments.

    thanks to all.

  30. Mickey Mouse says:

    Haha, yeah… everyone knows this.
    Centering unknown sized elements is what’s tricky.

  31. Kevin says:

    Great post, I have added this to my Evernote folder for future reference.

  32. Tri Nugraha says:

    Very well described. Thank you :)

  33. AntoxaGray says:

    I have a better trick: use display:box instead of position:absolute.

    It allows to «truly» center object, without need to manually setting coordinates, also not using position:absolute (so it’s not torn out of page flow)

    It is natively supported by most modern browsers *cough*Opera*cough*, and there is jQuery script that make it work even in IE6(!).

    Google for flexieJS (links are not allowed here?).

Leave a Comment

Subscribe
Membership
About the Author