How does line-height vertically center text? - html

I'm trying to understand why the line-height CSS property places the text vertically in the middle of this button:
.btn-order {
width: 220px;
height: 58px;
font-size: 24px;
padding: 0;
text-align: center;
vertical-align: middle;
line-height: 58px;
border: 1px solid black;
}
<div class="btn-order">Complete Order</div>

The line-height property is essentially setting a 29px (29 + 29 = 58) text line above and below your text, "Complete Order". If you added another line of text below this you will find it 58px below this text. You are putting line-height here only to center your text in the middle.
Here is a good slide show to help you understand this concept more... line-height
And here is an example using your code of what I am talking about: http://jsfiddle.net/YawDF/14/
By setting the line-height to 58px you are telling the browser to leave half this above and below the text line, creating a '58px' gap between each line and only a '29px' gap above the first line.
SIDE NOTE: Your use of vertical-align: middle is useless in the code you are showing. This can be taken out all together.

it is by design. If the CSS parser (i.e. the browser) doesn't know how tall is your text, he can't vertical align your text correctly.
Note there is a default value of line-height property.

line-height defines the height of text which make the paragraph looks neat so vertical-align works with respect to line-height when you increase the line height it increases the height and the you can more clearly see the effects of vertical-alignment of text
think this as a notebook which we children use to learn English -writing in nursery class

The text you generate is inside its own line box and vertical-align is used for placement inside that box. However, that box has nothing to do with the div you have wrapped around the text. You set the height of the div to 58px but that does not affect the height of the line text box. That is why you need line-height to match the height of the div.

Whenever a paragraph is inserted in a division the distance between the first line and the top border of the div is half of the line-height i.e if the default line- height is 1px then the distance between the first line and the top-border of the div is 0.5px.
If you have a division with height:58px the distance between the line and the top-border of the div is 29px and the distance between the line and the border of the bottom div would be=(total div height-distance b/w the line and the top border) which is 58px-29px=29px.This results in the line being vertically aligned at the center.
Also,there is no need to use vertical align:middle(for text containing not more than one line) if you're using line-height to centrally align the text.

Related

How can setting font-size on parent instead of directly on an element affect vertical aligning?

I have set up a simple markup to try to understand how vertical aligning works, but how font-size affect the alignment got me confused.
Example with font-size set on parent element: https://jsfiddle.net/wL5zjLnf/1/
section { font-size: 75px; }
Same example with font-size set directly on span: https://jsfiddle.net/tmk2hqon/
span { font-size: 75px; }
In the first example the red block seem to align its middle with text last line middle, while in the second example the red block middle seem to align with baseline.
It seems to me like some white-space between the elements mess up the aligning between the text and the block, as if there are three elements:
The text (75px)
A white-space (75px in first example, normal font sized in second example), which align baseline to baseline with the text
A red block, which align its middle to middle of the white-space
Is this expected behavior, or have I misinterpreted how it works? I would have assumed that both examples would give the same result, and the result would be the red block middle be aligned with the bottom of the last line of text.
By setting the parent's font-size, you implicitly set it's line-height as well, thus, the div will be in the middle.
When setting the span's font-size, the parent's line-height remains untouched and so the div is (apparently) at baseline level while it still is in the middle of the parent's line-height.

Baseline shifts for block-level element when no content inside

I'm working through a CSS problem at http://www.codecademy.com/courses/web-beginner-en-jNuXw/0/1?curriculum_id=50579fb998b470000202dc8b (actually, just helping a friend learn HTML/CSS) and came across a curious issue. If you erase the content in any of the <p> tags within a <div>, the div shifts upward. For example, delete the word 'Mom' without deleting the <p>. As best as I can figure out, this is because the element is set to vertical-align: baseline and for some reason the baseline is changing. I just can't figure out exactly why it's changing or what is causing it to change.
To be clear, I'm not asking for help to get the div's to align. That's simply a matter of setting their vertical-align to 'top'. I'm just trying to understand how the document flow is calculated. The specific question is: why does the empty div shift upwards?
DEMO: jsFiddle
UPDATE: Here is a new jsFiddle - http://jsfiddle.net/tonicboy/2DtTw/3/ which removes a lot of rules to boil the problem down to a simplified use case. From this, we can see that when a <p> tag has text in it, the baseline of the parent <div> is set at the baseline of the text. When you remove the text, the baseline of the parent <div> is set to the bottom of the <div>. Why is that?
HTML:
<div class="friend" id="best_friend"><p>Arthur</p></div>
<div class="friend"><p>Batmanuel</p></div>
<div class="friend"><p>Captain Liberty</p></div>
<div class="friend"><p>The City</p></div>
<div class="friend"><p>Justice</p></div>
<div class="family"><p></p></div>
<div class="family"><p>Dad</p></div>
<div class="family"><p>Bro</p></div>
<div class="family"><p>Sis</p></div>
<div class="family"><p>Rex</p></div>
<div class="enemy"><p>Baron Violent</p></div>
<div class="enemy"><p>The Breadmaster</p></div>
<div class="enemy"><p>The Deadly Nose</p></div>
<div class="enemy"><p>Dinosaur Neil</p></div>
<div class="enemy" id="archnemesis"><p>Chairface</p></div>
CSS:
div {
position: relative;
display: inline-block;
height: 100px;
width: 100px;
border-radius: 100%;
border: 2px solid black;
margin-left: 5px;
margin-top: 5px;
text-align: center;
}
div p {
position: relative;
margin-top: 40px;
font-size: 12px;
}
.friend {
border: 2px dashed green;
}
.family {
border: 2px dashed blue;
}
.enemy {
border: 2px dashed red;
}
#best_friend {
border: 4px solid #00C957;
}
#archnemesis {
border: 4px solid #cc0000;
}
I think I've mostly figured out the reason, after digging through W3C specs. Here are three key items from the spec which may explain this behavior:
"Line boxes that contain no text, no preserved white space, no inline elements with non-zero margins, padding, or borders, and no other in-flow content (such as images, inline blocks or inline tables), and do not end with a preserved newline must be treated as zero-height line boxes for the purposes of determining the positions of any elements inside of them, and must be treated as not existing for any other purpose."
When you delete the text, the <p> element is no longer in-flow.
"The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge."
Because there are no in-flow elements within the parent div, the baseline becomes the bottom margin.
Because the div's are set to display: inline-block, their default vertical alignment is 'baseline'
Because the other div's have in-flow elements (the <p> tags), their baseline is set to the text baseline.
And that is why the empty box's bottom margin aligns with the baseline of the <p> tags in the other div's.
The baseline of the element is shifting because the text inside the <p> determs the baseline height:
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.
source: http://www.w3.org/TR/CSS2/visuren.html#block-formatting
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
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.
source: http://www.w3.org/TR/CSS2/visudet.html#inline-box-height
So with this block being a inline-block and baseline is calculted based on the line-height which is calcuted by different font types. Because this <p> has no font/text the baseline will not be positioned.
place all the line-height: 0; and you will see that the one with no text/font doesn't react like the other does:
jsFiddle
So why are the other two elemets shifting that have text in them?
Well it's because the text excist of two lines of text. The margin of the text is bigger and uses more space, thus the baseline is pushed further

inline-block div with and without text not vertically aligned

I have two divs side by side. Both have the same size and display: inline-block. The only difference between the two is, the first one has some text and the second one is blank.
HTML:
<div>1</div>
<div></div>
CSS:
div {
display: inline-block;
border: 1px solid black;
width: 50px;
height: 50px;
}
The first div is lower than the second one.
I am aware of all the possible fixes, like adding some text or a to the second div. Adding vertical-align: top fixes this as well, of course.
What I want to know is, can someone explain, why a blank div has a different alignment than a div with some text in it?
JSFiddle
Inline-block boxes are, by default vertically aligned such that the baseline of the inline-block box aligns to the baseline of the line box in which it is rendered.
The baseline of an inline-block box with one line of text, is the baseline of that line. More generally, the baseline of an inline-block is the baseline of the last line of text that it contains. But that means that there is no baseline for an inline-block that contains no text.
In such a situation a fall back rule kicks in, and the bottom of the inline-block box is placed on the baseline of its line box.

Centered Variable Width Text with "dot dot dot" animation

http://pastebin.com/index/9M2rA8cx that has all my code.
You will notice that the two div's are centered in large.css. However, the text is being re-centered after each '.' is applied. If I put the span id="wait" outside the centered div, it will show up in the upper left corner. I don't need exact centering, but I can't use a absolute position for centering because the text changes.
Is there any way to append the "..." to the already centered text without it re-centering?
thanks!
Can't you just apply a fixed width style to the wait span, such as:
span.wait{
display: inline-block;
width: 20px;
}

HTML - Images Won't Align with Paragraph Text

When I have text beside an image and set them at the same point on the screen, why don't they align properly at the top of their containing div? The text appears to be a pixel or two lower than the image. Is it because of the hight of the text?
The site I am concerned with is below. I want the top of the head-shots to align with the top of the bios. Any ideas?
http://www.fiveholeforfood.com/the-team/
That's because of the line-height
The line- height is pushing it down a couple of px but if you want to keep that for ease of reading I'd give the paragraphs a -5px margin on the top
#content .single p {
line-height: 1.5em;
margin-bottom: 10px;
margin-top: -5px;
It rather seems to be font-related, perhaps the ascent line is pushing the font down.
If so, there's nothing that can be done about it except adjusting the margins & padding’s applied to your elements to move the text some pixels upwards. Changing fonts or maybe even font-sizes would ruin the effect though.