2

I have a problem that I've had for years.

A text with line-height: 1 will be compact and will reach the top and bottom of the surrounding elements.

A text with another line-height will be more readable but at the same time, it will no longer reach the top and bottom of the surrounding elements.

Here is a code example of the problem and a hackish solution. Changing the line-height or the font size will break it.

Is the a solid fix for this?

.wrap {
  display: flex;
}

.first {
  background: red;
  width: 1rem;
}

.second,
.second2{
  line-height: 2;
}

.second2 {
  margin-top: -9px;
  margin-bottom: -7px;
}
<strong>Problem:</strong> The letter "A" does not align with the red top.<br><br>

<div class="wrap">
  <div class="first"></div>
  <div class="second">A text that<br>spans on multiple rows</div>
</div>

<br><br>

<strong>Hackish fix:</strong> The letter "A" does align with the red top.<br><br>

<div class="wrap">
  <div class="first"></div>
  <div class="second2">A text that<br>spans on multiple rows</div>
</div>

The line-height is taken to the extreme, just to show the effect.

Jens Törnell
  • 23,180
  • 45
  • 124
  • 206
  • I doubt there is a solid fix (related: https://stackoverflow.com/a/62303653/8620333 ). As a side note, this is by design so why you want to fix something that is meant to work that way? – Temani Afif Apr 09 '21 at 13:16
  • @TemaniAfif How else would you make a text align with the top of a box if you still want line-height? – Jens Törnell Apr 09 '21 at 15:03
  • 1
    the solution I am linking above. I don't see more robust. In all the cases you need to have a extra property to rectify that gap. You can probably optimize it by introducing calc() to make it more generic. – Temani Afif Apr 09 '21 at 15:10
  • 1
    I think that [`text-edge: text`](https://drafts.csswg.org/css-inline-3/#text-edges) will one day support a better solution, but for now the hacky solution's all that's available. – Alohci Apr 09 '21 at 16:39
  • @Alohci Great news! It means that I'm not crazy after all! – Jens Törnell Apr 09 '21 at 17:30

1 Answers1

1

As you've observed, if you give an element containing text:

  • a font-size of 1em
  • a line-height of 2em

the text will be rendered in the vertical middle of the line-height.

The text will still be 1em tall, but it will now have 0.5em of space above it and below it.

To (seemingly, though not actually) counteract this vertical-middle-alignment, one approach would be to apply a

transform: translateY(-0.5em)

to the text-containing element.


Working Example:

body {
  display: flex;
}

.wrap-1,
.wrap-2,
.wrap-3 {
  display: flex;
  margin-right: 12px;
}

.first {
  background: red;
  width: 1rem;
}

.wrap-1 .second {
  font-size: 1em;
  line-height: 1em;
  background-color: rgb(255, 255, 0);
}

.wrap-2 .second {
  font-size: 1em;
  line-height: 2em;
  background-color: rgb(255, 255, 0);
}

.wrap-3 .second {
  font-size: 1em;
  line-height: 2em;
  background-color: rgb(255, 255, 0);
}

.wrap-3 .second p {
  background-color: rgba(0, 0, 0, 0.2);
  transform: translateY(-0.5em);
}

p {
  margin: 0;
  padding: 0;
  background-color: rgba(0, 0, 0, 0.2);
}
<div class="wrap-1">
  <div class="first"></div>
  <div class="second"><p>A text that<br>spans on multiple rows</p></div>
</div>

<div class="wrap-2">
  <div class="first"></div>
  <div class="second"><p>A text that<br>spans on multiple rows</p></div>
</div>

<div class="wrap-3">
  <div class="first"></div>
  <div class="second"><p>A text that<br>spans on multiple rows</p></div>
</div>
Rounin
  • 27,134
  • 9
  • 83
  • 108
  • 1
    Yes, I think you are more than half way there. I don't use `em` but just a number. I've now read that the number 2 in this case is font-size multiply by 2 so it would 2 * 1rem in case the font-size is 1rem. My guess is that a calc function would make it all the way. – Jens Törnell Apr 09 '21 at 15:02
  • 1
    `calc()` sounds like a good idea. You can probably do even more if you combine `calc()` with a [CSS Custom Property](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties) or two. – Rounin Apr 09 '21 at 15:15
  • 1
    Yes, custom property for the font-size to prevent duplication. – Jens Törnell Apr 09 '21 at 15:22