I'm struggling to understand the the following css behavior. Maybe I'm missing something important because this actually seems like a simple scenario to me. Consider the following example:
.container {
background-color: lime;
font-size: 20px;
line-height: 20px;
}
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" >
<circle cx="12" cy="12" r="10"/>
</svg>
Text
</div>
Because container
has line-height: 20px
set, I'd expect it to be 20px high. At least this is the case if it only contains text. With the svg however it is suddenly 24px high, even though the svg is 20px high, as expected because of height=1em
. Also the "Text" has a height of 23px, even though I'd expect it to be 20px.
Interestingly, if I set container
's line-height to something like 30px, it behaves as expected: container
is now 30px
high.
Can you help me understand why container
is not 20px high? Or is line-height
simply not easily predictable once the container contains other elements than just plain text? Thank you!
There are two things going on in your demo that are affecting the height of div.container
. First, line-height
isn't an explicit, fixed height
: it specifies the minimum height of line boxes within div.container
in your case. Since line-height
is a minimum, it can grow if something inside it causes it to grow.
That leads to the SVG: it has a default vertical-align
of baseline
, which aligns it to the baseline of div.container
, and, due to its height, causes the height
of div.container
to grow to accommodate it. By changing vertical-align
of the SVG to something else so it fits within your 20px
line-height
, you can make it fit.
I've added a few different vertical-align
props to your demo so you can see how alignment affects height. In general, bottom
and top
align the svg to the bottom and top of the line, respectively, which, given the SVG's 20px
height, keep it within the line-height
. However, if you really, really need div.container
to be 20px
height, height
or max-height
are probably better bets.
.container {
background-color: lime;
font-size: 20px;
line-height: 20px;
margin-bottom: 1em;
}
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" >
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: baseline (24px)
</div>
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:middle">
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: middle (~22px)
</div>
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:bottom">
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: bottom (20px)
</div>
<div class="container">
<svg width="1em" height="1em" viewBox="0 0 24 24" style="vertical-align:top">
<circle cx="12" cy="12" r="10"/>
</svg>
Default: vertical-align: top (20px)
</div>