Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do Vertical+Horizontal centering in CSS

Tags:

css

It regularly occurs that I want to center a css box inside another one both vertically and horizontally. What's the simplest way to do so that satisfies the following constraints?

  • The box should be precisely centered, not approximately.
  • The technique should work in modern browsers and in IE versions back to 8
  • The technique should not depend on explicitly knowing the width or height of either the centered content or the containing box.
  • I generally know the container is larger than the content, but supporting larger content (which then overflows symmetrically) would be nice...
  • The underlying content of the container must still be able to respond to clicks and hovers except where obscured by the centered content

I currently use 4 (!) nested divs to achieve this, with css along the following lines:

.centering-1 {
    position:absolute;
    top:0; left:0; right:0; bottom:0;
    text-align:center;
    visibility:hidden;
}
.centering-2 { 
    height:100%; 
    display:inline-table; 
}
.centering-3 { 
    display:table-cell; 
    vertical-align:middle; 
}
.centering-content { 
    visibility:visible; 
}

You can see this in action as a jsbin snippet. However, this approach, while workable, feels like extreme overkill due to the large number of wrapper divs, and it doesn't work with content that's larger than the container. How can I center things in CSS?

like image 649
Eamon Nerbonne Avatar asked Jun 28 '13 15:06

Eamon Nerbonne


People also ask

How do you center text vertically and horizontally?

Select the text that you want to center. in the Page Setup group, and then click the Layout tab. In the Vertical alignment box, click Center. In the Apply to box, click Selected text, and then click OK.

How do you center an element horizontally in CSS?

Like last time, you must know the width and height of the element you want to center. Set the position property of the parent element to relative . Then set the child's position property to absolute , top to 50% , and left to 50% . This just centers the top left corner of the child element vertically and horizontally.


2 Answers

Horizontal centering is easy:

.inner {
  width: 70%; /* Anything less than 100% */
  margin-left: auto;
  margin-right: auto;
}

But vertical centering is a little tricky. The best technique for modern browsers is to combine inline-block and a pseudo elements. This originates from "Ghost element", the last technique at http://css-tricks.com/centering-in-the-unknown/. It sets adds a pseudo-element and uses inline-block styles get the centering. The CSS:

.outer { 
  height: 10rem; 
  text-align: center; 
  outline: dotted black 1px; 
}

.outer:before { 
  content: ''; 
  display: inline-block; 
  height: 100%; 
  vertical-align: middle;
}

.inner { 
  width: 10rem; 
  display: inline-block; 
  vertical-align: middle;
  outline: solid black 1px; 
}

An example on Codepen: http://codepen.io/KatieK2/pen/ucwgi


For simpler cases, the following may be good options:

For single lines of content, you can do a quick and dirty vertical centering job on the text within an element by using line-height larger than your font-size:

.inner { 
  border: 1px solid #666; 
  line-height: 200%;
}

The solution with widest support is to use a non-semantic table. This works with very old versions of IE and doesn't require JavaScript:

td.inner { 
  vertical-align: middle; 
}

And here is simple solution for known height elements (which could be in ems, not px):

.outer { 
  position:relative; 
}
.inner { 
  position: absolute; 
  top:50%; 
  height:4em; 
  margin-top:-2em; 
  width: 50%; left: 25%; 
}
like image 197
KatieK Avatar answered Sep 20 '22 11:09

KatieK


You can get by with 2 fewer elements. Anything less than this is going to require things that IE8 (and IE9) doesn't support.

http://cssdeck.com/labs/0ltap96z

  <div class="centering-1">
    <div class="centering-2">
      <div class="intrinsically-sized-box">
        <p>You can put any content here too and the box will auto-size.</p>
      </div>
    </div>
  </div>

CSS:

body {max-width:750px;}
.generalblock {
  margin-top:2em; 
  position:relative;
  padding:10px;
  border:20px solid cyan;
  font-size: 18px;
}

.centering-1 {
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  text-align:center;
  visibility:hidden;
  display: table;
  width: 100%;
}
.centering-2 {
  display:table-cell;
  vertical-align:middle;
}
.intrinsically-sized-box {
  visibility:visible;
  max-width:300px;
  margin: 0 auto;
  background: yellow; 
  position:relative;
  border:1px solid black;
}
like image 44
cimmanon Avatar answered Sep 22 '22 11:09

cimmanon