4

I created small snippet to illustrate the problem.

I have a svg icon inside <i> tag. This is a basic block for my icons, placed throughout my page in various places. For the sake of this example I placed it inside a simple div container.

If you inspect the result of an example below you can see that <i> tag has height of 33px not 30px as expected. My question is why is that happening and how to prevent it?

.container {
  font-size: 30px;
}

.icon {
  line-height: 1;
}

.icon svg {
  height: 1em;
  width: 1em;
}
<div class="container">
  <i class="icon">
    <svg width="24" height="24" viewBox="0 0 24 24"><path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" /></svg>
  </i>
</div>

1 Answers1

7

To prevent it make the i inline-block and correct the alignment of the SVG.

.container {
  font-size: 30px;
  height: 30px;
  width: 30px;
}

.icon {
  line-height: 1;
  display:inline-block;
}

.icon svg {
  height: 1em;
  width: 1em;
  vertical-align:top;
}
<div class="container">
  <i class="icon">
    <svg width="24" height="24" viewBox="0 0 24 24"><path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" /></svg>
  </i>
</div>

The why is a bit tricky and is font related. Basically, the height of the i which is an inline element depend on the font properties and setting line-height:1 isn't enough

To better illustrate:

$('i').each(function(){
 console.log("i element: "+$(this).css('height')+" SVG: "+ $(this).find('svg').css('height'));
})
.container {
  font-size: 30px;
  height: 30px;
  width: 30px;
  line-height: 0;
  margin:10px;
}

.icon {
  line-height: 0;
  background:green;  
}

.icon svg {
  height: 1em;
  width: 1em;
  vertical-align:top;
  background:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <i class="icon">
    <svg width="24" height="24" viewBox="0 0 24 24"><path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" /></svg>
  </i>
</div>

<div class="container" style="font-family:monospace">
  <i class="icon">
    <svg width="24" height="24" viewBox="0 0 24 24"><path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" /></svg>
  </i>
</div>

<div class="container" style="font-family:cursive">
  <i class="icon">
    <svg width="24" height="24" viewBox="0 0 24 24"><path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" /></svg>
  </i>
</div>

As you can see, we have the same font-size and line-height is set to 0 and we still have the i bigger because it represent the content area that we cannot control.

More details here: Can specific text character change the line height

Also related: Line height issue with inline-block elements to better understand how line-height works because it's not always intuitive.

Another one to show the difference between line box and content area: Why is there space between line boxes, not due to half leading?

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thanks for the answer. I've tried with `inline-block`, but without `vertical-align` it didn't work. Also really nice example illustrating why this is happening. Although `vertical-align` will probably won't work for me cause it breaks my layout in places where `i` tag height is bigger than svg height, I think I will be able to make it work using flexbox cause from what I've quickly tested it yields same result. – Christopher Kalkhoff Sep 06 '19 at 11:06