Home > Software engineering >  White space above a vertically aligned inline-block element
White space above a vertically aligned inline-block element

Time:06-16

Code

.outer {
    display: block;
    background: lightblue;
    font-size: 50px;
}

.inner {
    display: inline-block;
    width: 50px;
    height: 50px;
    background: red;
    vertical-align: middle;
}
<div ><div ></div></div>

You can play and see the result here: https://jsfiddle.net/y1jkw3nu/5/

Problem

I have this weird empty space above the red square.

Question

Can someone explain to me where does this empty space come from? I understand that it's because of font-size: 50px, but the .inner div have vertical-align: middle. Doesn't it mean it should be positioned in the middle of the line?

CodePudding user response:

Thats because the 'content' inside reserves height for the text that could be there... put line-height:0 and its gone..

.outer {
    display: block;
    background: lightblue;
    font-size: 50px;
line-height:0;
}

.inner {
    display: inline-block;
    width: 50px;
    height: 50px;
    background: red;
    vertical-align: middle;
}
<div ><div ></div></div>

CodePudding user response:

First you need to understand what vertical-align is doing here:

middle

Align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the parent.

So you need to find the "baseline", the "x-height" and the midpoint of your box (this one is trivial).

To better find those values, add some text:

.outer {
  display: block;
  background: 
    linear-gradient(blue 0 0) 50% calc(50%   .33em - .5ex)/100% 2px no-repeat,
    linear-gradient(#fff 0 0) 50% calc(50%   .33em)/100% 2px no-repeat
    lightblue;
  font-size: 50px;
}

.inner {
  display: inline-block;
  width: 50px;
  height: 50px;
  background: 
    linear-gradient(green 0 0) 50%/100% 2px no-repeat
    red;
  vertical-align: middle;
}
<div >ÂBp
  <div ></div>
</div>

In the above, note how the "blue" (baseline half the x-height) and "green" (midpoint) line are aligned. Also note how the blue is shifted by 0.5ex from the baseline (in white).

Even without text, the above still apply and only the font properties will affect this alignment.

... if each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a "strut." (The name is inspired by TeX.).

The height and depth of the font above and below the baseline are assumed to be metrics that are contained in the font. (For more details, see CSS level 3.)

That "strut" element is the one used instead of the text.

You can also reduce the size of the box and you will have space at the bottom as well:

.outer {
  display: block;
  background: 
    linear-gradient(blue 0 0) 50% calc(50%   .33em - .5ex)/100% 2px no-repeat,
    linear-gradient(#fff 0 0) 50% calc(50%   .33em)/100% 2px no-repeat
    lightblue;
  font-size: 50px;
}

.inner {
  display: inline-block;
  width: 50px;
  height: 30px;
  background: 
    linear-gradient(green 0 0) 50%/100% 2px no-repeat
    red;
  vertical-align: middle;
}
<div >ÂBp
  <div ></div>
</div>

CodePudding user response:

You could give the .outer a height: 50px and the .inner position:absolute.

    .outer {
    display: block;
    background: lightblue;
    font-size: 50px;
    height:50px;
}

.inner {
    display: inline-block;
    width: 50px;
    height: 50px;
    background: red;
    vertical-align: middle;
    position:absolute;
}
  • Related