Align Block Elements on Top When Using Line-Height

Line height on inline-block div pushing down other inline-block siblings

The line-height is affecting all other siblings becuase they have display: inline-block applied to them, meaning they should be 'inline' with each other.

When setting a line-height it's increasing the line height for all elements sharing the same line; if you were to change your .item css display property to a block level element you will notice the line height will then not affect it's siblings as they don't share the same 'line'.

Vertically aligned item using line-height is slightly off middle

The culprit here is not so much the line-height, but rather the vertical-align: middle. It tries to align your box with the text that may hypothetically be inside the parent box. Where the inner box ends up depends on the font-size of that text. You can push the box further down by increasing the font-size of its parent:

.container{  height: 45px;   width: 100%;  line-height: 45px;   font-size: 45px;  background-color: red;   display: inline-block}
.item{ height: 15px; width: 40px; background-color: green; vertical-align: middle; display: inline-block;}
<div class="container">job  <div class="item">  </div></div>

Understand inline-element, vertical-align, line-box and line-height

Let's try to cover it step by step:

1.vertical-align works only for inline/inline-block element

Vertical-align applies to inline-level elements. That's currently: inline, inline-block, inline-table, inline-flex, inline-grid. Vertical-align is also used, but in a different way, for table cells.

2.vertical-align is based on line-height, not the height of its container!

Except for table cells, correct.

3.in a line-box, its line-height is the line-height of the inline box(in my opinion, its either inline-element or inline-block element) which has the highest line-height.

That's correct for simple cases but not for complex alignment ones. A better approximation goes something like this. Remove all the elements that are vertical-align:top and vertical-align:bottom. Align all the other elements so that their vertical alignment lines are level with one another. Call the box that contains them from the highest top of the aligned elements to the lowest bottom of the aligned elements the proto-line box. The actual height of the line box is then the maximum of the height of the proto-line box and all of the heights of the elements that are aligned top and bottom.


Now the relevant part of the specification for your question is this:

... for inline non-replaced elements, the box used for alignment is the box whose height is the 'line-height' (containing the box's glyphs and the half-leading on each side, see above). For all other elements, the box used for alignment is the margin box.

So for the span2, the green background area is the box's glyphs and above that are each glyph's upper half-leading, a value which is taken from the 100px line-height inherited from the container block element. It's the top of these half-leadings that aligns with the top of the line-box, not the top of the green background area.

On the other hand, the inline-block div aligns to the bottom of the line box, by the bottom of its bottom margin, and not by any half-leading.

Top vertical align in line-height (or vertical spacing without line-height)

You can add a negative top margin to your title.

Defining both your font size and the margin in em will allow you to achieve alignment regardless of what font size is inherited.

HTML/CSS: Vertical aligning span with vertical-align and line-height

Everything you said is right but you simply forget something which is inheritance. The span element is having the same line-height defined on the div that's why bottom has no effect in your case.

Sample Image

Reset the value to initial and it will work.

<div style="line-height: 50px; border: 1px solid yellow"><span style="border: 1px solid red; vertical-align: bottom;line-height:initial;">Some text</span></div>

Why does vertical-align: text-top make element go down?

Ref: https://www.w3.org/TR/CSS2/visudet.html#line-height

To understand this you need to first consider the definition of text-top:

The following values only have meaning with respect to a parent inline element, or to the strut of a parent block container element.

In the following definitions, for inline non-replaced elements, the box used for alignment is the box whose height is the 'line-height' (containing the box's glyphs and the half-leading on each side, see above).

Then

text-top

Align the top of the box with the top of the parent's content area

So we need to identify the top of the box and the top of the parent's content area

If we add some decorations, we can easily identify them

body {
font-family: sans-serif;
font-size: 30px;
}

p {
background: yellow;
line-height: 50px;
background:
linear-gradient(blue,blue) 0 7px/100% 2px no-repeat
yellow;
}

p span {
background:green;
}

.three {
vertical-align: text-top;
background:red;
}


.block {
display: inline-block;
width: 20px;
height: 20px;
background: pink;
border: 2px solid black;
vertical-align: text-top;
}
<div>
<p><span class="one">I'm</span> <span class="two">on the</span> <span class="three">yellow</span> <span>background</span> <span class="block"></span></p>
</div>

Align text to top of line

Without messing with the line-height:

div{
position: relative;
font-size: 16px;
line-height: 24px;
width: 25px;
padding: 0px 0px 0px 10px;
}
div:before {
position: absolute;
content: '';
top: 6px;
left: 0px;
bottom: 6px;
width: 0px;
border-left: 1px solid black;
}

The values top and bottom should equal (line-height - font-size) / 2 but due to different character height will need some manual nudging.

Demo: http://jsfiddle.net/NcbB7/



Related Topics



Leave a reply



Submit