In the code example below, you will see white-space between the vertically flowing spanss. The white space is between each line box.
I want to start out by stating that this has nothing to do with gaps between inline-block boxes or even a result of half leading, which is added on top and bottom of an inline level box when calculating minimum line height.
From the CSS2.1 spec:
The height of the inline box encloses all glyphs and their
half-leading on each side and is thus exactly 'line-height'.
And:
The minimum height (of a line box) consists of a minimum height above the baseline and a minimum depth below it....
Notes:
background-color (as seen in the below example) covers the full line box
Despite that, there is still white-space between each line box
I am not asking for a solution to remove the gap. If I wanted to do that, I would just set display: inline-block on the span
Why is the gap there, with basis in the CSS2.1 specification. What part of the spec explains that spacing?
Example code:
// From CSS spec:
// The height of the inline box encloses all glyphs and their half-leading on each side and is thus exactly 'line-height'. Boxes of child elements do not influence this height.
span {
background-color: red;
line-height: 1;
}
<span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span><br/><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span>
The background properties applies only to the content area and not the line box. In most of the cases the content area is defined by the height. As we can read in the specification:
The dimensions of the content area of a box — the content width and
content height — depend on several factors: whether the element
generating the box has the 'width' or 'height' property set, whether
the box contains text or other boxes, whether the box is a table, etc.
And here:
This property specifies the content height of boxes.
This property does not apply to non-replaced inline elements. See the
section on computing heights and margins for non-replaced inline
elements for the rules used instead.
And if check the above link we can read:
The 'height' property does not apply. The height of the content area
should be based on the font, but this specification does not specify
how. A UA may, e.g., use the em-box or the maximum ascender and descender of the font.
Here is an illustration to better show youref:
The content area is defined by the browser and in some case it can be the em1 that you see in above figure but not necessarely.
In all the cases and whataver the line-height will be, the content area will only depend on the font properties. So the line-height define the height of the line box AND the content area height is defined by the font properties.
So the real question is: Why by default the line-height doesn't make the line box equal to the content-area?
If check we check the documentation we can see that the default value is set to normal and:
normal
Depends on the user agent. Desktop browsers (including Firefox)
use a default value of roughly 1.2, depending on the element's
font-family.
Then
<number> (unitless)
The used value is this unitless <number> multiplied by the element's own font size.
In some cases, we will have the line box a bit bigger than the content area which explain the gap.1
Now why setting the line-height to 1 doesn't fix the issue?
Simply because you set the line-height of the spans and not the line-height of their container which is not enough. The line-height of the container is still the default one 1.2 which will be considered since it's bigger than 1. In other words, the biggest line-height will win.
Here is some illustration to better understand:
line-height of the body is 2 and only a bigger line-height for span will have an effect:
body {
line-height:2
}
span {
background-color: red;
line-height: 1;
animation:change linear infinite 2s alternate;
}
#keyframes change {
to {line-height:3}
}
<span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span><br/><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span>
Setting line-height to body is enough as the span will inherit it:
body {
line-height:1; /*line-height is equal to content area*/
}
span {
background-color: red;
}
<span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span><br/><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span>
1 Worth to note that in some cases and for some particular font, you may not see any gap and you won't even need to set line-height to 1 because the content area may be bigger enough to cover the line box since the calculation of both value are independent.
Here is some examples
span {
background-color: red;
}
div {
margin:5px;
}
<div><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span><br/><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span>
</div>
<div style="font-family:cursive"><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span><br/><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span>
</div>
<div style="font-family:monospace"><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span><br/><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span>
</div>
<div style="font-family:sans-serif"><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span><br/><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span>
</div>
We have gaps only for the first and last example.
It's because the parent container's line height does not match the span's - line height affects the children so as span is inline, it is obeying the parent's line height
// From CSS spec:
// The height of the inline box encloses all glyphs and their half-leading on each side and is thus exactly 'line-height'. Boxes of child elements do not influence this height.
div {
line-height: 1;
}
span {
background-color: red;
line-height: 1;
}
<div>
<span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span><br/><span>Some span. As seen, background covers font plus half leading on top/bottom. There is still a gap, which is due to something else.</span>
</div>
Related
font-size sets the font height.
Font height is measured or specified by the height of a line, which is
the full height required to display the gamut of characters, including
those that dip below the line, like j, and raised elements (accents on
capitals, for instance) like Ê.
See How is font size calculated?
So a font with long descenders and ascenders will look smaller than a font with the same font-size with short descenders and ascenders.
If the line-height is set to 1em, the line-height is presumably the same as the font-size. So a font-size: 50px with a line-height: 1em will have a line-height of 50px.
So why then are links around text bigger (have a greater height) than the font and a line-height of 1em?
See https://jsfiddle.net/fkv4qunm/
This screen grab shows text with a line-height of 1em with a green background. And links with a pink background. The height of the links is greater than the line-height / font-size. (And there is no padding or margins on the links)
UPDATE
If the font-size is the complete height of all the fonts glyphs, ascenders and descenders, then what is determining the height of the links?
UPDATE 2
But from relooking at the screen grab the green line-height of 1em isn't containing the complete height of all the fonts glyphs – I think the 'j' would get cropped. This suggests that font-height isn't setting the height required to display all the characters (accents on capitals etc). But the size of the pink link is determined by the this height. So I'm now confused what font-size is measuring.
It is because anchor tag <a> is an inline element, inline elements size (width & height) is depended on the content size if you change your CSS code to this:
a {
display:block;
width:200px;
background-color: pink;
text-decoration: none;}
You will see the height of the <a> element will be the same as <li> element.
So, if you want to use an inline element inside of a block-level element you should change the size manually or use properties that can convert the type of the element.
In an inline formatting context, boxes are laid out horizontally, one
after the other, beginning at the top of a containing block.
Horizontal margins, borders, and padding are respected between these
boxes. The boxes may be aligned vertically in different ways: their
bottoms or tops may be aligned, or the baselines of text within them
may be aligned. The rectangular area that contains the boxes that form
a line is called a line box.
The height of a line box is determined by the rules given in the
section on line height calculations.
Many thanks to Alireza and FluffyKitten. I believe this is the answer:
Font-height is determined differently for different fonts. It is not always the height from the lowest glyph to the highest glyph (for example from the lowest part of the ascender 'p' to the highest part of an accent on a capital letter 'À').
https://www.w3.org/TR/CSS21/visudet.html#line-height
CSS assumes that every font has font metrics that specify a
characteristic height above the baseline and a depth below it. In this
section we use A to mean that height (for a given font at a given
size) and D the depth. We also define AD = A + D, the distance from
the top to the bottom. (See the note below for how to find A and D for
TrueType and OpenType fonts.) Note that these are metrics of the font
as a whole and need not correspond to the ascender and descender of
any individual glyph.
These two screen grabs show how two different fonts deal with font-size differently. First example is Elena. Second example is Times New Roman.
The first one has more vertical space above and below the letters. Whereas the font-size of the second font is closely determined by the lowest ascender and tallest descender.
Interesting point
If the line-height is set to 1 or 1em (making the line-height the same height as the font-size) then many letters bleed out of the font-size / line-height. Which is weird. See below. This is font-size 50px line-height: 50px and the descenders aren't included in the height of the font or line-height!!
However, the height of the inline <a> link continues to contain all the fonts glyphs. i.e. the height on an inline element is determined not by font-size (or line-height) but by the in-built font metrics.
It seems to me that there should be a consistent way to measure CSS font-size (from the lowest to highest glyph?). At the moment different fonts are using different in-built metrics and it's a mess.
width: 100vw;/* 100% of viewport width */
height: 100vh;/* 100% of viewport height*/
This CSS should give me the exact(100%) dimensions of the viewport. But it is apparently too large because it's causing an overflow on the page.
It is not padding, margin, or outline because I removed all of that.
note It also seems that it only "grows" bigger than the projected dimensions when I add two divs with these dimensions. (but it's always the case in jsfiddle)
http://jsfiddle.net/0psu7ys6/
Should I just consider it a bug and write a work around? Or am I missing something?
The viewport measurements are accurate. The problem lies in the fact that your div is an inline-block. The browser renders your inline-block element on a line box. The whitespace underneath your div comes from the baseline of this line box; it is the area where typographic descenders should go. This additional space, combined with your div, is what results in overflow.
If you remove the display: inline-block declaration so that your div is rendered as a block-level element, the scrollbars will go away and the div will fit the viewport exactly.
If you need this element to be an inline-block for some reason, setting vertical-align: top (or bottom or middle) seems to fix it.
There is another way to solve this
you should set the line-height of all the body in vh
Hello my fellow CSS enthusiasts. It's not usual that I can not answer a CSS question.
The bug happens in Chrome and IE11, Firefox renders it the same size but different clipping.
I have an inputfield and a div filled with text, they should have the same height and should scale with the parent font-size. The problem is that the inputfield is bigger than expected.
Demo: http://jsfiddle.net/7Lg70qc4/
The div behaves like I expected, its height is font-size + padding * 2, but the inputfield is bigger than that.
I can not set the height as em since the padding is fix, but the font-size is not.
Why is the input bigger than the div?
You have to define :first-line pseudo element for input to make your both elements same height.
input:first-line {
display: inline-block;
}
Here you can find more information why it works.
if the height of the input is auto, and its height is only comprised by the size of the font-size, i mean, without padding and border, letting the font-size be Xpx, the height of the input will always be slighter bigger,
the reason for that is to accommodate the "leg" of letters like "j" and "g".
Try setting font-size to Xpx, height to Xpx, and input "j" or "y" to the input,
there will be a minor crop.
In addition, put height:auto; font-size:Xpx; and line-height:2;
this time the height will be exactly 2 * Xpx, because with the line-height at 2, there will be room to take in the "legs" of the specific letters i mentioned above.
This subject, context, can also be comparable to another one that has to do with that thin space at the bottom of an image with display:inline; inside of a div, this is easier seen if both elements have a border like border:1px solid Crimson; for instance.
Thank you.
I noticed that line-height seems to affect blocks. Its strange to me, that i never noticed this disturbing effect before.
The problem is that it will affect blocks, even if they do not contain text at all.
I created a JSFiddle to demonstrate the issue. If you set line-height to 0, the grey area will no longer exceed that of the image inside the container.
Why is this happening and is there a clean way to prevent it?
The line-height value affects rendering even in the absence of text, since “'line-height' specifies the minimal height of line boxes within the element. The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element's font and line height properties.” (CSS 2.1 about line-height.)
But that’s really not the cause here. Images are by default rendered inline, meaning that they act as big (or maybe small) letters, sitting on the baseline of text. The details are complicated, but by setting line-height considerably smaller than font size, you put baselines closer to each other and the space vanishes.
Another way to remove the disturbing effect is to set display: block on the img element. Then the element will be formatted in a different way.
Yet another way is to set vertical-align: bottom on the img element.
I'm having trouble figuring out why inline elements ignore line-height in some browsers (Chrome and Firefox ignore it, but IE9 does not).
Here is an example:
<small style="line-height: 1; font-size: 26px;">Hello, World</small>
The expected result is for the element height to be 26px, however, it's being set to 31px. If I set the element's display to block, the height is correctly set to 26px.
Everything I read says it's supposed to be set to the line height, so I can't figure this one out. Here is what I read on W3C:
The height of each inline-level box in the line box is calculated. For replaced elements, inline-block elements, and inline-table elements, this is the height of their margin box; for inline boxes, this is their 'line-height'.
Source: http://www.w3.org/TR/CSS2/visudet.html#line-height
What webkit inspector shows (and what you measured in PhotoShop) is the content area's dimensions.
See http://www.w3.org/TR/CSS2/visudet.html#inline-non-replaced
The height of the content area [of inline elements] should be based on the font, but this specification does not specify how. A UA may, e.g., use the em-box or the maximum ascender and descender of the font...
Different browsers simply use a different approach here. See http://jsfiddle.net/ejqTD/1/ for an illustration of that. Note how webkit renders a higher content area, but line-height is still correct.
The content area exceeds the line box in this case, which is permitted: http://www.w3.org/TR/CSS2/visudet.html#leading
if the height specified by 'line-height' is less than the content height of contained boxes, backgrounds and colors of padding and borders may "bleed" into adjoining line boxes.
It's easy to see if you consider line-heights < 1: http://jsfiddle.net/KKMmK/