Недавно работал над проблемой стиля, из-за которой значки шрифтов не располагались вертикально по центру контейнера. Изначально думал, что просто css написан неправильно, но на самом деле все не так просто.
После некоторых поворотов я, наконец, обнаружил, что большая яма была вырыта из-за маленькой детали.
В течение всего процесса решения проблемы, с одной стороны, я повторил соответствующие базовые знания CSS, с другой стороны, я также дал мне несколько новых идей в отношении метода рассуждений о причине проблемы, так что это настоящим записано.
причина
Коллеги Сяов спросил меня вопрос о стиле: на странице он написал, значок шрифта, который должен был быть вертикально сосредоточен, стал выровнен с верхней частью контейнера. Я не знаю, где CSS неверно.
Как показано на рисунке (поскольку места аварии больше не существует, вот смоделированная сцена восстановления):
<div class='wrapper'>
<div class='inner'>
<i class="far fa-check-circle"></i>
</div>
</div>
css выглядит следующим образом:
.outer {
height: 60px;
line-height: 60px;
text-align: center;
color: white;
background-color: gray;
}
.inner {
display: inline-block;
font-size: 26px;
line-height: 1;
}
анализировать
Как видите, структура html очень проста, разделена на три части, а именно внешний контейнер.outer
, внутренний контейнер.inner
, и сам значок шрифта.
Внешний контейнер будетheight
Вline-height
То же самое установлено на 60 пикселей, что является классическим методом вертикального центрирования, однако результат не центрируется.
В чем проблема?
Итак, давайте сначала проанализируем принцип вертикального центрирования.
Центрировать по вертикали, используя высоту строки
Мы часто говорим,"Позволятьheight
равныйline-height
Можно добиться вертикального центрирования". На самом деле, это утверждение само по себе имеет много проблем.
Во-первых, для контейнера и встроенного элемента нет необходимости устанавливать обаheight
а такжеline-height
, просто установите контейнерline-height
, он может быть «центрирован по вертикали», как показано ниже:
<div class='wrapper'>
<span class='text'>中文文本</span>
</div>
.wrapper {
margin-bottom: 20px;
line-height: 100px;
color: white;
background-color: gray;
text-align: center;
}
Нет необходимости устанавливатьheight
хорошо понял, потому чтоline-height
Также возможно растянуть высоту контейнера, в это времяheight
ценностьauto
, который автоматически рассчитывается какline-height
ценность .
Почему существует "пустьheight
равныйline-height
", потому что самая ранняя практика основана на контейнере, высота которого была фиксированной. Чтобы центрировать текст в нем по вертикали, вам нужно установить контейнерline-height
равняется высоте. (Так что вы также можете напрямую удалить высоту и установить вместо нееline-height
)
Но здесь все еще есть проблема: на самом деле текст не совсем «вертикально центрирован», если быть точным, центрирована «область содержания» текста. Если вы установите цвет фона для текста, вы увидите область его содержимого:
Однако этот счастливчик
display: inline-block
элемент не существует. Как показано ниже:
<div class='wrapper'>
<span class='cube'></span>
</div>
.wrapper {
margin-bottom: 20px;
line-height: 100px;
color: white;
background-color: gray;
text-align: center;
}
.cube {
display: inline-block;
width: 50px;
height: 50px;
background-color: white;
}
установить вертикальное выравнивание
дляdisplay: inline-block
элемент, чтобы центрировать его по вертикали, мы обычно добавляем элементvertical-align: middle
Сделайте его вертикально центрированным, как показано на рисунке:
.wrapper {
margin-bottom: 20px;
line-height: 100px;
color: white;
background-color: gray;
text-align: center;
}
.cube {
display: inline-block;
width: 50px;
height: 50px;
background-color: white;
vertical-align: middle;
}
Каков принцип этого?
Обратитесь к w3c дляvertical-align
определение, когда установленоmiddle
Время:
Align the vertical midpoint of the box with the baseline of the parent box plus half the x-height of the parent.
перевести, то естьvertical-align: middle
Элемент будет выровнен по высоте базовой линии шрифта, используемого родительским элементом, плюс половина высоты x, и это значение на самом деле является высотой средней линии строчной буквы x, как показано на рисунке:
Это также может объяснить, что если вы не установите
vertical-align
,Прямо сейчасvertical-align: baseline
, почему элемент высокий:видеть
vertical-align: baseline
Определение:
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.
Итак, нижняя часть блока элементов выравнивается по базовой линии, которая является линией, где по умолчанию стоит буква x:
попробуй исправить
После завершения приведенного выше анализа вернитесь к исходной проблеме и обнаружите, что как внутренний контейнер,display: inline-block
элемент, не добавленныйvertical-align
атрибут, поэтому давайте попробуем добавить его:
.wrapper {
height: 60px;
line-height: 60px;
text-align: center;
color: white;
background-color: gray;
}
.inner {
display: inline-block;
font-size: 26px;
line-height: 1;
vertical-align: middle;
}
оказалось бесполезным. Это потому, что есть только один значок шрифта и нет ссылки? (Предыдущие китайские иероглифы состояли из нескольких слов)
Помня об этой идее, попробуйте добавить символ рядом со значком шрифта следующим образом:
Нужно ли писать скрытый символ рядом со значком, чтобы центрировать значок? Почему я раньше не сталкивался с этой проблемой подобным образом?
Итак, я попытался центрировать один символ на других страницах, и результат выглядит следующим образом:Почему на других страницах нет этой проблемы? Я снова открыл официальный документ определения w3c и нашел это описание в разделе высоты строки:
The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a "strut." (The name is inspired by TeX.).
И вvertical-align
Параграф гласит:
The following values only have meaning with respect to a parent inline element, or to the strut of a parent block container element.
Короче говоря, когда есть только один символ, браузер устанавливает перед текстом скрытый символ шириной 0 в качестве ссылки для выравнивания. Таким образом, нет необходимости вручную писать символ для выравнивания.
Теперь я запутался. . .
Ловушка DOCTYPE
Успокоившись, переходите к анализу. Выяснено, что на разных страницах структура html и css абсолютно одинаковы, но почему собственно стиль отличается?
В соответствии с приведенным выше теоретическим анализом установлено, что причина отсутствия центрирования заключается в том, что браузер не предоставляет такой возможности.strut
,Ссылка. И это не соответствует спецификации, определенной w3c.
Подумав об этом, я вдруг кое-что понял, сравнив страницы, и нашел единственное отличие:
Если DOCTYPE не установлен, страница перейдет в Quirks Mode, который является причудливым режимом.
Странный режим — это тип HTML-документа, разработанный для обеспечения нормального отображения устаревших страниц после появления спецификации css. Поскольку страница находится в режиме совместимости, значок не центрируется по вертикали, как определено спецификацией w3c.
добавить сейчас
<!DOCTYPE html>
, проблема окончательно решена.
Суммировать
Во-первых, для задачи вертикального центрирования используйтеline-height
Этого может и не быть, это нужно анализировать в зависимости от конкретной ситуации, и в основе анализа лежит базовое определение в w3c. Видно, что для основных понятий следует не только останавливаться на том этапе, которым можно пользоваться, но и нужно его полностью прочитать и досконально понять;
Во-вторых, для решения проблем, помимо объединения теоретических данных, это хороший способ попытаться провести сравнения. Посредством сравнения мы можем шаг за шагом устранять не относящиеся к делу причины и, наконец, выкопать проблему;
Наконец, в процессе расследования нельзя заранее ставить условия без доказательств. Потому что в этот раз одна из причин, по которой я долго боролся, именно потому, что я не посчитал, что есть проблемы со стандартом самой страницы, и трачу время на то, чтобы выяснить, есть ли еще неизвестные ошибки на пути использовать. Только позже, после того как они были исключены шаг за шагом, окончательная причина была заблокирована.