2

I have the following simple code snippet. It is taken out from my application where .a1 is a container button, which has an icon. The icon should be vertically middle aligned to the parents line-height/height, but it is shifted with 1px from top. Could you explain me why this is the behavior? Is there any solution?

.a1 {
  display: inline-block;
  width: 28px;
  line-height: 28px;
  background-color: #000;
  text-align: center;
  vertical-align: middle;
}
.i {
  display: inline-block;
  width: 16px;
  height: 16px;
  background-color: #f00;
  vertical-align: middle;
}
<div class="a1"><i class="i"></i>
</div>
Roland Soós
  • 3,125
  • 4
  • 36
  • 49

4 Answers4

1

Why?

Because inline-block elements render with "white-space". You can see this in this demo where no height/width is set on the parent element.

When you use vertical-align:middle; the "white space" is rendered before the element (on top) (black line in the demo). This space moves the child element down and therefore it doesn't appear verticaly centered.

how to fix :

You can use display:block; and calculate the margin to apply to the child element so it centers verticaly and horzontaly.

You can also take a look at this question which talks about white space and ways to avoid them.

Community
  • 1
  • 1
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • As Roland Soós pointed out in his own answer, setting font-size 0 on the parent will work exactly because of this. The white space will have no size. But I wouldn't like to count on it so using margin is correct.(or flexboxing) – René Oct 28 '14 at 14:39
1

Well, it seems like font-size:0; for .a1 seems also a fix for such issue.

.a1 {
  display: inline-block;
  width: 28px;
  line-height: 28px;
  background-color: #000;
  text-align: center;
  vertical-align: middle;
  font-size: 0;
}
.i {
  display: inline-block;
  width: 16px;
  height: 16px;
  background-color: #f00;
  vertical-align: middle;
}
<div class="a1"><i class="i"></i>
</div>
Roland Soós
  • 3,125
  • 4
  • 36
  • 49
0

.a1 {
  display: inline-block;
  background-color: #000;
}
.i {
  display: block;
  width: 16px;
  height: 16px;
  margin: 6px 6px;
  background-color: #f00;
}
<div class="a1"><i class="i"></i>
</div>
Jason Williams
  • 2,740
  • 28
  • 36
  • Okay, this is a possible fix for the issue, but do you have any explanation what cause the original issue? My code seems logic for me, but it doesn't behave like yours. If I could get an explanation, that could help me with future problems with vertical align middle. Thanks! – Roland Soós Oct 28 '14 at 14:26
  • Using line-height with vertical-align makes sense for fonts. However, it doesn't play nice with block elements. Although the line-height was 28px, the font-size inside the block was inheriting from the parent container. My theory is it was trying to vertical-align based on the size of the font inside the container....even though there are no fonts in the container. – Jason Williams Oct 28 '14 at 14:34
  • You gave me an idea to test it with font-size: 0; on the parent element and it seems like that can also fix this problem. – Roland Soós Oct 28 '14 at 14:38
  • Cool. Glad I could have some input. – Jason Williams Oct 28 '14 at 14:40
0
.a1 {
  display: inline-block;
  background-color: #000;
}
.i {
  display: block;
  width: 16px;
  height: 16px;
  margin: 6px 6px;
  background-color: #f00
user3722785
  • 216
  • 1
  • 13