2

Ok, I've got the following HTML structure

<div class="category">
    <div class="container bottom">
        <h2>Name1</h2>
    </div>
    <div class="container top">
        <h2>Name2</h2>
    </div>
    <div class="container ">
        <h2>Name3</h2>
    </div>
    <div class="container">
        <h2>Name4</h2>
    </div>
    <div class="container">
        <h2>Name5</h2>
    </div>
    <div class="container">
        <h2>Name6</h2>
    </div>
    <div class="container">
        <h2>Name7</h2>
    </div>
</div>

The CSS is this:

* {
    margin: 0;
    padding: 0;
}

.category {
    text-align: center;
    width: 95%;
    margin: 0 auto;
}

.container {
    display: inline-block;
    width: 33%;
    height: 4em;
}

h2 {
    display: inline-block;
    width: 100%;
}

.left > * {
    text-align: left;
}

.right > *{
    text-align: right;
}

.top > * {
    vertical-align: top;
}

.bottom > * {
    vertical-align: bottom;
}

The main goal is to do something like this: Example

For the sake of it, pretend the picture is accurate and the .container (gray boxes) have the same size (as you can see in the CSS)

My problem is the vertical-align is not working.. I've looked into this CodePen Code that works without display: table-cell and other table-display-related solutions I've found out in StackOverflow. Why doesn't it work with my HTML and CSS code? I get all the <h2> align in the middle :\

PedroMendes
  • 75
  • 1
  • 9

4 Answers4

3

In the Codepen example it's not actually the h2 is vertically aligned in the box. It's the alignment of elements next to each other, not the elements in the container. It's a bit confusing. Having one inline element won't work but if you had two you would see them vertically align with each other. However when using a table cell this functionality changes.

Try removing the images from the Codepen example and then putting a height on the div. You'll see that it stops being vertically aligned.

I would align with display:table and display:table-cell. It will work using the position:absolute approach but if the text expands out of the box you will have layout issues as the text isn't in the document flow anymore. By setting them as tables you keep a bit of flexibility.

Adam Hughes
  • 2,197
  • 20
  • 31
0

A solution is to use absolute positioning.

.container {
  position: relative;
}

.container h2.middle {
  position: absolute;
  top: 50%;
  -webkit-transform: translateY(-50%);
  transform: translateY(-50%);
}

To style the different classes just change the .middle class after h2 and apply left right top bottom values as necessary. Something like this:

.container h2.top {
  position: absolute;
  top: 0;
}

.container h2.bottom {
  position: absolute;
  bottom: 0;
}

.container h2.right {
  position: absolute;
  right: 0;
}

.container h2.left {
  position: absolute;
  left: 0;
}

And in your html:

<div class="container">
    <h2 class="top">Name1</h2>
</div>
<div class="container">
    <h2 class="bottom">Name2</h2>
</div>
<div class="container ">
    <h2 class="left">Name3</h2>
</div>
<div class="container">
    <h2 class="right">Name4</h2>
</div>
Chrillewoodz
  • 27,055
  • 21
  • 92
  • 175
  • @PedroMendes Because you lack a lot of the CSS in the pen which you didn't use in your example here. – Chrillewoodz Jul 05 '15 at 14:35
  • how come? I have a reset `* { margin: 0}` applied and my `

    ` inside the `.container` has `display: inline-block` and `width: 100%`.. I believe it is pretty much the same.. I will edit my original post

    – PedroMendes Jul 05 '15 at 14:48
  • Since this was the solution I ended up using, I'll mark it as the answer. However, I was looking for a reason why it works in the codepen link given and not on my code :'( thank you – PedroMendes Jul 05 '15 at 17:11
  • @PedroMendes I'm unsure to why it wasn't working for you, but as a general opinion I try to stay away from using table-like CSS. Using absolute is more flexible even if it has a tiny decrease in performance. So this solution should be more suitable to you. – Chrillewoodz Jul 05 '15 at 17:23
  • I would just use a `display:table-cell`. It gives you more flexibility if the amount of text changes as it's kept in the document flow. – Adam Hughes Jul 06 '15 at 08:50
0

<h2> alignment is due to its default margin. Try positioning the h2 using translateY.

.category {
text-align: center;
width: 95%;
margin: 0 auto;
}

.container {
border: 1px solid red;
display: inline-block;
width: 32%;
height: 4em;
}

.left {
text-align: left;
}

.right {
text-align: right;
}

.top h2{
  transform: translateY(0);
}

.bottom h2 {
  transform: translateY(100%);
}
h2{
margin: 0;
display: inline-block;
transform: translateY(50%);
}
<div class="category">
<div class="container bottom">
    <h2>Name1</h2>
</div>
<div class="container top">
    <h2>Name2</h2>
</div>
<div class="container left">
    <h2>Name3</h2>
</div>
<div class="container bottom">
    <h2>Name4</h2>
</div>
<div class="container right">
    <h2>Name5</h2>
</div>
<div class="container bottom right">
    <h2>Name6</h2>
</div>
<div class="container">
    <h2>Name7</h2>
</div>
</div>
Felix A J
  • 6,300
  • 2
  • 27
  • 46
0

first of all the height of the div is very small and h2 had default margin. the best way to vertical align bottom according to me is make

.container{ 
   position: relative;
}
.bottom { 
    position: absolute; 
    bottom: 0px;
 } 
<div class="container">
   <h2 class="bottom">Name1</h2>
</div>
Dmitriy
  • 4,475
  • 3
  • 29
  • 37