Why Is the Descender "Created" When Baseline Is Set to Vertical-Align

Why does the sibling line-box gets aligned vertically whenever there is no space for the first line-box to be vertically aligned?

Now, if i apply 'vertical-align' to the second line-box, it moves without a problem, since there is plenty of space. However, obviously there is no space for the first line-box to move up or down, but when i apply vertical-align to it, the second line-box moves almost as if the vertical align properties applies to it.

Your missunderstanding is in the plenty of space or let's say space in general. Vertical align will not consider the space you have in mind but will create that space.

let's first understand the definition

This property affects the vertical positioning inside a line box of the boxes generated by an inline-level element. ref

Then you can read the following rules:

The height of a line box is determined as follows:

  1. 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'.

  2. The inline-level boxes are aligned vertically according to their 'vertical-align' property. In case they are aligned 'top' or 'bottom', they must be aligned so as to minimize the line box height. If such boxes are tall enough, there are multiple solutions and CSS 2.1 does not define the position of the line box's baseline (i.e., the position of the strut, see below).

  3. The line box height is the distance between the uppermost box top and the lowermost box bottom.

We first start by defining the height of each element and we consider the margin box then we place all the elements and only at end the line box height is defined (the spaces you are talking about).

In your first example, both element have a default baseline alignment

Align the baseline of the box with the baseline of the parent box. If the box does not have a baseline, align the bottom margin edge with the parent's baseline.

so both will get aligned by their text and logically the margin of any of them will push the other.

A better example with different fonts:

.container {
border: 1px solid;
background:linear-gradient(blue,blue) 0 78px/100% 2px no-repeat;
}

.first {
display: inline-block;
font-size: 30px;
background-color: darkcyan;
border: 1px solid;
margin: 50px 0 0 0;
opacity:0.5;
}

.second {
display: inline-block;
border: 1px solid;
background-color: red;
font-size: 50px;
margin:0;
opacity:0.5;
}
<div class="container">
text outside

<div class="first">Lorem ipsum</div>

<p class="second">Lorem ipsum</p>

</div>

Why is this first in-line block anchored at the bottom?

By default if you set attribute into inline it will have vertical-align attribute as baseline it default behavior

but if you want to make it middle align or top you can change it into middle

see this code

* { margin: 0; padding: 0; }
#abc, #buttons { display: inline-block; vertical-align: middle; }
#wrapper { background-color: yellow; }
ul li { display: inline; }
<div id="wrapper">
<div id="abc">
abcd
</div>
<div id="buttons">
<ul>
<li><a href="/1"><img src="https://via.placeholder.com/50x50"></a></li>
<li><a href="/2"><img src="https://via.placeholder.com/50x50"></a></li>
<li><a href="/3"><img src="https://via.placeholder.com/50x50"></a></li>
<li><a href="/4"><img src="https://via.placeholder.com/50x50"></a></li>
</ul>
</div>
</div>

CSS & Typography: Uniform Vertical Alignment of Number Descenders

Use a different font. Arial puts all the bottoms of its numbers on the same baseline. So does Microsoft Sans Serif. So does Trebuchet. So, for that matter, does Times New Roman.

The fact is, numbers have different ascenders and descenders depending on the typeface. What typographers do is center the "body" of the number based on what they believe looks good, then go up or down from there. Usually that variation is on serif faces, but not always. You can't control it, in any case. BTW, the 3, 4, 5, 7 and 9 are the ones that usually have the descenders and the 6 and 8 usually have the ascenders.

Ignore Ascender and Descender when centering UILabel vertically?

Thanks, Abhinit, for your answer.

I was also looking for this so I would like to post here the exact constraints you need to apply to align texts to your liking.

This image from Wikipedia shows the different size sections of a font.

Sample Image

So, there are many ways to align a label depending on whether you want to align to the ascender height, the cap height, the x-height, baseline or descender height.

Let's say you have a label containing text in caps like "HELLO" and you want to align with viewAbove to cap height and align with viewBelow to baseline.

You would do:

let font = label.font
let ascenderDelta = font.ascender - font.capHeight

LayoutHelper()
.addViews([
"label":label, "viewAbove":viewAbove, "viewBelow":viewBelow
])
.withMetrics(["ascenderDelta":ascenderDelta])
.addConstraints([

// -- Here the constraints to align to cap height --
"X:label.top == viewAbove.bottom - ascenderDelta",
"X:label.baseline == viewBelow.top",

...other constraints...
])

Note: in the example I'm using my utility class LayoutHelper, but I hope the idea is clear.

About an "auto-aligning" label:

I will think about making an "intelligent" label that adjusts to the appropriate line depending on whether it contains descenders, ascenders, caps, etc.

You could do it using negative insets in drawTextInRect(like here but, for example, using insets = {-ascenderDelta, 0, font.descender, 0}). But that would crop any ascenders/descenders in case you had. I would prefer to align to caps without cropping any possible ascender.

Behaviour of vertical align

This wiki page gives some information on the vertical-align property:

https://www.w3.org/wiki/CSS/Properties/vertical-align

Here is a link to the CSS2 spec. Section 10.8 covers vertical-align:

https://www.w3.org/TR/CSS2/visudet.html

It looks to me like your HTML is displaying as it should. The vertical-align property assigned to an inline element controls that element's alignment, compared to the "baseline" of the line box that element is in.

The default value is "baseline." "Baseline" refers to the line that text appears to be sitting on. "Bottom" refers to the bottom of the box that contains the text (including descenders). So for your inline-blocks, baseline will be the same as bottom. So all of your inline boxes (of class floating-box and floating-box2) have the same vertical alignment (either through your CSS or through the default values). So all the inline boxes that appear on one line will have their bottom edges aligned.

Text within each inline-block is displaying as it should: Inline-blocks fill from top to bottom (just like any other block-level element). The vertical-align property does not control the alignment of text within the element that has the property; the vertical-align property controls the alignment of the element with the property, relative to its "container." The container is the "line box," which is is a CSS construct used to group all of the elements that the browser has placed on one line.

This article from Smashing Magazine may help: https://www.smashingmagazine.com/2012/12/css-baseline-the-good-the-bad-and-the-ugly/

CSS - Display text at descent instead of baseline?

What about vertical-align: bottom with line-height: 65%?

http://jsfiddle.net/y53uK/



Related Topics



Leave a reply



Submit