2

I am trying to vertically center some h2 text within a div using display:table-cell combined with vertical-align: middle.

However, this is not working seemingly because the div I'm trying to center the content in is the child of another div.

Here is my CSS and HTML:

.productList {
  width: 100%;
  max-width: 1120px;
  position: relative;
  margin: 0 auto;
}
.hoverbase1 {
  float: left;
  margin: 15px;
  width: 250px;
  height: 250px;
  position: relative;
}
.hoverbase1 a br {
  display: none;
}
.hoverbase1 img {
  width: 250px;
  height: 250px;
  position: relative;
}
.hovertop1 {
  position: absolute;
  width: 250px;
  height: 250px;
  bottom: 0;
  left: 0;
  background-color: white;
  border: 2px solid black;
  opacity: 0;
  display: table-cell;
  vertical-align: middle;
}
.hoverbase1 a:hover + .hovertop1,
.hovertop1:hover {
  opacity: 1;
}
<div class='productList'>
  <div class='hoverbase1'>
    <a href='http://kingfisher.org.au/library-shelving'>
      <img src="http://kingfisher.org.au/pic/library_shelving.jpg" />
    </a>
    <div class='hovertop1'>
      <a href='http://kingfisher.org.au/library-shelving'>
        <h3>Library Shelving</h3>
      </a>
    </div>
  </div>
</div>

Also available as a fiddle.

misterManSam
  • 22,389
  • 10
  • 63
  • 82
James M
  • 87
  • 8
  • This question has been [asked](http://stackoverflow.com/questions/8865458/how-to-align-text-vertically-center-in-div-with-css) [several](http://stackoverflow.com/questions/2939914/vertically-align-text-in-a-div) [times](http://stackoverflow.com/questions/9249359/is-it-possible-to-vertically-align-text-within-a-div?lq=1) [before](http://stackoverflow.com/questions/396145/how-to-vertically-center-a-div-for-all-browsers?rq=1). At least one of them could answer yours. – Hashem Qolami Oct 03 '14 at 06:45

4 Answers4

4

I have prepared this example with display: inline-block, instead of table-cell, so they can wrap and I removed all unneeded HTML markup.

Main CSS Properties

  • The text is centered using a pseudo element, .product:before. Essentially this element forces the inline text to vertically align in the middle. If you need this to work in IE6 - 7, it can be replaced with a div.

  • The text is given 0 opacity until .product is hovered.

  • The image is position: absolute and will position itself in relation with it's position: relative parent. This is needed to pull it out of the flow in order to align the text.

  • The transitions smooth out the opacity changes. .product is given a white border so that it can transition to a black border when hovered.

Note: Currently there is no fallback for browsers which don't support opacity, namely IE6 and 7. This can be achieved, if needed, with display: none in an IE 6 / 7 conditional stylesheet.

2 Examples

"Show code snippet" and run it.

We don't need no silly div

The class .product is given to the <a> element and the entire box is a link.

<a class="product" href="href='http://kingfisher.org.au/library-shelving">
  <img src="http://kingfisher.org.au/pic/library_shelving.jpg" />
  <h2>Library Shelving</h2> 
</a>

.product {
  width: 250px;
  height: 250px;
  display: inline-block;
  vertical-align: middle;
  position: relative;
  border: solid 1px #FFF;
  transition: border 1s;
  text-align: center;
}
.product:before {
  height: 100%;
  content: '';
  display: inline-block;
  vertical-align: middle;
}
.product img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.5s;
}
.product:hover {
  border: solid 1px #000;
}
.product:hover img {
  opacity: 0;
}
.product h2 {
  opacity: 0;
  transition: opacity 0.5s;
  font-weight: none;
  display: inline;
  font-size: 1em;
}
.product:hover h2 {
  opacity: 1;
}
.product {
  text-decoration: none;
}
<a class="product" href="href='http://kingfisher.org.au/library-shelving">
  <img src="http://kingfisher.org.au/pic/library_shelving.jpg" />
  <h2>Library Shelving</h2> 
</a>

With a div - "I don't want them clicking just anywhere!"

  • The class .product is given to a div that contains the image and text. Only the text is a link.

  • The <a> is position relative so it can be given z-index: 2 to ensure that it is clickable. This is mainly for IE8 and 9.

  • The image is given z-index: 1 so that it positions itself underneath the <a>

<div class="product">
  <img src="http://kingfisher.org.au/pic/library_shelving.jpg" />
  <a href="href='http://kingfisher.org.au/library-shelving">
    Library Shelving
  </a>
</div>

.product {
  width: 250px;
  height: 250px;
  display: inline-block;
  vertical-align: top;
  position: relative;
  text-align: center;
  border: solid 1px #FFF;
  transition: border 1s;
}
.product:before {
  height: 100%;
  content: '';
  display: inline-block;
  vertical-align: middle;
}
.product img {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  transition: opacity 0.5s;
  z-index: 1;
}
.product:hover {
  border: solid 1px #000;
}
.product:hover img {
  opacity: 0;
}
.product a {
  position: relative;
  text-decoration: none;
  font-weight: normal;
  opacity: 0;
  transition: opacity 0.5s;
  z-index: 2;
}
.product:hover a {
  opacity: 1;
}
a:hover {
  text-decoration: underline;
}
<div class="product">
  <img src="http://kingfisher.org.au/pic/library_shelving.jpg" />
  <a href="href='http://kingfisher.org.au/library-shelving">
    Library Shelving
  </a>
</div>
misterManSam
  • 22,389
  • 10
  • 63
  • 82
0

With the table-cell it makes vertical center and as usual, text-align:center does horizontal center.

.hovertop1 a {
    display: table-cell;
    vertical-align: middle;
    text-align:center;
}

Try with this.

Sameera Thilakasiri
  • 8,933
  • 8
  • 49
  • 80
  • While [one line answers](http://meta.stackoverflow.com/questions/266954/one-line-answers) and snippet-only are acceptable, they often result in the answer being routed to the Review Queue (*q.v.*). In addition, sometimes they are not well received by the community. Its usually a good idea to provide a brief explanation that explains how the answer solves the problem. – jww Oct 03 '14 at 04:47
  • @jww I'm sorry, I didnt get much time to write the answer just gave the idea, I'll update now. – Sameera Thilakasiri Oct 03 '14 at 05:02
  • 2
    See [Fastest Gun in the West Problem](https://meta.stackexchange.com/questions/9731/fastest-gun-in-the-west-problem) on Meta... – jww Oct 03 '14 at 05:08
0

Try adding position:relative; to the div containing the <h2> then add this to the <h2> element:

position:absolute;
top: 50%;
SnareChops
  • 12,124
  • 8
  • 61
  • 88
0

Check this out. I've made it incredibly simple. The key is setting line-height on the parent and vertical-align on the child (NOT THE PARENT!). vertical-align only works within the space of a line. Even if you have a div with height:300px; The default line-height will be the font-size so you need to set it manually.

http://jsfiddle.net/y6mx14pz/

div{
    text-align:center;
    line-height:300px;
    border:1px solid black;
}

h1{
    vertical-align:middle;
}
Christopher Reid
  • 3,364
  • 2
  • 25
  • 63