Подтвердить что ты не робот

Какова сделка с вертикальным выравниванием: базовый?

Я думал, что знаю свой подход к CSS, но мне сейчас нужно что-то объяснить кому-то, и я обнаружил, что не могу.

Мой вопрос в основном сводится к: почему vertical-align:baseline игнорируется, если в одной строке есть другие выравнивания?

Пример: если второй диапазон имеет vertical-align:bottom, первое вертикальное выравнивание по пролету игнорируется, если оно baseline; он ведет себя так, как будто он имеет также bottom.

span:first-child {vertical-align:baseline}
span:last-child {font-size:3em; vertical-align:bottom;}
<p>
  <span>one</span> <span>two</span>
</p>
4b9b3361

Ответ 1

Вертикально-Align

vertical-align используется для выравнивания элементов линейного уровня. Это элементы, свойство display оценивается как:

  • inline
  • inline-block
  • inline-table (не рассматривается в этом ответе)

Элементы линейного уровня располагаются рядом друг с другом в строках. Когда в текущей строке есть больше элементов, чем соответствующая, новая строка создается под ней. Все эти строки имеют так называемый line box, который охватывает все содержимое своей строки. Содержимое разного размера означает линейные ящики разной высоты.

На следующем рисунке верхняя и нижняя строки строк обозначены красными линиями. введите описание изображения здесь

Внутри этих строк строки свойство vertical-align отвечает за выравнивание отдельных элементов.


Baseline

Наиболее важная точка отсчета для выравнивания по вертикали является базовой вовлеченными элементами. В некоторых случаях также становится важным и верхний и нижний край закрывающего элемента.

Встроенные элементы

введите описание изображения здесь

Верхний и нижний край высоты линии обозначены красными линиями, высотой шрифта зелеными линиями и базовой линией синей линией.

Слева текст имеет высоту линии, установленную на ту же высоту, что и размер шрифта. Зеленая и красная линии рухнули в одну линию с каждой стороны.

В середине высота строки вдвое превышает размер шрифта.

Справа высота строки вдвое меньше размера шрифта.

Обратите внимание, что внешние строки встроенных элементов (красные линии) не имеют значения, если высота строки меньше высоты шрифта.

Элемент строкового блока

введите описание изображения здесь

Слева направо вы видите:

  • a inline-block элемент с in-flow content

  • a inline-block с в потоке и overflow: hidden

  • a inline-block элемент без in-flow (но область содержимого имеет высоту)

Границы поля обозначены красными линиями, граница - желтой, зеленым цветом и областью содержимого - синей. Базовая линия каждого элемента inline-block показана как синяя линия.

Базовая строка элементов inline-block зависит от того, содержит ли элемент in-flow. В случае:

  • in-flow content базовый элемент inline-block - это базовый уровень последнего элемента контента в нормальном потоке ( пример слева)

  • in-flow, но свойство overflow, оценивающее что-то отличное от видимого, базовым является нижний край поле поля (пример посередине)

  • no in-flow content базовый уровень - это опять же нижний край поля поля (пример справа )

Линейный блок

введите описание изображения здесь

Это, вероятно, самая запутанная часть при работе с vertical-align. Это означает, что базовая линия размещается там, где она должна выполняться для выполнения всех других условий, таких как vertical-align и минимизация высоты полевых коробок. Это свободный параметр в уравнении.

Поскольку базовая линия строк не является невидимой, она не может быть сразу же очевидна там, где она есть. Но вы можете сделать его видимым очень легко. Просто добавьте символ в начале строки в вопросах, например, "x" на рисунке. Если этот символ не выровнен каким-либо образом, он будет по умолчанию базироваться на базовой линии.

Вокруг базовой линии поле строки имеет то, что мы можем назвать его текстовым полем (зеленые линии на рисунке). Текстовое поле можно просто рассматривать как встроенный элемент внутри строки строки без какого-либо выравнивания. Его высота равна font-size его родительского элемента. Поэтому текстовое поле просто включает неформатированный текст строки строки. Поскольку это текстовое поле привязано к базовой линии, оно перемещается при перемещении базовой линии.


Отрывок

Если вы хотите поэкспериментировать с различными vertical-align и font-size здесь, у вас есть фрагмент, в котором вы можете попробовать его. Также доступен в JSFiddle.

let sl1 = document.getElementById('sl1');
let sl2 = document.getElementById('sl2');
let sl3 = document.getElementById('sl3');
let sl4 = document.getElementById('sl4');
let elm1 = document.getElementById('elm1');
let elm2 = document.getElementById('elm2');
let elm3 = document.getElementById('elm3');
let elm4 = document.getElementById('elm4');
let ip1 = document.getElementById('ip1');
let ip2 = document.getElementById('ip2');
let ip3 = document.getElementById('ip3');
let ip4 = document.getElementById('ip4');
let slArr = [sl1, sl2, sl3, sl4];
let elmArr = [elm1, elm2, elm3, elm4];
let ipArr = [ip1, ip2, ip3, ip4];
let valueArr = ['baseline', 'top', 'middle', 'bottom'];
for (let i = 0; i < slArr.length; i++) {
  slArr[i].addEventListener('change', (event) => {
    elmArr[i].style.verticalAlign = event.target.value;
    elmArr[i].innerHTML = event.target.value;
    addDiv();
  })
}
for (let i = 0; i < ipArr.length; i++) {
  ipArr[i].addEventListener('change', (event) => {
    elmArr[i].style.fontSize = event.target.value + 'em';
    addDiv();
  })
}

document.getElementById('btnRandom').addEventListener('click', () => {
  for (let i = 0; i < elmArr.length; i++) {
    let element = elmArr[i];
    let fontSize = Math.floor(Math.random() * 4 + 1);
    ipArr[i].value = fontSize;
    element.style.fontSize = fontSize + 'em';
    let styleIndex = Math.floor(Math.random() * 4);
    element.style.verticalAlign = valueArr[styleIndex];
    element.innerHTML = valueArr[styleIndex];
    slArr[i].selectedIndex = styleIndex;
  }
}, this);

function addDiv() {
  let view = document.getElementById('viewer');
  view.innerHTML = "";
  elmArr.forEach(function(element) {
    let div = document.createElement('div');
    div.appendChild(element.cloneNode());
    view.appendChild(div);
  }, this);
}
.header span {
  color: #000;
}

select {
  width: 100px;
}

#elms {
  border: solid 1px #000;
  margin-top: 20px;
  position: relative;
}

span {
  color: #FFF;
  font-size: 1em;
}

#elm1 {
  background-color: #300;
}

#elm2 {
  background-color: #6B0;
}

#elm3 {
  background-color: #90A;
}

#elm4 {
  background-color: #B00;
}

div {
  z-index: -1;
}

#div1 {
  width: 100%;
  height: 1px;
  background-color: #000;
  position: absolute;
  left: 0;
  top: 25%;
}

#div2 {
  width: 100%;
  height: 1px;
  background-color: #000;
  position: absolute;
  left: 0;
  top: 50%;
}

#div3 {
  width: 100%;
  height: 1px;
  background-color: #000;
  position: absolute;
  left: 0;
  top: 75%;
}
<div class="header"> <span style="width: 100px;display: block;float: left;margin-right: 20px;">vertical align</span> <span>font-size(em)</span> </div>
<div>

  <select name="sl1" id="sl1">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip1" />
  <br>
  <select name="sl2" id="sl2">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip2" />
  <br>
  <select name="sl3" id="sl3">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip3" />
  <br>
  <select name="sl4" id="sl4">
    <option value="baseline">baseline</option>
    <option value="top">top</option>
    <option value="middle">middle</option>
    <option value="bottom">bottom</option>
  </select>
  <input type="number" value="1" id="ip4" />
  <br>
  <button id="btnRandom" (onclick)="random()">Random</button>
</div>
<div id="elms">
  <span id="elm1">one</span>
  <span id="elm2">two</span>
  <span id="elm3">three</span>
  <span id="elm4">four</span>
  <div id="div1"></div>
  <div id="div2"></div>
  <div id="div3"></div>
</div>
<div id="viewer"></div>

Ответ 2

Вопрос в том, почему vertical-align: baseline; игнорируется. Ну, я не думаю, что это так. В первом фрагменте вы используете baseline и bottom, что явно дает разницу между двумя элементами <span>. Итак, что делает baseline? Ну baseline Выравнивает базовую линию элемента с базовым элементом родительского элемента. В приведенном ниже примере я скопировал и скорректировал некоторые части, чтобы дать разницу.

span.one {vertical-align:baseline}
span.two {vertical-align:middle;}
<p>
  <span class="one">one</span> <span class="two">two</span>
</p>