8

I am trying to align the baseline of some text in a div to the very bottom edge of said div (such that characters like g and j would actually overflow the div)

I can only seem to align the bottom edge of the text element to the bottom edge of the div. I have tried to use vertical-align with values baseline and bottom on the inner and outer element, but without success.

div {
  height: 80px;
  width: 300px;
  background: #ff5;
  position: relative;
}

span {
  font-size: 30px;
  position: absolute;
  left: 0;
  bottom: 0;
}
<div>
  <span>
  TEST gjp ABC
  </span>
</div>

I also want to be able to offset the baseline from the bottom of the div (e.g. bottom: 10px; positions the baseline of the text 10px from the bottom edge of the div).

Edit: I should also mention that I want to keep the position: absolute; property on the span element, because I want to freely position multiple of those in the parent div.

For example, here, A's baseline should be at the bottom edge of the div, B's should be 10px above it and C's 20px:

div {
  height: 80px;
  width: 300px;
  background: #ff5;
  position: relative;
}

span {
  font-size: 30px;
  position: absolute;
  left: 0;
  bottom: 0;
}
<div>
  <span style="left: 0px; bottom: 0px;">
  A
  </span>
  <span style="left: 50px; bottom: 10px;">
  B
  </span>
  <span style="left: 100px; bottom: 20px;">
  C
  </span>
</div>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
lux
  • 139
  • 2
  • 8

3 Answers3

5

Add a ::before pseudo element with 100% height and display: inline-block; and use it to vertically align the <span> to the baseline:

div {
  height: 80px;
  width: 300px;
  background: #ff5;
  position: relative;
}

div::before {
  display: inline-block;
  height: 100%;
  content: '';
}

span {
  font-size: 30px;
  vertical-align: baseline;
}
<div>
  <span>TEST gjp ABC</span>
</div>

You can apply the same idea to the span itself, but you'll have to state the height of the span:

div {
  height: 80px;
  width: 300px;
  background: #ff5;
  position: relative;
}

span {
  display: inline-block;
  font-size: 30px;
  position: absolute;
  left: 0;
  bottom: 0;
  height: 1em;
  background: red;
}

span::before {
  display: inline-block;  
  height: 100%;
  vertical-align: baseline;
  content: '';
}
<div>
  <span style="left: 0px; bottom: 0px;">gjp</span>
  <span style="left: 50px; bottom: 10px;">gjp</span>
  <span style="left: 100px; bottom: 20px;">gjp</span>
</div>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
  • this works, but I want to keep the `position:absolute;` in the `span` because I want to freely position **multiple** of those `span` elements in the parent div. I didn't state this explicitly in my original question, so I'll edit it – lux Oct 27 '19 at 19:12
  • sorry to bother again, but now there seems to be a space inserted between the `::before` element and the actual text in the `span`. I need the left edge of the `span` at the position I specify. If the gap were consistent I could just shift the `span` to the left by a certain amount, but the gap varies with font size... – lux Oct 27 '19 at 19:45
  • 2
    That's a white space. You can remove the white space in the HTML or use one of the other methods proposed here. I've updated the HTML to remove the white space. – Ori Drori Oct 27 '19 at 19:48
  • Oh I see. I though it added a space between the `::before` element and the text, and since `::before` is only a pseudo-element and not specified inside the html code, I though I can't get rid of it by removing spaces. Thanks! – lux Oct 27 '19 at 19:52
1

You can also decrease line-height to 0.8em so the text overflow the span .

<div style="height: 80px; width: 300px; background: #ff5; position: relative;">
 <span style="font-size: 30px; position: absolute; left:0; bottom:0;line-height:0.8em;">
  TEST gjp ABC
 </span>
</div>
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
1

Make the span with a line-height equal to 0 then consider a hidden character that will control the alignment. You may need to adjust the value based on the font used:

.container {
  height: 80px;
  width: 400px;
  background: #ff5;
  position: relative;
}

.container>span {
  font-size: 30px;
  position: absolute;
  left: 0;
  bottom: 0;
  line-height: 0;
}

.container>span:before {
  content: "\200B";
  vertical-align: -0.35em;/* Adjust this */
}
<div class="container">
  <span>TEST gjp ABC</span>
  <span style="font-family:arial;right:0;left:auto;font-size:20px">TEST gjp ABC</span>
</div>

You can also simply consider a translation:

.container {
  height: 80px;
  width: 400px;
  background: #ff5;
  position: relative;
}

.container>span {
  font-size: 30px;
  position: absolute;
  left: 0;
  bottom: 0;
  line-height: 0;
  transform: translateY(-0.35em);
}
<div class="container">
  <span>TEST gjp ABC</span>
  <span style="font-family:arial;right:0;left:auto;font-size:20px">TEST gjp ABC</span>
</div>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415