1

I know that the img element has a descender margin below it by default.

.box {
  border: 1px solid;
}
<div class="box">
  <img src="http://placehold.jp/150x150.png"> xyz
</div>

Question

I thought that the vertical-align property "aligns" elements at a specific position, so the height doesn't change. However, with the following code, when measuring the height when changing vertical-align, height was increased only forbaseline.

Why does it behave like "making a descender only when baseline"? Isn't a descender always present regardless of the value of the vertical-align property? There was no mention of this behavior in the vertical-align specification.

var align = ["top", "bottom", "baseline"];
var idx = 0;

function changeVerticalAlign() {
  document.querySelector(".box>img").style.verticalAlign = align[idx];
  document.querySelector("p").innerText = "height=" + getComputedStyle(document.querySelector(".box")).getPropertyValue("height") + ", vertical-align=" + getComputedStyle(document.querySelector(".box>img")).getPropertyValue("vertical-align");
  idx < 2 ? ++idx : idx = 0;
}

document.querySelector("button").addEventListener("DOMContentLoaded", changeVerticalAlign);
document.querySelector("button").addEventListener("click", changeVerticalAlign);
.box {
  border: 1px solid;
}
<div class="box">
  <img src="http://placehold.jp/150x150.png"> xyz
</div>
<p></p>
<button>change vertical-align to "bottom"</button>
  • vertical-align doesn't seem to make a lot of sense and it behaves different between browsers. Usually it only works relative to other inline elements next to it. Also consider that the line-height will be another variable affecting it. – Steve Tomlin Nov 23 '19 at 14:40
  • img stands on the baseline but also stands on a single line ( no matter the height, it won't span through other lines, i will only increase the height of the line where it stands) . If you align it to bottom, it will stand below the baseline ... where the text stands, if you set it on top, il will stand on the upper part . but the text will still be on the baseline. https://developer.mozilla.org/en-US/docs/Web/CSS/vertical-align – G-Cyrillus Nov 23 '19 at 15:40
  • I believe this extra space is reserved for text with a bottom tail like `j,y,q` .. – Thanh Trung Nov 23 '19 at 21:16

1 Answers1

1

I thought that the vertical-align property "aligns" elements at a specific position, so the height doesn't change.

This isn't true because the height is defined after the alignment is done and you can clearly notice this if you use text instead of image:

.box{
  border:1px solid;
  margin:5px;
}
<div class="box">
<span>some text</span>
<span>some text</span>
<span>some text</span>
</div>

<div class="box">
<span style="vertical-align:super">some text</span>
<span>some text</span>
<span>some text</span>
</div>
<div class="box">
<span style="vertical-align:super">some text</span>
<span>some text</span>
<span style="vertical-align:sub">some text</span>
</div>

From the specification:

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.

and also

A line box is always tall enough for all of the boxes it contains. However, it may be taller than the tallest box it contains (if, for example, boxes are aligned so that baselines line up). When the height of a box B is less than the height of the line box containing it, the vertical alignment of B within the line box is determined by the 'vertical-align' property.

Then in another part of the specification

As described in the section on inline formatting contexts, user agents flow inline-level boxes into a vertical stack of line boxes. The height of a line box is determined as follows:

  1. The height of each inline-level box in the line box is calculated. ....

  2. The inline-level boxes are aligned vertically according to their 'vertical-align' property. ....

  3. The line box height is the distance between the uppermost box top and the lowermost box bottom. (This includes the strut, as explained under 'line-height' below.)

So basically the height is defined bigger enough to hold the content after being aligned that's why the height may increase for some alignment.

If you add border to your elements you will notice the uppermost box top and the lowermost box bottom.

var align = ["top", "bottom", "baseline","super","sub","text-bottom","text-top"];
var idx = 0;

function changeVerticalAlign() {
  document.querySelector(".box>img").style.verticalAlign = align[idx];
  document.querySelector("p").innerText = "height=" + getComputedStyle(document.querySelector(".box")).getPropertyValue("height") + ", vertical-align=" + getComputedStyle(document.querySelector(".box>img")).getPropertyValue("vertical-align");
  idx < 6 ? ++idx : idx = 0;
}

document.querySelector("button").addEventListener("DOMContentLoaded", changeVerticalAlign);
document.querySelector("button").addEventListener("click", changeVerticalAlign);
.box {
  border: 1px solid;
}

.box> * {
  border:1px solid red;
}

p {
 margin:0;
}
<div class="box">
  <img src="http://placehold.jp/150x130.png"> <span>xyz</span>
</div>
<p></p>
<button>change vertical-align</button>
Temani Afif
  • 245,468
  • 26
  • 309
  • 415
  • Thank you for the detailed explanation. In the last example, why is `super` positioned below than `sub`? After the height and baseline are determined, the baseline doesn't change and shouldn't `super` be above `sub`? –  Nov 26 '19 at 14:34
  • super mean *Aligns the baseline of the element with the superscript-baseline of its parent.* so we take the baseline of the image (its bottom border) and we align it with superscript-baseline which is defined by the text `xyz` and is around the top of that text. So the bottom of the image should be at the same level of the top of the text `xyz`. After doing this we put both inside the div and get the needed height to contain them. – Temani Afif Nov 26 '19 at 14:41
  • @mayard sub is the opposite and will cosnider the subscript of the text so the bottom of the text. We align the bottom of the image with the bottom of the text and we will get a shorter height than super – Temani Afif Nov 26 '19 at 14:41