Here is a Label element in HTML and the red dotted outline shows it's bounding box. Notice that the characters are not flush with the top edge of their bounding box:
line-height:1.2; /* default */
Here is the JSFiddle showing the image above http://jsfiddle.net/6gLQU/16/.
Here is the same text where the line-height
style is set to 1 or 100% (it is better but still not flush):
line-height:1;
Finally, if I set the line-height
style to .8 (80%), as in this code example, it is flush except for a small but acceptable single pixel difference in the last test text. This is great but if there is more than one line of text (multiline) then the next line is pulled up too high because that makes each line height 80% of it's actual height.
line-height:.8;
Here is the JSFiddle code http://jsfiddle.net/6gLQU/16/.
(You can skip this paragraph if you don't know Flash) In Flash TLF (FTE or Flash Text Engine) if you add a text field, using FTE or TLF as it's engine, the text characters are aligned flush to the very top of the bounding rectangle. They look like the text in the last picture (the characters are snug up against the top border of the bounding box).
In HTML the text character is not aligned flush to the top of the bounding rectangle as shown in the examples above. When you increase the font size you also increase the gap from the top of the character to the top of the bounding box rectangle.
In my research in the text used in HTML and CSS the font style line-height
will adjust the position of the characters of text inside their bounding box (as shown in the pictures above). In Flash the line-height
style does not affect the characters in the first line of text but does adjust the following lines as well as in HTML (so it does not work in HTML or Flash for multiline).
I've determine that if I set line-height to .8 or 80% in HTML the font fits flush up against the top of the bounding box (as shown above). Great! That's what I want but it does not work for multiple lines of text. If there is more than one line, the next line is "pulled up" and overlaps the preceding line because, obviously, I'm giving each line only 80 percent of it's actual height.
Anyway, my question is:
line-height
causes multiple lines of text to be too close together. I found an alternative that uses a negative margin space but I must manually enter it. It's not ideal because it's a different value for each font size (found by trial and error) and it moves the text box up, not the characters. With the line-height
hack I can use .8
and I know it will be positioned correct.
Here is a link to the code and picture using negative margin. I only applied it to the last element. Notice the red border:
font-size:64px;
line-height:1.2;
margin-top:-14px;
Here is another test and another using multiples of 12 using negative margin percentage. Again, each negative margin value is different and found by trial and error:
font-size:12px;
line-height:1.2;
margin-top:-.19%;
Here is information on the FTE engine. I read it for an hour and I realize now I know a few of those words.
PS Sorry this question is so long. I'm trying to win the longest post award, apparently. Also, I added two questions because there is the actual problem and then there is the workaround question that might not be necessary if the actual problem is solvable. I'm not sure what this is called but someone told me it's a common thing with programming questions on SO. Also, adding the Firefox tag since it's running in Firefox and one of the Firefox developers might see it and know how this all works.
Update 2019:
I have another question posted about this somewhere but the accepted fix works for specific fonts but not every font.
IIUC The top edge of the text character, called a glyph, is called the caps height and the height of the container around the glyph is the em height. The caps heights are different for each font since fonts are different styles and created by different authors.
IIUC Browsers don't position according to em or font size and caps height is not considered.
A feature request I have for browsers would be to support aligning the first line of a text of a paragraph or label at the caps height so the text is flush to the top edge. That might be a negative text margin. This would make browsers accurately reproduce what many design tools support.
// something like any of these:
align-caps-height: true;
first-line-position: caps-height;
margin-top: caps-height;
Font spacing is not the problem here because text gets scaled evenly. The problem is created by margin in percentage. Percent margins are calculated as percent of width. So as you can expect, there will be no relation between the percent margin and
Method I
What you can do is, find the margin in pixel for one block. Then let k = font_size/ margin
for that block. Divide font-size
by k
to get margin of other blocks.
Method II
Instead of using percent margin, try using transform: translate;
using em values:
Relevant code
label { /* added properties*/
transform: translateY(-0.2em);
}
Updated Fiddle 1
Method III
I realized, bit late though, that transform
is not required. You can simply use margin-top: -0.2em;
Relevant code
label { /* added properties*/
margin-top: -0.2em;
}
Updated Fiddle 2
#BorderContainer1711 {
position:absolute;
left:32px;
top:60px;
width:500px;
height:160px;
background-color:#FFFFFF;
background-alpha:1;
border-width:1px;
border-style:solid;
border-color:#00DD00;
color:#000000;
}
label { /* added properties*/
margin-top: -0.2em;
}
#Label1551 {
position:absolute;
left:46px;
top:60px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:12px;
}
#Label1613 {
position:absolute;
left:123px;
top:60px;
width:61px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:24px;
}
#Label937 {
position:absolute;
left:220px;
top:60px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:36px;
}
#Label2125 {
position:absolute;
left:342px;
top:60px;
color:#000000;
font-weight:normal;
font-family:Arial;
font-size:64px;
}
*, *:before, *:after {
-moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box;
}
*, *:before, *:after {
outline:1px dotted red;
}
<div id="BorderContainer1711">
</div>
<label id="Label1551">[12px]</label>
<label id="Label1613">[24px]</label>
<label id="Label937">[36px]</label>
<label id="Label2125">[64px]<br>nextline</label>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With