7

I have this code:

<p style="line-height: 1;overflow: hidden;">blah_blah</p>
<p>blah_blah</p>

<p style="line-height: 1;overflow: hidden;">qypj;,</p>
<p>qypj;,</p>

which results in (notice no underscore, and cut characters):


enter image description here

That is, it behaves that way in Firefox (66.0.3 on Windows 10). Other browsers seem to render the underscore. The above snippet runner also seems to work (even in Firefox), unless you run it in "Full page".

This Q is similar to Text changes height after adding unicode character except there are no tricks here. "_" is just a simple ASCII character.

My question is which behavior is the correct one. Is specific character allowed to change line height (I thought it was only supposed to be font dependent)? Shouldn't line-height: 1 imply it can fit exactly any text?

I suppose some characters are special, such as "p", "g", "j" (and possibly "_") that draw below its line. Still which behavior is the correct one. Is it considered overflow or not?

PS: Furthermore I find it funny either overflow-x: hidden;overflow-y: visible; and overflow-x: visible;overflow-y: hidden; still causes this. Which seems more like an actual bug to me.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
krOoze
  • 12,301
  • 1
  • 20
  • 34

3 Answers3

11

My question is which behavior is the correct one.

All of them are correct because we don't have the same default font in all browsers and it's also different depending on the OS.

Is specific character allowed to change line height (I thought it was only supposed to be font dependent)?

Character doesn't change line-height. To be more accurate, line-height is a property that can only be changed by setting line-height but you are probably confusing with the line box that is defined by the line-height and a character alone cannot change it.

Shouldn't line-height: 1 imply it can fit exactly any text?

Not necessarely, line-height:1 means that the line box will be equal to the 1xfont-size 1 but is the font designed to include all the character inside this space? Probably most of them will do but we don't know.


Basically, you have two things to consider. The content area that is defined by the font properties and the line box that is defined by the line-height. We have no control over the first one and we can only control the second one.

Here is a basic example to illustrate:

span {
 background:red;
 color:#fff;
 font-size:20px;
 font-family:monospace;
}

body {
 margin:10px 0;
 border-top:1px solid;
 border-bottom:1px solid;
 animation:change 2s linear infinite alternate;
}

@keyframes change {
  from {
    line-height:0.2
  }
  
  to {
    line-height:2
  }
}
<span >
blah_blah
</span>

The red is our content area and its height is defined by the font properties and if you inspect the element you will see it has a height equal to 23px (not 20px like the font-size) and the borders define our line box that we control using the line-height.

So if the line-height is equal to 1 we will have a line box equal to 20px which is not enough to contain the 23px of the content area thus it will get truncated and we may probably hide some characters (or a part of them) which is logical:

span {
  background: red;
  color: #fff;
  font-size: 20px;
  font-family: monospace;
}

body {
  margin: 5px;
  line-height: 1;
  overflow:hidden;
}

html {
 overflow:auto;
}
<span>
blah_blah ÂÄ j p
</span>

a different font-size will remove the underscore in Firefox:

span {
  background: red;
  color: #fff;
  font-size: 26px;
  font-family: monospace;
}

body {
  margin: 5px;
  line-height: 1;
  overflow:hidden;
}

html {
 overflow:auto;
}
<span>
blah_blah ÂÄ j p
</span>

enter image description here

Another example with a Google Font where the result should be the same cross browser. The underscore is visible but not the ^/¨

span {
  background: red;
  color: #fff;
  font-size: 26px;
  font-family: 'Gugi', cursive;

}

body {
  margin: 5px;
  line-height: 1;
  overflow:hidden;
}

html {
 overflow:auto;
}
<link href="https://fonts.googleapis.com/css?family=Gugi" rel="stylesheet">
<span>
blah_blah ÂÄ j p
</span>

enter image description here

Another example where the underscore is not visible:

span {
  background: red;
  color: #fff;
  font-size: 27px;
  font-family: 'PT Sans', sans-serif;

}

body {
  margin: 5px;
  line-height: 1;
  overflow:hidden;
}

html {
 overflow:auto;
}
<link href="https://fonts.googleapis.com/css?family=PT+Sans" rel="stylesheet">
<span>
blah_blah ÂÄ j p
</span>

enter image description here

You can clearly see that we have a different overflow everytime we use a different font which confirms that this is font related. We have no control over it unless we know how the font is designed.


Related questions:

Understanding CSS2.1 specification regarding height on inline-level boxes

Why is there space between line boxes, not due to half leading?

Line height issue with inline-block elements


Here is a good article to get more accurate details and calculation: https://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align

A quote from this article:

It becomes obvious that setting line-height: 1 is a bad practice. I remind you that unitless values are font-size relative, not content-area relative, and dealing with a virtual-area smaller than the content-area is the origin of many of our problems.

enter image description here


1 : I considered a simplified explanation but in reality the calculation of the line box is not only relate to the line-height property.

Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • I mean, if I understand it correctly, Firefox considers the space of `line-box - line-height` an overflow. Meanwhile other browsers consider it not an overflow. So which is the correct behavior? Can't be both, (at least in ideal world). Not sure how default font matters here (which you open your answer with). Unless it is some kind of bitmap monospace font, then all fonts draw below the text line for esthetic reasons on some characters... – krOoze May 04 '19 at 00:51
  • @krOoze what you mean by *the space of line-box - line-height*? .. the line-height is defining the line box. And yes the font matters because not all of them have the same properties and not all of them are drawn the same way (the screenshot I added show a different behavior between Chrome and Firefox because the monospace font is not the same) – Temani Afif May 04 '19 at 00:54
  • @krOoze and if you run the snippet where I added the animation you will notice an overflow on the top and the bottom which is not necessarely equal and will not be the same for all the fonts too – Temani Afif May 04 '19 at 00:56
  • @krOoze added more details and examples, hope it more clear – Temani Afif May 04 '19 at 01:25
  • Took me some time to grok this. I think this is as close to answer as it gets. This example: https://jsfiddle.net/2qawxm50/ seems particularly illustrative to me if you wish to add it. – krOoze Jun 04 '19 at 13:52
2

If I use the browser tools in Firefox to inspect my snippet below, there is no height difference between the lines with and without underscore. The only difference is caused by the line-height setting: 16px with line-height: 1, 19.2 px with the browser's default line-height. So the underscore doesn't make a difference here (Firefox 66.0.3 on Mac), and it is visible in both cases.

Note that I set margins to 0 to see the "pure" line-height without distances between the lines. Also, I didn't specify a font-familiy setting, so the default font of the browser for p tags is used.

The only reason for what you describe which I can think of is a font with very particular dimensions/settings, where the descenders (i.e. the parts of letters like p q j which extend below the baseline) are not inside the line-height as defined by the font.

After a bunch of comments back and forth: I suppose it could be caused by the different default (system) fonts on Windows and Mac. Still a bug, I would say (if you are using the default font).

html,
body {
  margin: 0;
  padding: 0;
}

p {
  background: #fb6;
  margin: 0px;
}
<p style="line-height: 1;overflow: hidden;">blah_plah</p>
<p style="line-height: 1;overflow: hidden;">blah plah</p>
<p>blah_plah</p>
<p>blah plah</p>
Johannes
  • 64,305
  • 18
  • 73
  • 130
  • OK, I may have been inconsistent in the Q with "line height" vs "line-height". Although this is interesting. Considering the "container" of all the cases is the same I don't see a good reason why `overflow` should apply to some subpart of it. I guess it is up to what the specs say... (and whether or not should I report it to Mozzilla) – krOoze May 04 '19 at 00:11
  • Apparently the difference is between Windows and Mac: We both use FF 66.0.3, but I am on a Mac – Johannes May 04 '19 at 00:18
  • No, my observation matches yours. The `height` is the same. Only `line-height` differs. – krOoze May 04 '19 at 00:21
  • Actually I suppose it could be caused by the different default (*system*) fonts... – Johannes May 04 '19 at 00:22
  • Definitely. I should add the "p" etc to the snippet. Those are guaranteed to write below text line. Underscore could be aligned with text in some fonts... – krOoze May 04 '19 at 00:24
  • I just replaced some "b"s with "p"s. I still see everything, i.e. the full descender of the "p". What does it look like on Windows? – Johannes May 04 '19 at 00:28
  • Do you run it in online snippet editor, or do you save it to `htm` and open that file? – krOoze May 04 '19 at 00:32
  • Until now only in the snippet here. But same behaviour in Codepen: https://codepen.io/anon/pen/XwrVwm – Johannes May 04 '19 at 00:34
  • FWIW, I just tried it in a "real website": `line-height: 1`, `overflow: hidden;`, both with the webfont I had set and then also with the default font, in Firefox 66.0.3 on Mac: The underscore always remains visible... – Johannes May 04 '19 at 09:51
2

The default line-height (depending on the font-family) when not otherwise specified is about 1.2 in most browsers. This includes Firefox.

This would explain why the underscore did not show in FireFox when the line-height was set to 1 - the bottom was of the line was cut off. So I don't think it's entirely to do with the font (although this does contribute), but also browser defaults.

Some font-sizes are bigger than other even at seemingly the "same" font size (as I'm sure you've seen when typing documents in e.g. Georgia vs Times new Roman/Baskerville ; so you wouldn't be guaranteed that text would always show on a specified line height of 1 (or 1.2). There are ways of measuring a font in pixels however

Hope this helps

Rachel Gallen
  • 27,943
  • 21
  • 72
  • 81
  • In the snippet in my answer the underscore is visible regardless of the line-height (also in Firefox), so the underscore is definitely *not* "cut off" by `line-height: 1`. – Johannes May 04 '19 at 00:01
  • I couldn't see in Firefox until I set line height to 1.1 – Rachel Gallen May 04 '19 at 00:13
  • Hm - must be a different Firefox version then, reacting differently. I am on a Mac and FF 66.0.3 – Johannes May 04 '19 at 00:15
  • @Johannes also, only the 3rd out of the 4th 'blah blah' shows with an underline in FF on windows (latest version) - so yours is not a universal answer – Rachel Gallen May 04 '19 at 00:17
  • Note my other comment - seems to be a difference between FF Windows and Mac. – Johannes May 04 '19 at 00:19
  • @Johannes did you try to view the problem @ line-height of 1.1 on your Mac? – Rachel Gallen May 04 '19 at 00:20
  • Yes: still visible (which is logical, since it's even visible with `line-height: 1`) – Johannes May 04 '19 at 00:24
  • @RachelGallen I mean it makes sense it is `1.2`. Nobody wants to read crammed text (i.e. it is used as line distance). But definition of `1.0` is that it should match the text of a given font, no? – krOoze May 04 '19 at 00:37
  • @krOoze no. Font sizes differ. Have you scrolled through the fonts in Adobe or Word recently? They are not all the same at 10pt or 12pt.. why should they all fit in 1em? – Rachel Gallen May 04 '19 at 00:39
  • @RachelGallen Regardles whether they are 10pt or 12pt, they are 100 % of their own size. Not `1em`, `1` (unitless). – krOoze May 04 '19 at 00:41
  • @krOoze read this [article](http://iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align) – Rachel Gallen May 04 '19 at 01:10