Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to vertically center text in its bounding box?

Tags:

css

My text is not vertically centered and my designers are pointing it out.

However, I am using the proper CSS to achieve vertical centering, that is not the issue.

The problem lies in the font itself. The glyphs are not centered in the actual text. Selecting the text reveals its bounding box, and from here I can see an uneven amount of space below the text.

enter image description here

Line-height does not appear to fix this issue. The bounding box is still off, even with a line-height of 0. I can add padding to the top of my elements to attempt to fix this problem, but that's not going to be scalable across the many elements that use this font.

With descender It appears that the uneven space is because of descenders. This makes sense, but unfortunately it doesn't get me any closer to figuring out how to truly vertically center this text.

enter image description here

The font in question is SouvenirStd-Medium, but I have noticed this with many other web fonts. It is consistently off no matter which element is used... h1's, paragraph tags, etc.

Although it probably wont be useful, here is an example my styles for headlines:

font-family: SouvenirStd-Medium;
font-size: 5rem;
font-weight: 400;
font-style: normal;
line-height: 1.3;
letter-spacing: 0;

And an example of how I am centering my text in a wrapping tag.

div {
   display: flex;
   height:100px;
   align-items: baseline;
}
like image 274
lostPixels Avatar asked Oct 30 '22 04:10

lostPixels


1 Answers

Line height won't help the issue, as it adds or subtracts equal amount of space to the top and bottom of a single text line, based on the top and bottom spacing defined within the font itself (see line-height description at w3c for more information). This means that you need to find a different font in order to get what you want without going out of your way.

padding-top or padding-bottom work great if you use em as the unit, which is relative to the total height of the letter (including the above and below space). That will allow you to shift text by the same relative amount accross the whole webpage, independant of the font-size (and you can use line-height from there to manage distance between individual lines):

.font-timesnewroman {
  font-family: 'Times New Roman', serif;
  padding-top: 0.1em;
}

Adapted from a hack I found in this blog post, here's a possible solution if the above doesn't work for you (yet also a bit narrow in application):

div {
  height: 100px;
  margin-top: 40px;
  border: thin dotted gray;
  text-align: center;
}
.text {
  font-size: 100px;
  line-height: 0px;
  background-color: #9BBCE3;
}
.text::after {
  content:'';
  display: inline-block;
  height: 80%; /* adjust this to shift the text */
}
<div>
  <span class="text">Test</span>
</div>

This has the following features and constraints:

  • works for elements the above solution doesn't, for example because the elements you're trying to style already have a padding
  • allows you to adjust the baseline with percentage or em values (so they do scale with font-size)
  • halfway implementable with the after-selector, however requires a span (or other inline-rendered) element around the text to be positioned
  • only works for non-wrapping lines
like image 138
TheThirdMan Avatar answered Dec 06 '22 14:12

TheThirdMan