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;
}