Grow your CSS skills. Land your dream job.

Centering Percentage Width/Height Elements

Published by Chris Coyier

If you know the exact width/height of an element, you can center it smack dab in the middle of its parent element easily with this classic trick: top and left set to 50% and negative margins half the width and height of the element. That's great if you know the width and height of the element you're trying to center, but what if they are percentages?

You'd think you could just use negative percentage margins. That works for horizontal margins, but margins are based on width (even vertical margins) so it breaks down when you try to use negative top margin to pull things into place.

There is a little trick involving a "ghost" pseudo element and inline-block/vertical-align that is pretty darn clever. But that requires the element you are centering to be inline-block and that's not a real common scenario. More likely you're trying to center something like a modal window right in the center. And with small screens / responsive design being big business, it's highly likely you'll want your dialog box to be of percentage width (or otherwise unknown like have just a max-width).

There is a way! I saw this trick used by Mary Lou over at Codrops and her article/demo Nifty Modal Window Effects.

Instead of using negative margins, you use negative translate() transforms.

.center {
  position: absolute;
  left: 50%;
  top: 50%;
  
  /*
  Nope =(
  margin-left: -25%;
  margin-top: -25%;
  */

  /* 
  Yep!
  */
  transform: translate(-50%, -50%);
  
  /*
  Not even necessary really. 
  e.g. Height could be left out!
  */
  width: 40%;
  height: 50%;
}

Use whatever prefixes you need these days.

There we are then:

Check out this Pen!

Comments

  1. Francesco Belladonna

    Nice trick, this will be helpful, I always have “issues” with which approach should I use for vertical centering.

  2. pwerui

    Moore usefull for real vertical align.

  3. Decent support, needs testing when using, but definitely nice!

    If you’re wondering – http://caniuse.com/transforms3d

  4. This is really awesome! Great solution! Thanks for sharing!

  5. That’s a very nice trick!

  6. arnold

    speaking of codrops, that site is cool , lots of nifty UI demo , at some point it just sucks IE still left behind in CSS3

  7. Ben

    You can also use a combo of right+left or top+bottom to centre an absolute percentage-defined element without the transform:

    This is slightly different in the way it’s measured, but it ends up the same as your example would be if border-box were applied.

    • Yes to this solution. I was going to post this, but I saw someone else beat me to it. For those too lazy to jump to the codepen:

      position:absolute;
      left: 30%;
      right:30%;
      top: 25%;
      bottom:25%;
      

      Width and height independent, fully scalable, perfectly centered.

    • That was is awesome too, probably with a bit higher support. But note that implying right and bottom along with top and left implies a width and height even though you don’t use width and height.

      The transform method (despite the example in the article and title of article) works without needing to know the width/height.

      Here’s with totally expandable both width and height: http://codepen.io/chriscoyier/pen/Lgaij (try clicking in an editing the text).

    • Did someone tryied to open this on iPad?? Something weird happens and the container fall down the screen!

  8. Andrea

    It would be nice if we could find a similar approach for non fixed width/height elements.

  9. MaxArt

    That’s new to me!
    You can apply that to not only percentage-sized elements, but to elements with automatic width and height! That’s really good!

    To bad you have to drop IE8 support…

  10. Terrible support for IE. What a shocker… :)

  11. VERY sweet. This also works for auto height and width.

  12. Not bad, not bad.

  13. I prefer the “TRBL” method:

    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left:  0;
    margin: auto;
    width: 40%;
    height: 50%;
    

    I use it all the time and works down to IE8.

    • ChrisB

      That’s also quite nice, didn‘t know about this one.

      (But I suppose it only works if width and height are explicitly given, and not for auto?)

    • @ChrisB

      This method does not need an explicit width and height set at all. You can do

      position:absolute;
      left: 30%;
      right:30%;
      top: 25%;
      bottom:25%;
      

      And it will work just fine. See this pen that Ben posted a few comments up.

    • I think the big difference between the 2 solutions here lies in the layout of the content box. Check the background color of the box with the transform 2D approach and no width/height. It is not painted as big as with the TRBL technique (which, btw, should work in IE7 too).

  14. It is also possible to vertically center an element even without knowing its dimensions with a combination of line-height, display inline-block and the new vh css unit: http://codepen.io/anon/full/mkFDK

    (won’t work in IE, unfortunately)

  15. omg this is rad… it even seems to work with height:auto

  16. Jonathan Weavers

    Hey Cris -

    Your last post [Centering Percentage Width/Height Elements] was freaking awesome. I have gone ahead and added your stuff to my Feedly account. Please keep me updated if you post anywhere else.

    Keep rocking –

    Jon

  17. Fizer

    Very Nice. Why it does not work in jsfiddle

    http://jsfiddle.net/fizerkhan/BFqA2/

  18. Matt

    Nice trick ; however, I encountered some problems while testing it. Indeed, it seems that there’s a problem on Chrome with transforms and borders. Depending on the parity of the width/height.

    If one of the dimensions is odd, then its 50% value is not an integer and the border is blurred in some cases, or have an offset in others.

    Here’s a fork of your pen that illustrates the problem. Try playing with the size of the window to see the offset appear in Chrome.

    • ElijahFowler
      Permalink to comment#

      Matt, while that is an odd problem, you can fix it by adding background-clip: padding-box. Here’s my fork of yours.

  19. Darwin Mateos

    Nice tip, very useful.

  20. Thank you! Thank you! Thank you! This is exactly what I have been trying to achieve for the last week with not one, but two projects. As noted above, it even works with height:auto, so I no longer have to distort the image.

  21. Elena Vázquez

    Great solution, thanks! :)

  22. Jacques

    Pushing Ben’s technique above to include overflowing content:

    http://codepen.io/jacmaes/full/EFLjG

  23. Thank you Chirs, for telling me another CSS trick, previously I was using relative postion to center my absolute div

    
        .s3-relative{
            position:relative;
            width:100%;
            height:100%;
        }
        .s3-absolute{
            position:absolute;
            top:0;
            right:0;
            bottom:0;
            left:0;
            width:50%;
            height:50%;
            margin:auto;
        }
    
    

    Please suggest which one is more better

  24. Awesome…Thanks for sharing this handy tip…

  25. Ludwig

    That`s why I love to read this blog!! Great CSS-Trick

  26. We can use this for vertical center and horizontal center.

    .center{
    width:500px;
    height:500px;
    display:table-cell;
    vertical-align:middle;
    text-align:center;
    }

  27. Actually, if you do have width and height of the element, the easiest way is to use negative margins, like this:<br/>

    .center {<br/>
    width: 300px;<br/>
    height: 300px;<br/>
    top: 50%;<br/>
    left: 50%;
    margin-left: -150px;<br/>
    margin-top: -150px;<br/>
    }

  28. I FOUND this article very nice

  29. If you positively must at all costs support legacy browsers, shall we not forget the Javascript solution (using jQuery):

    <style>
     .center {
      position: absolute;
      top: 50%;
      left: 50%;
    }
    </style>
    
    <script>
    $(function(){
      $center = $('.center');
      $center.css({
        margin-left: '-' + Math.round( $center.width() / 2 ),
        margin-top: '-' + Math.round( $center.height() / 2 )
      });
    });
    </script>
    

    Demo

    • Using jQuery for such things is just a huge overkill… :(

    • For this to work, I needed to add + ‘px’ to both of the margins.

      @LorDex Since I am using jQuery all over my project, I don’t think it is overkill at all.

  30. helpful in responsive websites.

  31. I totally ran into this last week with the Nifty Modals (http://tympanus.net/Development/ModalWindowEffects/)! I thought it was really cool, but a negative side effect is that we noted in some browsers (Firefox did this the most), it uses some smoothing to do this transform, and if you have something complex in the modal (in our case, an ExtJS grid and some other components) it causes all kinds of weird issues with the scrollbar and causes a strange anti-aliased look on everything. I ended up having to use the negative margin trick instead to make it work.

  32. Caleb

    Cool. This also helped me center a width: auto element between a fixed width and another with: auto element.

  33. Dan

    Using display: block and margin: 0 auto often works nicely too.

  34. Roma Serebryakov

    I have been looking for the vertical align for responsive Div or Images for few days now, that would aslo work in IE browsers. Finally, I just experimented on my own and came up with this, that seems to work the best so far, with no additional hacks using CSS3 :after or translate() properties… Let me know if it works for you, too, pretty straight forward:

    The margin of the div becomes it’s vertical centering agent, so to speak.

  35. I’ve bin waiting for that one for a long time…

    Can’t wait to try it!

    Tx.

  36. Shrikant
    Permalink to comment#

    Nice Trick, it’s help full for me.

  37. What about using flexbox?

    (This assuming the item being centered is the only thing in the document, else html could be .container or whatnot.)

    html{
      display: box;
      box-orient: vertical;
      box-pack: center;
      box-align: center;
    }
    
    .item-to-be-centered{
      display:block;
    }
    

    Obviously, with prefixes like -webkit-box, etc…

  38. Great trick – having issues on Safari however. Will try some of the fixes listed in the comments. Thanks for sharing!

  39. Blake
    Permalink to comment#

    This is probably the best CSS only method for centering an element of unknown height vertically. Nice trick. In Chrome I’m seeing some font rendering issues. Maybe what @Nathan St. Pierre was talking about. Apparently Chrome’s making the text content of the element with transform: translate(-50%,-50%). I looked at it on an iPhone 5 and the text is sharp.
    The remaining issue I have is when the element being centered vertically with this method is taller than the window, like when viewed in landscape orientation on a phone, the top of the element is off screen. So I’m still using a method like @Yotam mentioned to center vertically only if the window height is greater than the element height.

  40. Blake
    Permalink to comment#

    I meant to say Chrome’s making the text content of the element with transform: translate(-50%,-50%) blurry. Seems like a weird bug. Haven’t seen this before.

  41. 0leg
    Permalink to comment#

    This drives me nuts:
    This is codepen from this article with reduced styling: Screenshot 1.
    And this is the same code brought to my codepen, saved (using firefox), and then opened in chrome: Screenshot 2.
    The same exact thing happens to my modal on my site…
    As you can see, the code is the same in both examples. Why????!!!

  42. With this solution, the centered div looks very blurry in Google Chrome 31.

    Some mobile browsers (Android 2.x) are not able to use translate() with values in percent.

  43. So this works great except in the scenario where you have an image, set it to 100% height (which causes the width to be wider than 100% of the container). Any ideas on how to center an img that ends up being > 100%?

    CSS:

    .mobile-screen-viewport {
      position: relative;
      width: 320px;
      height: 548px;
      background-color: red;
    }
    
    #image1 {
      height: 100%;
      position: absolute;
      top: 0px;
      left: 50%;
      -webkit-transform: translate(-50%, 0);
    }
    

    Here’s a code pen: http://codepen.io/napawapa/pen/soeGz with my example with image in place.

  44. Permalink to comment#

    oh my god you are a BIG hero for me ! this is SO CLEVER!

  45. Sean
    Permalink to comment#

    Great fix, thank you!

    I couldn’t get some text to center on top of an image while using skelton.css. The responsive design meant you had to have all the boxes be the same size or individually fix to center based on the column amount. This was much easier, would recommend for responsive sites.

Leave a Comment

Current day month ye@r *

*May or may not contain any actual "CSS" or "Tricks".