I'm having a strange issue, in this page there are two spans with different font-size.
The first span (with content "With empty title") has no explicit font size thus it inherits a font-size of 100%, in css inspector it becomes 12px. The second span with the word 'EMPTY', is initially hidden and is viewable by clicking on IT flag. It has this css applied
td {
.empty {
color: #bbb;
font-size: 0.8em;
text-transform: uppercase;
letter-spacing: 0.2em;
}
}
According to inspector, when "EMPTY" span is shown its computed size is 9px, however when the second span is shown there is a 1px flickering for the containing tr, on my browser tr height changes from 32px to 33px with the higher value when empty span is shown.
Why is this happening? How to prevent that without changing span.empty font-size?
Span is an inline element and behave in the flow like letters or inline-boxes does.
It stands on the baseline, beneath the baseline , you have a gap that remains for letters such as : g,j,p,q,y,....
Letters and inline-boxes stands on baseline wich is the defaut vertical-align for any inline element. reset it to vertical-align:top or bottom and the gap will be part of area used.
If you reduce line-height, the baseline is reduced, and element 'too high' will be go over it.
Hope it's clear enough, do not hesitate to edit this post to turn it into proper english , thks (erasable line)
Related
I thought 'what determines height of content-box' and thought line-height might.
It seems to be the case you can determine it for block elements with line-height.
<p style="background-color: grey; font-size: 16px; line-height: 2em;">Is line-height same as height of p tag?</p>
<div style="background-color: lightsalmon; font-size: 16px; line-height: 2em;">Is line-height same as height of div tag?</div>
<span style="background-color: aquamarine; font-size: 16px; line-height: 2em;">Is line-height same as height of span tag?</span>
Inline elements seems a different story. Would someone be able to elaborate?
For block elements its quite easy but you need to distinguish between two different cases. When we have an IFC (inline formatting context) or BFC (block formatting context). From the specification you can read
If 'height' is 'auto', the height depends on whether the element has any block-level children and whether it has padding or borders:
The element's height is the distance from its top content edge to the first applicable of the following:
the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child's bottom margin does not collapse with the element's bottom margin
the bottom border edge of the last in-flow child whose top margin doesn't collapse with the element's bottom margin
zero, otherwise
Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored, and relatively positioned boxes are considered without their offset)
If we consider an IFC then the line boxes will define our height exactly like your examples where in the div and p you have one line box defined by the line-height.
If we consider a BFC then the (2) and (3) apply. Here, you can see it as a recursive definition because having a BFC means we have other blocks inside and those blocks will follow the same rules (either BFC or IFC and so on). In addition, we consider the margin collapsing rules to get the final height.
If the block is empty then it's zero.
Of course, this consider the case of height:auto. If you explicitely set a height then it's trivial.
For inline elements you can refer to this part of the specification:
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. (The latter would ensure that glyphs with parts above or below the em-box still fall within the content area, but leads to differently sized boxes for different fonts; the former would ensure authors can control background styling relative to the 'line-height', but leads to glyphs painting outside their content area.)
Here is a bit tricky but the rule is simple: you cannot control or set the height of the content area. Only the font properties you will be using will define the final height.
You should also note that the content area is different from the line box.
The vertical padding, border and margin of an inline, non-replaced box start at the top and bottom of the content area, and has nothing to do with the 'line-height'. But only the 'line-height' is used when calculating the height of the line box.
<span style="background-color: aquamarine; font-size: 16px; line-height: 2em;">Is line-height same as height of span tag?</span>
<br>
<span style="background-color: aquamarine; font-size: 16px; line-height: 4em;">Is line-height same as height of span tag?</span>
<br>
<span style="background-color: aquamarine; font-size: 16px; line-height: 8em;">Is line-height same as height of span tag?</span>
If you increase the line-height you will clearly notice that the background won't cover a bigger area but only the line box will be bigger
Some related question to get more details and understand the difference between line box and content area:
Can specific text character change the line height?
Box Model for Inline Elements
Why is there space between line boxes, not due to half leading?
So line-height will indeed define the height of block element and not inline element since the block element height will depend on the height of the line boxes and the height of line boxes are defined with line-height1
Here is an example to show a block element having its height defined by the line box and the content area of the inline element inside will oveflow because they play no role in defining the line boxes:
p {
margin:50px;
font-size:35px;
border:1px solid red;
line-height:0;
}
span {
background:green;
line-height:10px;
}
<p>
<span>some text here and there</span>
</p>
<p>
<span style="font-family:cursive">some text here and there</span>
</p>
In both examples, we have a height equal to 12px for the p (10px of line-height + 2px of border) and our inline element is having a different height in each case because the font is not the same.
1: We should note that in practise it can be more complex and the value of line-height alone isn't enough.
If we read the specficiation we can see that:
On a block container element whose content is composed of inline-level elements, line-height specifies the minimal height of line boxes within the element.
Then
On a non-replaced inline element, line-height specifies the height that is used in the calculation of the line box height.
That's why in the last example I made the line-height of the block element to be 0 so only the line-height of the inline elements inside will define the final height of the linebox
Even the vertical alignment play a role here because if we have multiple elements not aligned the same way and with different line-height, finding the result will be more complex:
p {
margin:50px;
font-size:35px;
border:1px solid red;
line-height:0;
}
span {
background:green;
line-height:1;
}
<p>
<span>AB</span> <span >AB</span>
</p>
<p>
<span>AB</span> <span style="vertical-align:super">AB</span>
</p>
To find the height of a linebox you need to consider 3 factors:
The line-height of the block container (the IFC)
The line-height of the inline elements inside
the vertical alignment of inline elements
Let's not forget that line-height is inherited so if we don't set it explicitely we need to either consider the value of the parent element or the default one.
CSS2.1 Section 10.6.1 specifies:
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.
The vertical padding, border and margin of an inline, non-replaced box start at the top and bottom of the content area, and has nothing to do with the 'line-height'.
Then, the statements that seem contradictory follow in 10.8 Line height calculations:
The height of a line box is determined as follows:
The height of each inline-level box in the line box is calculated. For inline boxes, this is their 'line-height'....
And:
User agent must align glyphs in a non-replaced inline box to each other by their relevant baselines....
The height of the inline box encloses all glyphs and their half-leading on each side and is thus exactly 'line-height'
There is something I am not fully understanding here.
Is the height of inline-level boxes equal to the line-height property set on them (with the minimum being the line-height set on the parent block container element), OR is it just determined by the font height (and UA implementation)?
EDIT
Just to avoid confusion (since there are many posts about this):
I know that an inline-level element's content height is equal to the font it contains (and UA implementation)
I realize the spec does state that in 10.6.1, but in 10.8.1 it states that the height of an inline-level box is equal to its line-height
That seems contradictory to me
My purpose with this post is to discuss the wording in the spec, in order to fully understand what it means and how it ties in with reality
EDIT:
To avoid the "opinion based" close votes, I have changed the title. It is not my opinion that the spec is contradictory, and I am not asking for anyone else's opinion on whether it is contradictory either.
I realize it is not actually contradictory, I was just trying to understand why it is not, given its wording.
Is the height of inline-level boxes equal to the line-height property set on them (with the minimum being the line-height set on the parent block container element),
Yes it is.
OR is it just determined by the font height (and UA implementation)?
No it isn't
CSS is really about boxes, not elements, and you should try not to confuse the two.
So an inline element has associated with it a number of boxes. A content box, padding box, border box and margin box. It also has zero (if display:none), one, or multiple inline boxes. The content box, paddings, borders and margins may be divided among the inline boxes so that the inline content can be spread over more than one line.
The inline box's height is the content height adjusted by the leading. It's the leading that does the magic here. The leading is defined as the line-height of the element minus the content height of that inline box.
Simply rearranging that equation tells us that the height of the inline box depends only on the line-height and not on the content box (or padding, border, margin boxes).
Note that none of the above discusses the line box, which is a different thing again and not a direct property of inline elements or their boxes. The line box is constructed by arranging the inline boxes that occur on the same line such that their vertical alignments fit the rules computed for the elements, including the zero width inline box formed by the strut.
Each line box is bounded by the top of uppermost inline box and the bottom of the lowestmost inline box that that line box contains.
Digression: On why the height of the line box can surprise.
Suppose we have a simple case of a containing block which just contains one short inline element (i.e. short enough that it fits in a single line box). Also suppose that everything is aligned on the baseline. Let's say that the line-height is set on the containing box to 20px, and the inline element inherits that. Also suppose that the font-size (em-square) of the containing block is 16px, and that means that the font metrics compute to an ascent (above the baseline) of 14px and a descent (below the baseline) of 4px.
So the content area for the strut is (14px + 4px =) 18px high. The line-height is 20px, so there is 2px leading, 1px goes above the ascent, and 1px below the descent. So the line-height of the strut is made of 15px above the baseline and 5px below the baseline.
Now, suppose that the font-size of the inline element is set to 0.5em (i.e. half that of the containing block). The content area for the inline element will be an ascent of 7px and a descent of 2px. The line-height is still 20px, so the leading is 20px - (7px + 2px) = 11px, meaning that 5.5px goes above the ascent and 5.5px goes below the descent. This results in the line-height for the inline element is made of 12.5px above the baseline and 7.5px below the baseline.
Since the strut and the inline element are aligned vertically to their baselines, the top of the uppermost inline box (the strut) is 15px above the baseline and the bottom of the the lowermost inline box (the inline element) is 7.5px below the baseline, the actual height of the line box is not 20px but (15px + 7.5px =) 22.5px.
As I explained in this previous question (Why is there space between line boxes, not due to half leading?) we have the content area and the line box.
The content area is defined by the font properties and the UA (like described in your first quote) and the line box is defined by the line-height (like described in your second quote). Here is some example to show different height of content area based on different fonts and to illustrate the difference with the line box:
span {
border-left: 1em solid red;
background: rgba(255, 0, 0, 0.2);
}
.container>div {
margin-bottom: 5px;
border: 1px solid;
line-height: 30px;
}
.container>div:nth-of-type(1) span{
font-family: arial;
font-size: 25px;
}
.container>div:nth-of-type(2) span{
font-family: "open sans";
font-size: 20px;
}
.container>div:nth-of-type(3) span{
font-family: monospace;
font-size: 30px;
}
.container>div:nth-of-type(4) span{
font-family: cursive;
font-size: 22px;
}
<div class="container">
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
</div>
As you can see the background and border apply to the content area that is defined by the font-family and font-size. For all the cases, I set the line-height to be equal 30px thus all the line boxes are equal.
We can also notice that the border-left behave differently which indicates that indeed the height of the content area depends on the font and UA.
Here is the same example with some vertical padding/margin/border in order to illustrate how they affect the content area and has nothing to do with line-height:
span {
border-left: 1em solid red;
background: rgba(255, 0, 0, 0.2);
font-family: arial;
font-size: 25px;
}
.container>div {
margin-bottom: 5px;
border: 1px solid;
line-height: 40px;
}
.container>div:nth-of-type(1) span {
padding: 10px;
}
.container>div:nth-of-type(2) span {
border-bottom: 5px solid red;
}
.container>div:nth-of-type(3) span {
padding: 10px;
background-clip: content-box;/*I limit the background to content-box only*/
}
.container>div:nth-of-type(4) span {
margin: 20px;
}
<div class="container">
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
<div>
<span>Hello World</span>
</div>
</div>
If you look at this codepen https://codepen.io/anon/pen/pwQrmm
`h2 {
padding-top:16px;
padding-bottom:16px;
font-size: 16px;
}`
the h2 tag is set to have 16px in font-size but the height of its content box is 18px. Is there a way to set the height on the content box to match the font-size without manually setting its height with height: 16px. Also when the h2 tag becomes two lines, the content box should become 32px.
I tried searching this problem but couldn't find any answers. I'm sorry if this has been answered before.
You can set line-height to match font-size.
line-height: 16px;
When you write enough content (so there will be a second line), it'll become 32px.
However this isn't suggested. The content will become too crowded, the text will be too close to the text above (and below).
Line-height should be between 1,2x-1,5x of text-size.
Came across something very curious today I can't figure out the reason for.
For this HTML:
<div class="a"><div class="b"></div></div>
And CSS:
.a {
background: blue;
}
.b {
display:inline-block;
height: 30px;
width: 30px;
background: red;
}
I would expect the outer "a" div to be just as tall as is needed to contain "b", 30px tall. But when rendered "a" is 35px tall. There are 5 pixels of emptiness below "b". Why?
See http://jsfiddle.net/Pb2q9/
I've tried this on Chrome and Firefox and they both give the same output.
Curiously if you change "b" to be display:block that extra space at the bottom goes away. Can anyone explain why these two scenarios render differently? What is it about inline-block that dictates that 5px of space should exist?
EDIT:
Stranger still I found that if you change the HTML to
<div class="a"><div class="b">x</div></div>
Note the single "x" character in the b div the extra 5px at the bottom goes away!
The vertical white space you see is due to the line-height property in play. If you set line-height: 0 on the parent element, you can see that the spacing goes away - http://jsfiddle.net/Pb2q9/9/
When working with inline-block elements and yet wanting to achieve the layout behavior of block-level elements, remember to set both font-size and line-height to 0.
It is a normal behaviour of inline block elements. There is always white space.
If you want to remove white space of element, change fontsize of parent container to 0px
.a{font-size:0px;}
.b{font-size:16px;}
Fiddle
This is the HTML:
<div>
<p>
We bring you the latest in entertainment & information services, right on your phone. From the latest of Bollywood to the futuristic applications, get it all here!
View All
</p>
</div>
And this is the CSS....
div{width: 350px;}
a{
padding: 30px;
background: red;
margin: 20px;
border-radius: 12px;
background: red;
color: #fff;
font: bold 12px Arial, Helvetica, sans-serif;
text-decoration: none;
}
I know this could be solved by using display: inline-block; in .a. But I would like to know why this is overlapping the text? Should it not to go beyond the text?
DEMO1
DEMO2 now a is within a block level of p.
And also have a look at this DEMO. Img is also an inline element. And why this is not overlapping, this should also be overlapping, right?
<a> tag is inline level but while <img> tag is both inline and block level specially inline-block. So <a> tag is overlapping because of inline level which is corresponding to the text but <img> tag won't overlap because it is behaving inline-block. And you may know the difference between them.
Reference: Is <img> element block level or inline level?
An inline element could not be set its width and height and even doesn't work correctly the margin behaviour what actually should do. The margin is applied only to left or right side. Actually this is why, inline element here <a> tag would not set its width and height and remain in same line and seems to be overlapped when applied padding values.
The following picture makes you clear to understand about inline vs inline-block
View Live Demo
It's overlapping because the default behavior for an <a> tag is to fit with the text. If you want it to behave like a block, then set display: block.
The initial value for the display property on a link is display: inline. This means that it will try to fit in with the text and will accept horizontal margins, and padding on all sides, which is exactly why your link overlaps the text. In order for it to accept vertical margins (so it doesn't overlap), you need to set it to display:block or inline-block if you want it to align with the text still.
Padding doesn't work well with inline elements.
Ref:Inline Elements and Padding
This actually is explained in the W3C spec, although it was a bit tricky to find.
Horizontal margins, borders, and padding are respected between these boxes.
This tacitly implies that vertical margins/borders/padding are not respected. It goes on to say:
The height of a line box is determined by the rules given in the section on line height calculations
If you move the <a> into the contents of the box
We bring you the latest in entertainment View All
You can see this effect: http://jsfiddle.net/rHCNb/7/ -- the horizontal padding is respected, but not the vertical. The fact that it covers the other text has to do with z-indexing.
Add the below property in a.
position:relative;
float:left;
Working DEMO
TIPS:
Write background-color instead of the shorthand background when you
are not associating any other property.
If you write display:block then the block width will be equal to the parent
width, so always write width with display.
a{
padding: 30px;
background-color: red;
margin: 20px;
border-radius: 12px;
color: #fff;
font: bold 12px Arial, Helvetica, sans-serif;
text-decoration: none;
display: block;
width: 50px;
}
DEMO