vertical-align в CSS


Содержание

Центрирование горизонтальное и вертикальное

В CSS есть всего несколько техник центрирования элементов. Если их знать, то большинство задач решаются просто.

Горизонтальное

text-align

Для центрирования инлайновых элементов – достаточно поставить родителю text-align: center :

Для центрирования блока это уже не подойдёт, свойство просто не подействует. Например:

margin: auto

Блок по горизонтали центрируется margin: auto :

В отличие от width/height , значение auto для margin само не появляется. Обычно margin равно конкретной величине для элемента, например 0 для DIV . Нужно поставить его явно.

Значение margin-left:auto/margin-right:auto заставляет браузер выделять под margin всё доступное сбоку пространство. А если и то и другое auto , то слева и справа будет одинаковый отступ, таким образом элемент окажется в середине. Детали вычислений описаны в разделе спецификации Calculating widths and margins.

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

Для горизонтального центрирования всё просто. Вертикальное же изначально не было предусмотрено в спецификации CSS и по сей день вызывает ряд проблем.

Есть три основных решения.

position:absolute + margin

Центрируемый элемент позиционируем абсолютно и опускаем до середины по вертикали при помощи top:50% :

Это, конечно, не совсем центр. По центру находится верхняя граница. Нужно ещё приподнять элемент на половину своей высоты.

Высота центрируемого элемента должна быть известна. Родитель может иметь любую высоту.

Если мы знаем, что это ровно одна строка, то её высота равна line-height .

Приподнимем элемент на пол-высоты при помощи margin-top :

При стандартных настройках браузера высота строки line-height: 1.25 , если поделить на два 1.25em / 2 = 0.625em .

Конечно, высота может быть и другой, главное чтобы мы её знали заранее.

Можно аналогично центрировать и по горизонтали, если известен горизонтальный размер, при помощи left:50% и отрицательного margin-left .

Одна строка: line-height

Вертикально отцентрировать одну строку в элементе с известной высотой height можно, указав эту высоту в свойстве line-height :

Это работает, но лишь до тех пор, пока строка одна, а если содержимое вдруг переносится на другую строку, то начинает выглядеть довольно уродливо.

Таблица с vertical-align

У свойства vertical-align, которое управляет вертикальным расположением элемента, есть два режима работы.

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

Его возможные значения:

baseline Значение по умолчанию. middle , top , bottom Располагать содержимое посередине, вверху, внизу ячейки.

Например, ниже есть таблица со всеми 3-мя значениями:

Обратим внимание, что в ячейке с vertical-align: middle содержимое находится по центру. Таким образом, можно обернуть нужный элемент в таблицу размера width:100%;height:100% с одной ячейкой, у которой указать vertical-align:middle , и он будет отцентрирован.

Но мы рассмотрим более красивый способ, который поддерживается во всех современных браузерах, и в IE8+. В них не обязательно делать таблицу, так как доступно значение display:table-cell . Для элемента с таким display используются те же алгоритмы вычисления ширины и центрирования, что и в TD . И, в том числе, работает vertical-align :

Этот способ замечателен тем, что он не требует знания высоты элементов.

Однако у него есть особенность. Вместе с vertical-align родительский блок получает табличный алгоритм вычисления ширины и начинает подстраиваться под содержимое. Это не всегда желательно.

Чтобы его растянуть, нужно указать width явно, например: 300px :

Можно и в процентах, но в примере выше они не сработают, потому что структура таблицы «сломана» – ячейка есть, а собственно таблицы-то нет.

Это можно починить, завернув «псевдоячейку» в элемент с display:table , которому и поставим ширину:

Если дополнительно нужно горизонтальное центрирование – оно обеспечивается другими средствами, например margin: 0 auto для блочных элементов или text-align:center на родителе – для других.

Центрирование в строке с vertical-align

Для инлайновых элементов ( display:inline/inline-block ), включая картинки, свойство vertical-align центрирует сам инлайн-элемент в окружающем его тексте.

В этом случае набор значений несколько другой:

Это можно использовать и для центрирования, если высота родителя известна, а центрируемого элемента – нет.

Допустим, высота внешнего элемента 120px . Укажем её в свойстве line-height :

Работает во всех браузерах и IE8+.

Свойство line-height наследуется, поэтому надо знать «правильную» высоту строки и переопределять её для inner .

Центрирование с vertical-align без таблиц

Если центрирование должно работать для любой высоты родителя и центрируемого элемента, то обычно используют таблицы или display:table-cell с vertical-align .

Если центрируются не-блочные элементы, например inline или inline-block , то vertical-align может решить задачу без всяких таблиц. Правда, понадобится вспомогательный элемент (можно через :before ).

  • Перед центрируемым элементом помещается вспомогательный инлайн-блок before , занимающий всю возможную высоту.
  • Центрируемый блок выровнен по его середине.

Для всех современных браузеров и IE8 можно добавить вспомогательный элемент через :before :

В пример выше добавлено также горизонтальное центрирование text-align: center . Но вы можете видеть, что на самом деле внутренний элемент не центрирован горизонтально, он немного сдвинут вправо.

Это происходит потому, что центрируется весь текст, а перед inner находится пробел, который занимает место.

    Убрать лишний пробел между div и началом inner , будет

Центрирование с использованием модели flexbox

Данный метод поддерживается всеми современными браузерами.

  • Не требуется знания высоты центрируемого элемента.
  • CSS чистый, короткий и не требует дополнительных элементов.
  • Не поддерживается IE9-, IE10 поддерживает предыдущую версию flexbox.

Итого

Обобщим решения, которые обсуждались в этой статье.

Для горизонтального центрирования:

  • text-align: center – центрирует инлайн-элементы в блоке.
  • margin: 0 auto – центрирует блок внутри родителя. У блока должна быть указана ширина.

Для вертикального центрирования одного блока внутри другого:

Если размер центрируемого элемента известен, а родителя – нет

Родителю position:relative , потомку position:absolute; top:50% и margin-top:- . Аналогично можно отцентрировать и по горизонтали.

Если нужно отцентрировать одну строку в блоке, высота которого известна

Поставить блоку line-height: . Нужны конкретные единицы высоты ( px , em …). Значение line-height:100% не будет работать, т.к. проценты берутся не от высоты блока, а от текущей line-height .

Высота родителя известна, а центрируемого элемента – нет.

Поставить line-height родителю во всю его высоту, а потомку поставить display:inline-block .

Высота обоих элементов неизвестна.

  1. Сделать элемент-родитель ячейкой таблицы при помощи display:table-cell (IE8) или реальной таблицы, и поставить ему vertical-align:middle . Отлично работает, но мы имеем дело с таблицей вместо обычного блока.
  1. Решение со вспомогательным элементом outer:before и инлайн-блоками. Вполне универсально и не создаёт таблицу.
  2. Решение с использованием flexbox.

vertical-align

Свойство vertical-align выравнивает элемент по вертикали отностильно окружающего текста или ячейки таблицы.

Для этого свойства важно помнить что:

  1. Свойство vertical-align применяется только к строчным элементам, или к строчно-блочным.
  2. Свойство vertical-align применяется к элементу, а не к его содержимому. Исключением являются случаи, когда это свойство применяется к ячейке таблицы.
  3. Когда это свойство применяется к ячейке таблицы, вертикально выравнивается содержимое ячейки, а не она сама.

Краткая информация

Свойство vertical-align: краткая информация
Значение по умолчанию baseline
Применяется К строчным и строчно-блочным элементам или ячейкам таблицы.
Наследуется Нет
Ссылка на спецификацию http://www.w3.org/TR/CSS21/visudet.html#propdef-vertical-align

Значения

Свойство vertical-align: значения
Значение Пример
baseline Базовая линия элемента совпадает с базовой линией родителя. Если родительский элемент не имеет базовой линии, то за неё принимается нижняя граница элемента.
bottom Выравнивает нижнюю границу элемента по нижней границе того элемента из строки, чья нижняя граница является самой низкой.
middle Выравнивает середину элемента по базовой линии элемента родителя.
sub Элемент отображается в виде нижнего индекса. На размер шрифта это значение не влияет.
super Элемент отображается в виде верхнего индекса. На размер шрифта это значение не влияет.
text-top Верхняя граница элемента выравнивается по самому высокому текстовому элементу текущей строки.
text-bottom Нижняя граница элемента выравнивается по самому нижнему краю текущей строки.
top Выравнивание верхней границы элемента по верхней границе самого высокого элемента строки.
inherit Значение наследуется от родителя.

Примеры

Давайте рассмотрим работу свойства vertical-align на нескольких примерах. Присвоим разные значения строчно-блочным элементам.

Для начала посмотрим работу этого свойства со значением baseline , используемым по умолчанию.

В примере создадим контейнер #container , внутри которого будем размещать наши строчно-блочные элементы #small и #big для экспериментов.

Вот результат работы этого кода:

Границы строчно-блочных элементов выделены красным цветом.

Мы видим, что наш текст отформатирован так, как будто он написан в тетрадке. Я специально выбрал символ строчная буква «у», она пишется с «хвостиком» ниже базовой линии.

Теперь поменяем значение свойства vertical-align на bottom :

Теперь нижние границы всех элементов выстроены в одну линию. Тут стоит обратить внимание на очевидный факт: строчно-блочные элементы выравниваются относительно строки, а не контейнера, а которому принадлежат. По другому это свойство будет вести себя в таблицах, но об этом поговорим позже.

Далее, поменяем значение свойства vertical-align на middle :

Теперь элементы в строке выровнены по центру.

Ну и последний пример, поменяем значение свойства vertical-align на top :

Имеем ожидаемый результат: строчно-блочные элементы размещены по верхнему краю строки.

Задача посложнее

Давайте теперь решим такую задачу: нам нужно в этом контейнере разместить текст по центру вертикали контейнера #container .

Ключ решения такой задачи следующий: нужно высоту строки сделать равной высоте блока. Высоту строки можно задать с помощью свойства line-height .

Высота нашего контейнера height : 100px . Только тут нужно учитывать то, что у нашего контейнера уже есть padding : 2px , который накладывается с margin : 2px строчно-блочных элементов, но у них есть border : 1px , который также нужно учесть.

То есть, корректная высота строки line-height будет равна: height : 100px минус ( padding : 2px + border : 1px ) *2 (так как нужно учитывать верх и них) = 94px .

Другие значение: проценты, пикселы и т.д.

Для свойства vertical-align в качестве значения можно использоывать проценты. При этом отсчет ведется от значения свойства line-height , при этом 0% соответствует значению baseline .

Если использовать пикселы или другие доступные в CSS единицы, то положительное число смещает элемент вверх относительно базовой линии, отрицательное число опускает элемент вниз.

Работа с ячейками таблицы

Когда свойство vertical-align применяется к ячейке таблицы, то выравнивается содержимое ячейки, а не она сама.

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

Vertical-align в CSS

В CSS есть такое свойство, называется vertical align. И я думаю, вы не первый раз слышите об этом. Простейшее использование выглядит так:

Обратите внимание, что в этом случае использования, свойство применяется к элементу img. Поскольку изображения являются строчными элементами, то располагаются они в строке, как если бы они были простым текстом. Но что именно значит «располагаются в строке»? Вот именно здесь появляется понятие «вертикальное выравнивание».

Атрибут может принимать следующие значения: baseline, sub, super, top, text-top, middle, bottom, text-bottom, length, или значение в процентах..

Некоторые пытаются использовать это свойство для элементов блочного уровня и, естественно, не получают ожидаемого результата. То есть если вы разместите один div внутри другого и захотите вертикально центрировать его, то vertical-align вам не поможет. Как поступать в таком случае я расскажу в отдельной статье.

Baseline

Значением по умолчанию для vertical-align является baseline. Изображения будут находиться на одной линии с текстом. Обратите внимание, что выступающие элементы символов, выступают за базовую линию. Картинки не выравниваются по этим выступам, поскольку это не базовая линия.

Middle

Возможно, наиболее используемое значение для vertical-align — это «middle» для изображений-иконок. Результат получается довольно кросс-браузерным.

Браузер центрирует высоту текста в пикселях с высотой картинки, опять же, в пикселях:

Необходимо запомнить, если изображение больше чем текущий размер шрифта и высота строки, то оно будет «вытолкнуто» вниз, если это необхоимо.

Text-bottom

Отличается от baseline тем, что изображение выравнивается по нижней линии текста (не базовая линия, а по линии выступающих частей текста). Картинки могут быть выравнены по этой линии таким образом:

Text-top

Противоположностью значения text-bottom является text-top. Самая высокая точка строки текста при текущем размере шрифта. Таким образом вы можете выровнять изображение по этой линии. Обратите внимание, что в примере используется шрифт Georgia, у которого, возможно, есть элементы выше, чем на рисунке. Поэтому вы видите небольшой отступ.

Top и Bottom

Top и Bottom работаю подобно свойствам text-top и text-bottom, но при выравнивании расчёт происходит не по высоте текущего текста, а по высоте максимального элемента в строке (например другой картинки). И при расопложении учитывается именно его верх (или низ).

Sub и Super

Эти значения используются для верхних (superscript) и нижних (subscript) индексов. При использовании этих значений, элементы выстраиваются таким образом:

Vertical Align on Table Cells

В отличии от картинок, у таблиц по умолчанию используется выравнивание по центру (middle).

Если вы хотите выровнять текст по верху или низу ячейки, используйте значения top и bottom для vertical-alignment:

Для вертикального выравнивания в ячейках таблицы, лучше всего использовать только эти значения (top, middle, bottom). Использование других значений может привести к непредсказуемым результатам в разных броузерах. Например, text-bottom прижимает текст к низу в IE 6, а в Safari 4 — к верху. Установка значения sub выравнивает по центру в IE 6, а в Safari 4, опять же, по верхней линии.

Vertical Align и элементы Inline-Block

Изображения, которые технически являются элементами строчного уровня, больше похожи по поведению на элементы с поведением inline-block, потому что можете им устанавливать размеры.

Inline-block-элементы, при вертикальном выравнивании, ведут себя точно так же, как картинки. Однако, стоит помнить, что не все броузеры обрабатывают inline-block-элементы одинаково, и поэтому vertical-align может не оправдать ваших ожиданий. Хотя это уже другая история.

Атрибут «valign»

Иногда вы можете встретить атрибут «valign» для вертикального выравнивания в ячейках таблицы (например, . Стоит отметить, что этот атрибут является устаревшим и не должен использоваться. Да и зачем, если вы можете добиться желаемого, используя CSS.

Vertical-align в CSS

Классная статья. Спасибо за перевод. Давно хотелось с этим разобраться.

Алексей

Элемент (черная рамка) состоит из контейнеров строк (белые рамки), состоящих из строчных элементов (сплошные рамки) и анонимных элементов строки (белые рамки)

Видимо ошибка: и анонимных элементов строки (пунктирные рамки).

SelenIT (Автор записи)

Спасибо! Моя промашка(. Исправлено!

Владимир

Спасибо за статью, многое стало понятнее!

Алексей

По переводу: мне кажется в некоторых случаях переводите слишком буквально. По-русски фраза «В этом большая разница» будет звучать: «И в этом большая разница!» (хотя вообще, наверное, в зависимости от контекста). Аналогично, фраза «И в этом большая разница!» на английском будет переведена, вероятно, без And. И таких моментов может быть много (я не знаю, удачный ли я привёл пример). Пусть перевод будет чуть более вольный, но, при этом, не звучит нигде натянуто, если для смысла это не критично. Авторы привыкли говорить так, как принято там, где они общаются, но мысли их могут быть понятны и нам :-) Если типичные для слушателя обороты речи, смогут более естественно передать ОРИГИНАЛЬНОСТЬ АВТОРСКОЙ МЫСЛИ, то может лучше использовать их?
Напоминаю, что высота контейнера строки рассчитывается от самой высокой до самой низкой точки его потомков.
Тут ещё хорошо бы напомнить, что область содержимого находится ПОСЕРЕДИНЕ line-height. При первом прочтении это не очевидно :-)
А вообще статья просто превосходна! Очень порадовала.
Странно, а почему Вы не даёте ссылку на свою книжку? Скромничаете?
По-сути в этой статье разъяснены некоторые моменты, которые затрагиваются в Вашей книжке. Статья здорово её дополняет, развевает туман в некоторых местах, например вносит практически полную ясность в базовое понятие «высота строки», на котором многое строится и не понимая которое, очень сложно воспринять те или иные аспекты строчного форматирования и разобраться как же именно они работают…
ЗЫ: По поводу рассчётов в CSS тоже тут недавно вёл рассчёты (в Маткаде), чтоб понять откуда-докуда заливать градиент у траснформируемой фигуры. Не то, что это плохо само по себе, но всё же, в некоторых аспектах, пожалуй, несколько запутанно. Думаю, что некоторые дополнительные возможности (не упрощения!) сделали бы реализацию тех или иных вполне интуитивных задач более простой и надёжной. Вот как раз:
ЗЫЗЫ: Собираетесь ли Вы вносить в спецификацию, какие-то свои предложения, по строчному форматированию? :-)

SelenIT (Автор записи)

в некоторых случаях переводите слишком буквально

Возможно. Слегка торопился успеть опубликовать перевод до намечавшегося на работе аврала, пытался сэкономить время на втором проходе вычитки… эх, зря. Сейчас вот еще немного подправил пару мест. Возможно, сложности добавляет еще то, что для самого автора английский не родной, в нескольких местах понять его мысль помогла лишь французская версия статьи:)

ещё хорошо бы напомнить, что область содержимого находится ПОСЕРЕДИНЕ line-height.

Не хотелось добавлять слишком много отсебятины переводчика. Чтобы не пришлось в итоге перечислять всё, из чего складывается расстояние от базовой линии до нижнего края «виртуальной области» (удачный авторский термин, кстати). Но спасибо за замечание, возможно, кому-то этот комментарий поможет быстрее разобраться!


По-сути в этой статье разъяснены некоторые моменты, которые затрагиваются в Вашей книжке. Статья здорово её дополняет

Именно поэтому я так спешил ее перевести:). Свежий взгляд на знакомую тему, причем за это время браузеры избавились от многих разночтений, более-менее удалось «разрулить» путаницу с переводом многозначных терминов типа «inline», и т.п.

Предложений в спеку пока не вносил, но поддерживал некоторые чужие, например, сделать высоту заглавных букв новой единицей измерения (по аналогии с существующей ex ).

Алексей

Слегка торопился успеть опубликовать перевод

Да в целом-то нормально, я просто обратил внимание, что когда читаешь переводные статьи то иногда сталкиваешь с такой конструкцией фраз, что понимаешь, что автор — англоговорящий (в данном случае даже француз %)

до намечавшегося на работе аврала

Эх, где взять хвалёную в Вашей статье Путь верстальщика «программистскую мудрость», чтоб знать: когда капать, а когда не капать :-))

Чтобы не пришлось в итоге перечислять всё, из чего складывается расстояние от базовой линии до нижнего края «виртуальной области»
«виртуальной области» (удачный авторский термин, кстати).
Насколько мне известно, слово «виртуальный» в английском языке имеет немного более ёмкое значение чем в русском. Если в русском это что-то вроде «воображаемый», «не существующий» «предполагаемый в уме» ну в лучшем случае «где-то в параллельном мире», то в английском, это что-то вроде «непроявленное». То есть, в явном виде может и не существующее, но о чём-то говорящее… Вот и line-height, с одной стороны его увидеть не получается, но его параметры дают другим значениям найти своё конкретное и вполне законное место в строке.

спасибо за замечание, возможно, кому-то этот комментарий поможет быстрее разобраться!

С этой целью, в основном и написал, об этом сказано в начале статьи, а в примере, обратили внимание, на довольно очевидную вещь, что мол строка складывается от самого высокого места, до самого низкого, а почему виртуальная область распределена именно так — не написано.

поддерживал некоторые чужие, например, сделать высоту заглавных букв

Да, большая тема…
Спасибо!

Алексей

vertical-align: text-top / text-bottom выравнивают по верху или низу области содержимого
Но будьте осторожны: во всех случаях оно выравнивает виртуальную область, высота которой невидима
Так что к чему выравнивается? Область содержимого к области содержимого или виртуальную область, выравниваемого элемента, к области содержимого strut? (или даже не strut?! а, скажем, самого высокого элемента в строке? врят ли, ну а вдруг? :-) )

SelenIT (Автор записи)

Насколько я понимаю, виртуальную область выравниваемого элемента к родительской области содержимого (если у выравниваемого элемента есть инлайновый родитель — то к области содержимого этого родителя, если нет — к области содержимого strut родительского блока).

Алексей

Ну да, так, примерно и понял…

Алексей

Учтите, что этот тест только для демонстрационных целей. Полагаться на это нельзя. Причин много:
метрики шрифтов-то постоянны, но вот браузерные вычисления — не очень ¯⁠\⁠(ツ)⁠/⁠¯
если шрифт не загрузился, у резервного шрифта скорее всего другие метрики, а работать с несколькими разными значениями быстро станет практически нереально.

Интересную ссылку приводит автор (span-область наск. я понимаю, Content-Area). Посмотрев значения шрифтов в указанной автором программе, оказалось, что поймать вертикальный ритм не так просто. И у меня получилось сделать это в Хроме для размера шрифта, при котором размер его заглавных букв составил 200px (А вот при размере заглавных 120px ритм съезжал). Вот видимо почему — браузер округляет значения, в результате точное значение — не то значение, которое используется по факту. Кстати, в этой таблице нет размера заглавных, но наверняка используются тоже какие-то целые значения.
Интересно что в Хроме всё работает для двух шрифтов, при этом ощущение, что для Times шрифтовая площадка, всё же сдвинута на 1px вверх, и только для Arial всё нормально. При этом в Лисе всё постепенно съезжает…

Чтобы не пришлось в итоге перечислять всё, из чего складывается расстояние от базовой линии до нижнего края «виртуальной области»

можно воспользоваться вот этой шпаргалкой (изображение кликабельно). Но, что бросается в глаза: некоторые отличия литерных площадок от виртуальных. Во-первых em-квадрат и line-height теперь разные вещи, одно строится в пространстве другого(или другое строится в координатах первого), но теперь это разные понятия связанные друг с другом лишь относительно.
И второе, следующее из первого, line-height теперь не меряется как расстояние между базовыми линиями, а, насколько я понимаю, от верхнего half-leading до нижнего (или наоборот, без разницы). При этом сам leading стал понятием условным, лидинги напрямую друг с другом не контактируют, а контактируют line-box (хотя понятно, что самая верхняя и самая нижняя точка line-box это чей-то half-leading, причём, я так понимаю, это верно, даже если в строке есть замещаемые элементы или inline-block, поскольку, из чего бы они не состояли, они лежат в области содержимого, а только халф-лидинги шрифтов образуют межстрочное расстояние, которое отделяет содержимое одного лайн-бокса, от другого).

Алексей

причём, я так понимаю, это верно, даже если в строке есть замещаемые элементы или inline-block

Похоже что путаю: и тем и другим плевать на лидинги(кроме возможно, случае vertical-align text-top и text-bottom), они видят контейнер (строка — лайнбокс) и укладываются в него как им удобнее :) Если такой элемент самый высокий в строке (или vertical-align указан как top или bottom), то замечательно умещаются до краёв виртуальной области строки.

Алексей

Тут такой вопрос возник: как связаны безразмерное значение line-height и значение, в единицах измерения?
Я считал, что line-height: 1 это тоже самое что 1em. То есть, если размер font-size: 16px, то,
если мы зададим line-height: 1 то он будет равен 16px.
Но тут неожиданно оказалось что значения безразмерного коэффициента, и это же значение, умноженное на font-size, незначительно различающиеся значения.
Кто-нибудь может мне объяснить, в чём тут дело?

SelenIT (Автор записи)

В первом приближении оно и должно быть равно 1em. Могут быть разве что нюансы до пикселя из-за округления. Можно увидеть пример различия?

Разница между line-height: 1 и line-height: 1em в том, как они наследуются: для размерных величин наследуется то значение в пикселях, которое получается для родительского элемента, а для безразмерных — сам коэффициент, который для каждого дочернего элемента заново умножается на его font-size.

Алексей

В первом приближении оно и должно быть равно 1em. Могут быть разве что нюансы до пикселя из-за округления. Можно увидеть пример различия?

Да, вот пример. Голову сломал — почему ритм не сходится? Всё 10 раз перепроверил, и неожиданно выяснилось, что если поменять значение line-height на размерное, то всё сходится(43-44 строчки).
Соответственно, возник вопрос — почему?

Разница между line-height: 1 и line-height: 1em в том, как они наследуются: для размерных величин наследуется то значение в пикселях, которое получается для родительского элемента, а для безразмерных — сам коэффициент, который для каждого дочернего элемента заново умножается на его font-size.

Ну, в приведённом примере, лайн-бокс, насколько я понимаю, формируют strut, который либо умножаешь на фонт-сайз, либо оставляешь безразмерным. У дочернего span line-height задано как normal, который заведомо меньше strut, а большОй белый элемент справа — абсолютно позиционирован, соответственно на размер родителя(а соответственно и размер строки) влиять не должен.
Может, конечно, я где-то что-то проворонил и дело не в этом, но открытием было именно то, что когда умножаешь безразмерное значение на фонт-сайз, ритм выстраивается…

Алексей

Как я уже говорил с большим удовольствием прочитал статью, и выяснил для себя, некоторые пробелы, которые у меня, к сожалению, остались после прочтения Вашей книжки.
Автор очень подробно рассказывает о том, что же действительно происходит в строке, и, возникает ощущение, что теперь, я примерно понимаю, что же действительно происходит в строке – по крайней мере что касается, вертикальной составляющей, а она, насколько я понимаю, в вебе, основная.
Кстати, в примере, приведённом в статье, ContentArea (область содержимого), похоже, названо тем, что, по-идее, является виртуальной областью (правда у разобранного автором шрифта значение line-gap(межстрочного расстояния) равно нулю, а значит область контента и область содержимого совпадают). Но у других шрифтов может быть по-другому.
Тем не менее, обстоятельно рассказав теорию, пример, на мой взгляд, автор пояснил немного бегло. Причём общая идея примера, достаточно прозрачна, но всё же, практика показывает, что есть нюансы. И, если интересно, не только понять о чём речь, но и увидеть, что с чем будет взаимодействовать, и какие возникают пути решения, то остаются вопросы.
Попробуем разобраться, что в принципе происходит в строке такого, что поможет нам увидеть вертикальный ритм в строке и понять как работает выравнивание.
На мой взгляд, если попытаться выразить идею вертикального выравнивания одним словом, то слово это будет «относительное». Строки заполняют пространство документа с верху вниз, соответственно каждая строка, своим верхним краем, упирается в верхнюю строку (или начало документа), располагая своё содержимое вниз, расширяясь, при этом, с тем, чтоб уместились все её элементы, учитывая их вертикальное расположение, друг относительно друга. Элемент, расположенный в строке выше всех, упирается своей верхней частью, в верхнюю часть строки и чем выше он расположен, тем больше пространство строки увеличится вниз, а значит сместит вниз и находящиеся в ней элементы. Таким образом, элемент может поменять своё положение не только изменив собственное значение vertical-align, но и под влиянием соседей. Значение вертикального выравнивания показывает положение элемента в строке относительно других элементов строки.
В блоке есть текстовый потомок по-умолчанию, называется strut (про который сказано и в статье и в книжке). Мало того, что он передаёт по-наследству свои строчные параметры, так он ещё и незримо присутствует в строках блока, обуславливая, тем самым её минимальный размер. Насколько мне известно, избавится от его влияния можно только задав блок-обёртку с другими параметрами. Для эксперимента, можете сделать блок со свойством line-height: 100px, и попробовать сделать в любом месте блока расстояние между строками размером, скажем, 16px, используя только строчное форматирование. Как сделаете, мне обязательно расскажите :-)
Влияние этого блочного потомка, strut, обязательно нужно учитывать. Он может присутствовать незримо и совпадать со своим видимым коллегой, особенно если коллега безымянный и пользуется по-умолчанию тем, что ему досталось от этого strut, но влияние strut неожиданно может проявиться. Получается, в заполненной строке, УЖЕ есть два элемента: текущий и strut.
А поскольку выравнивание, во многом, относительное, то либо элемент выравнивается, относительно strut, либо strut относительно элемента. Вот – основной теоретический каркас, на котором строится всё выравнивание. Стоит ещё отметить что для strut напрямую задать вертикальное выравнивание нельзя, его расположение – некая блочная базовая линия, положение которой, впрочем, может меняться под влиянием других элементов в строке.
Продолжу в следующем комментарии…

Алексей

Теперь давайте посмотрим на задачу, предложенную в статье: сделать высоту строки, пропорциональной заглавным буквам определённого шрифта, при этом, сами заглавные буквы, должны находится ровно посередине строки.
Первое, что приходит в голову, это сделать strut большим (задав большой line-height для содержащего блока), а элемент двигать относительно него. Такой подход имеет очевидный недостаток – все строки в блоки будут далеко друг от друга. Если блок для этого и создан, то, как говорится – нет проблем, а если это общий контейнер, где каким-то элементам нужно придать определённые свойства, то это может мешать. Рецепт лечения такой бяды понятен – блок-обёртка (либо для участков где нужна большая строка, либо для участков, где строка нужна маленькая, нивелируя влияния большой на маленькую), насколько он оправдан в каждом конкретном случае – зависит от того, насколько мы не хотим загружать html проблемами CSS :-)
Известно, что область содержимого лежит посередине виртуальной области, а значит если в области содержимого, заглавные буквы будет находится посередине, то они будут находится и посередине строки. Параметры шрифта посмотрим, в указанной в статье программе FontForge, расстояния от края области содержимого до ближнего края заглавных букв посчитаем по примеру в статье (от низа – расстояние нижних выносных элементов, верх – разница между верхними выносными элементами и заглавной буквой).
Сравним эти расстояния – какое-то из них, вероятно будет чуть больше. Значит нужно сдвинуть в противоположную сторону настолько, чтоб эти расстояния выровнялись. Посчитаем разницу между этими расстояниями, половина разницы – будет посередине. Значит если мы сдвинем на это расстояние, с одной стороны прибавится, в с другой, настолько же, убавится, и буква выровняется по центру. Замечу, что двигать букву, относительно её базовой линии (и соответственно остальных строчных параметров) средствами CSS не получится. Но на деле, мы двигаем букву относительно strut, который, в виду своих больших размеров, и формирует строку.
Итак, проба для шрифта Times New Roman, и для шрифта Arial. В Хроме и Лисе всё работает – смотрим вертикальный ритм, еле уловимый, словно шум моря из ракушки. Похоже, для Arial в Chrome ритм не идеален.
Здесь и далее, смотрите примечания к коду.

Алексей

Второй вариант, логично напрашивающийся, это сделать большой span и маленький strut. Но, как не сложно догадаться, сделать его значительно сложнее – относительно чего будет двигаться наше строчное содержимое, если оно и есть самый большой элемент в строке? Скорее, всё остальное (в том числе и strut) будет двигаться, и только потом сам элемент. Поэтому случай с маленький strut мы оставим на закуску, а займёмся вторым вариантом (который, кстати, похоже и был разобран в статье).
Принцип взаимодействия этих элементов отличается: если в случае, когда strut был большим, то только он принимал участие в формировании строки, span же целиком помещался в его пространстве, то теперь оба элемента имеют влияние на высоту строки. И, если мы изменим положение одного, относительно другого, то элемент, оказавшийся выше, будет упираться в верх строки, а ниже – в её низ. Высота строки же вырастет на величину сдвига.
По-идее, если расстояние от верхнего края заглавной, до края области содержимого, чуть больше чем аналогичное расстояние внизу, то уровнять мы можем либо немного уменьшив расстояние вверху, либо немного увеличив расстояние внизу. Уменьшая или увеличивая line-height, мы обрежем или дополним элемент с двух сторон, при этом разница, между расстоянием до верха и до низа, никуда не денется – и её потребуется чем-то скомпенсировать. Чем же?
Итак, у нас есть два расстояния от заглавной буквы, до верха и до низа строки. Находящиеся на одном уровне два элемента одинаковый высоты, занимают минимальную возможную для них высоту, и любой сдвиг одного из них, приведёт к увеличению строки. Для того, чтоб меньшее расстояние стало равным большему, нужно сдвинуть второй элемент в сторону увеличиваемой стороны, на расстояние этого увеличения (второй элемент, при этом, играет, своеобразную роль заглушки). Соответственно, размер этого сдвига, равен разнице между меньшим и большим расстоянием (от верхнего края буквы или от нижнего края, буквы до ближайшего для него края строки). Что же это за второй элемент? – strut.
Понятно, что удобней двигать (воздействовать на) сам элемент, поскольку strut затрагивает всё содержимое блока, а элемент, только самого себя и влияет только на ту строку, в которой лежит. Как мы помним, вертикальное выравнивание относительно, а значит, для того, чтоб сдвинуть strut, например, вниз, мы можем поднять элемент вверх. При этом, поскольку элементы одинаковые, строка увеличится на величину сдвига.
Единственная сложность, в данном случае, что размер строки нужно привести к размеру заглавных букв. Если в предыдущем примере, сделать это было относительно легко – мы просто увеличивали strut (предварительно посчитав его размер в заглавных буквах), то теперь, на размер строки влияют два элемента, каждый из которых чуть-чуть меньше полного размера строки. Но, поскольку, понятно, насколько они меньше (на величину сдвига), то высчитать зависимость наших элементов от величины заглавных не составит большого труда. В общем, этот способ не намного сложнее, и, тем не менее, для его успешной реализации, пришлось переписать большую часть кода, сделав алгоритм расчёта, по возможности, более прозрачным.
В данном случае, кстати, приходится «вручную» смотреть какое расстояние больше – до верха или до низа. Благо считается это просто, да и в коде результат нужно вставить всего в паре мест, но всё-таки, пожалуй, небольшое неудобство. Отмечу, что размер сдвига, по сравнению с предыдущим примером, в два раза больше: здесь разница, между расстоянием от заглавной до верха, и до низа, а в предыдущем – лишь половина разницы.
Вот результат, для Arial и для Times New Roman. Хром-Лиса полёт нормальный :)

Алексей

Ну и, наконец, третий случай, strut маленький, а элемент большой. Как быть? Решение простое, как дрова — псевдоэлемент :-) Он берёт на себя функции второго элемента (равной высоты) и выравниваясь относительно текущего элемента, выравнивает элемент.
Пример для Arial и Times. Поскольку такое решение – на подобии второго примера, наверное, можно сделать и на подобии первого: элемент маленький, псевдоэлемент большой, элемент выравнивается относительно псевдоэлемента. Технически, правда, придётся сделать наоборот – выравнивать псевдоэлемент относительно элемента, но с тем, чтоб двигался именно элемент. Возможны нюансы :-) Рассмотреть подобный случай оставлю на Ваше усмотрение…
В итоге, я нашёл два способа: один когда регулируется маленький элемент относительно большого, и второй – когда два одинаковых (или близких по размерам?!) элемента, и они регулируются друг относительно друга, один упирается в верхний край строки, другой — в нижний. Какой из способов лучше? Даже не знаю, пожалуй, третий :-) Вариант с псевдоэлементом, несёт, пожалуй, наибольшую практическую ценность, поскольку не затрагивает блочные настройки. Но я делал псевдоэлемент по второму варианту, можно попробовать и сделать по первому… Думаю, что понимание, как работают оба способа, полезно в любом случае и рано или поздно может Вам пригодится :)

Алексей

Что-то я не могу найти горизонтальные характеристики шрифта Georgia, а именно letter-spacing (именно это значение, насколько я понимаю, используется для рассчитываня отступа между инлайн-блоками), перерыл весь FontForge, там есть какие-то туманные характеристики, вроде максимальное и минимальное растяжение пробела, а также пробел в конце предложения, впрочем, возможно в зависимости от пары символов расстояние между ними будет различаться… Ну а какое оно тогда между инлайн-блоками?
opentype.js указанный в статье тоже не понятен, скармливаешь ему шрифт, он этим шрифтом пишет некий текст, а список параметров так и приводится в виде ссылок, нажимая на которые, попадаешь в некие пространные описания…

SelenIT (Автор записи)

Я полагаю, что расстояние между инлайн-блоками — это обычная ширина (advance width) символа пробела (код 32). А эксперимент показывает иное?

CSS свойство vertical-align

Выравнивает элемент по вертикали относительно своего родителя или окружающего текста.

CSS синтаксис

Возможные значения

Значение Описание
значение Поднимает (положительное значение) или опускает (отрицательное значение) элемент на заданное значение относительно базовой линии. В качестве значений используются допустимые единицы длины CSS - пиксели (px), пункты (pt), сантиметры (cm) и т.д. 0 равно значению baseline.
% Поднимает (положительное значение) или опускает (отрицательное значение) элемент на величину в процентах от значения свойства line-height. При этом 0% аналогично значению baseline.
baseline Значение по умолчанию. Выравнивает базовую линию текущего элемента по базовой линии родителя. Если родительский элемент не имеет базовой линии, то за нее принимается нижняя граница элемента.
sub Элемент выравнивается как подстрочный, в виде нижнего индекса. Размер шрифта при этом не меняется.
super Элемент выравнивается как надстрочный, в виде верхнего индекса. Размер шрифта остается прежним.
top Верх элемента выравнивается по верху самого высокого элемента строки.
text-top Верх элемента выравнивается по верху шрифта родительского элемента.
middle Выравнивание средней точки элемента по середине родительского элемента.
bottom Низ элемента выравнивается по низу самого нижнего элемента строки.
text-bottom Низ элемента выравнивается по низу шрифта родительского элемента.
inherit Значение наследуется от родительского элемента.
initial Устанавливает значение по умолчанию.

Пример

Устанавливаем вертикальное выравнивание изображения

Очередной блог фрилансера

коротко и полезно о веб-разработке

Обзор CSS-свойства vertical-align

Довольно часто от веб-разработчиков можно услышать возмущенный возглас: “vertical-align не работает!”. Несмотря на то, что назначение этого свойства следует из его названия, на практике, начинающие разработчики, равно как и многие ветераны CSS, часто испытывают трудности с его применением.

В сегодняшней статье, я постараюсь раскрыть все непонятные моменты этого CSS-свойства.

Чего не делает vertical-align

Наиболее распространенное заблуждение относительно свойства vertical-align состоит в том, что оно влияет на вертикальное выравнивание всех дочерних элементов контейнера, к которому применяется. Например, если мы применим к контейнеру свойство vertical-align: top, предполагается, что все содержимое контейнера будет выровнено по верхнему краю контейнера.

Это напоминает мне старые, добрые времена табличной верстки:

В этом примере табличной ячейки, свойство valign (сейчас уже запрещенное в HTML5), действительно прижмет все содержимое ячейки к верхнему краю. Возможно исходя из этого, CSS-разработчики ожидают похожего эффекта, от применения свойства vertical-align.

Но свойство vertical-align так не работает.

Как на самом деле работает vertical-align

Свойство vertical-align можно разделить на три простых правила:

  1. Оно применяется только к элементам со свойствами display: inline; и display: inline-block;
  2. Оно влияет на положение самого элемента, а не его содержимого (за исключением табличных ячеек)
  3. Когда оно применяется к табличной ячейке, то влияет на содержимое ячейки, а не на саму ячейку.

Другими словами, следующий код не будет иметь никакого эффекта:

Почему? Потому что

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

На картинке ниже, представлен пример того, как ведут себя строчные элементы, когда вы применяете свойство vertical-align:

Значения свойства – ключевые слова

Свойство vertical-align может принимать следующие значения:

  • baseline (значение по умолчанию)
  • bottom
  • middle
  • sub
  • super
  • text-bottom
  • text-top
  • top

Большинство из них вам скорее всего не понадобятся, но всегда хорошо знать из чего можно выбрать. Например, на демо-странице, текстовому полю назначено свойство vertical-align: top, благодаря чему, оно выровнено относительно самого высокого элемента в строке (большой картинки).

А если вы не хотите располагать элемент относительно изображений или других строчных элементов, можно использовать значения text-top или text-bottom, чтобы ваш элемент позиционировался относительно текста, расположенного в строке.

О значении “middle”


К сожалению, vertical-align: middle; не расположит строчный элемент по центру самого большого элемента в строке, как этого можно было бы ожидать. Вместо этого, значение middle расположит элемент относительно гипотетической строчной “x” (также называемой “x-высотой”). По-хорошему, это значение следовало бы назвать “text-middle”, для правильной идентификации его механизма.

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

Цифровые значения свойства

Возможно вы не знали, но vertical-align в качестве значения может принимать абсолютные и процентные значения, все приведенные ниже примеры будут правильными:

В чем разница между абсолютными значениями и ключевыми словами, можно почитать в CSS-спецификации, или (что на мой взгляд гораздо полезнее) самостоятельно попробовать различные варианты.

Перевод статьи “Understanding CSS’s vertical-align Property”, автор Louis Lazaris

Рассказать друзьям

Понравилась статья? Лучший способ сказать спасибо - поделиться ссылкой в социальных сетях:

ТИПИЧНЫЙ ВЕРСТАЛЬЩИК

Line-height и vertical-align — это простые CSS свойства. Они настолько просты, что большинство из нас убеждено в том, что в полной мере понимают, как они работают и как их использовать. Но это не так. В действительности же они сложны. Можно даже считать, что они являются самыми сложными свойствами, т.к. они играют важную роль в создании мало известной особенности CSS: в строчном форматировании текста.

Например, line-height может быть установлен в качестве длины или безразмерного значения, но по умолчанию у него задано значение normal. Окей, но что такое normal? Пишут, что чаще всего это 1 или может даже 1.2. Но даже в спецификации по CSS нет ясного ответа на этот вопрос. Мы знаем, что line-height — безразмерное свойство относительно родительского значения font-size, но проблема заключается в том, что font-size: 100px выглядит по разному, в зависимости от семейства шрифта. Вопрос: значение line-height всегда одинаковое или разное? Действительно ли значение варьируется между 1 и 1.2? А vertical-align? Каково его влияние в отношении line-height?

Глубокое погружение в CSS не такой простой механизм…

Давайте сперва поговорим о font-size

Посмотрите на простой HTML код. Тег p содержит три span , каждый из которых имеет свой собственный font-family :

Используя некоторое значение font-size с различными font-family, мы получаем элементы разной высоты:

Разные font-family, одинаковое значение font-size, получаем разную высоту элементов

Почему font-size: 100px не создает элементы с высотой в 100px? Я измерил и получилось:

  • Helvetica — 115px;
  • Gruppo — 97px;
  • Catamaran — 164px.

Элементы со значением font-size:100px имеют разную высоту

Все это кажется немного странным, на первый взгляд, но это вполне объяснимо. Причина находится внутри самого шрифта. Вот как это работает:

  • шрифт определяется его em-квадратом (или единицей em) своего контейнера, в котором будет нарисован каждый символ. Этот квадрат использует относительные единицы и обычно устанавливает значение на уровне 1000 единиц. Но здесь также может применяться значение 1024, 2048 и т.д.
  • устанавливается на основе своих относительных единиц, показателей шрифтов (ascender, descender, capital height, x-height и т.д.). Обратите внимание, что некоторые значения могут выходить за пределы em-квадрата.
  • в браузере относительные единицы масштабируются, чтобы нужный размер соответствовал шрифту.

Давайте возьмем шрифт Catamaran и откроем его в FontForge, чтобы получить его показатели:

  • em-квадрат 1000;
  • Ascender — 1100 и Descender — 54. После выполнения некоторых тестов, окажется, что браузеры используют значения HHead Ascent/Descent на Mac OS, а также значения Ascent/Descent на Windows (эти значения могут отличаться!). Отметим также, что прописная буква имеет высоту 640px и высота обычной буква составляет 485px.

Значения шрифта в FontForge

Это значит, что шрифт Catamaran использует 1100 + 540 единиц при 1000 единиц в em-квадрате, который дает высоту 164px, в то время, как в настройках указано font-size: 100px . Эта вычисленная высота определяется как контент-область (content-area) элемента и я буду использовать этот термин далее в этой статье. Вы можете думать о контент-области, как об области, для которой применяется свойство background .

Мы также можем увидеть, что заглавные буквы имеют высоту 68px (680 единиц) и строчные буквы (x-height) — 49px (485 единиц). В результате, 1ex = 49px и 1em = 100px, а не 164px (к счастью, em основан на размере шрифта, а не на вычисленной высоте).

Шрифт Catamaran: эквивалент UPM и пикселей при использовании font-size: 100px

Прежде чем идти дальше, оставлю некоторое пояснение. Когда элемент p> отображается на экране, то он может состять из нескольких линий, в соответствии с его шириной. Каждая строка состоит из одного или нескольких inline-элементов (HTML-теги или встроенные imline-элементы для текстового содержимого) и имеет название line-box. Высота line-box основана на высоте его дочерних элементов. Таким образом, браузер вычисляет высоту для каждого inline-элемента, и, следовательно, высоту line-box (от высшей точки своего дочернего элемента к самой нижней точке своего дочернего элемента). В результате line-box — достаточно высок, чтобы содержать все свои дочерние элементы (по умолчанию).

Каждый HTML-элемент на самом деле является неким множеством, состящим из line-boxes. Если вы знаете высоту каждого line-box, Вы знаете высоту элемента.

Если обновить предыдущую страницу HTML код, то получим:

Он будет генерировать три line-boxes:

  • первый и последний, каждый из которых содержит единственный встроенный элемент (содержание текста)
  • второй, содержащий два встроенных элемента и три span>

Тег (черная рамка) сделана из line-boxes (белые границы), которые содержат inline-элементы (сплошные границы) и анонимные inline-элементы (пунктирные границы)

Мы ясно видим, что второй line-box выше остальных, в связи с вычисленной контент-областью его дочерних элементов, один из которых использует шрифт Catamaran.

Трудным в создании line-box является то, что мы не можем видеть и управлять им с помощью CSS. Даже применяя background с псевдоклассом : : first-line не дает нам ни какой визуальной подсказки о высоте line-box.

line-height: к проблемам и за ее пределами

Ранее я ввел два понятия: контент-область (content-area) и line-box. Если вы читали внимательно, то я сказал, что высота line-box вычисляется в соответствии с его дочерней высотой, я не сообщал дочерним элементам высоту их контент-области. В этом и заключается больше различие.

Хотя это может показаться странным, inline-элемент имеет две разные высоты: высоту content-area и высоту virtual-area (Я изобрел термин virtual-area , обозначая таким образом высоту, невидимую для нас. Этого термина Вы не найдете в спецификации).

  • высота content-area определяется показателями шрифта (как показано выше)
  • высота virtual-area — это line-height , а также это высота, которая используется для вычисления высоты line-box

Inline-элементы, имеющие две разные высоты

Это ломает распространенное мнение о том, что line-height это расстояние между базовыми линиями (baselane). В CSS это не так.

В CSS, the line-height — это не расстояние между двумя базовыми линиями

Рассчитанная разность высот между virtual-area и content-area называется ведущей. Половина этой ведущей добавляется к верхней части content-area, другая часть — к нижней. Content-area располагается всегда в центре virtual-area.

На основе его значений, line-height (virtual-area) может быть больше, меньше или равной content-area. В случае меньшего размера virtual-area, ведущее значение станет отрицательным и line-box стане визуально меньше его дочернего элемента.

Существуют также другие виды inline-элементов:

  • inline-элементы ( img> , input> , svg> , etc.)
  • inline-block и все inline-* элементы
  • inline-элементы, которые используются в качестве форматирования текста (например, во flexbox-элементах)

Для этих inline-элементов, высота вычисляется на основе height , margin и border . Если height имеет значение auto , то line-height используется в content-area и строго равна line-height .

Inline замещаемые элементы, inline-block/inline-* и blocksified inline элементы имеют контент-область, равную их высоте или высоте линии

Итак, вернемся к FontForge. Em-квадрат шрифта Catamaran равен 1000, но мы видим значения ascender/descender:

  • Ascent/Descent: ascender — 770 и descender — 230. Используется для символьных рисунков. (табл. “OS/2”)
  • показатели Ascent/Descent: ascender — 1100 и descender — 540. Используется для высоты content-area. (табл. “hhea” и табл. “OS/2”)
  • показатель Line Gap. Используется дл line-height : normal , путем добавления этого значения показателей Ascent/Descent. (табл. “hhea”)

В нашем случае, шрифт Catamaran определяет разрыв в 0 единиц для line gap, поэтому line-height : normal будет равен content-area, который составляет 1640 единиц, иначе 1.64.

В качестве сравнения, шрифт Arial описывает em-квадрат в 2048 единиц, ascender — 1854, descender — 434 и line gap составляет 67. Это означает, что font-size : 100px дает content-area — 112px (1117 единиц) и line-height : normal — 115px (1150 единиц, иначе 1.15). Все эти показатели шрифта устанавливаются разработчиком шрифта.

Становится очевидным, что установка line-height : 1 плохая практика.Я хотел бы напомнить вам, что безразмерное значение относительно для font-size и virtual-area меньше, чем content-area. Именно это и является источником многих наших проблем.

Используя line-height: можно создать line-box меньше, чем контент-область

Уточнения о вычислении line-box:

  • для inline-элементов, padding и border увеличивают область фона, но не высоту content-area (или высоту line-box).Сontent-area — это не всегда то, что ты видишь на экране. margin-top и margin-bottom не имеют ни какого эффекта.
  • для inline-элементов, inline-block и blocksified inline-элементы: padding , margin и border увеличивают height , а значит увеличивают content-area и высоту line-box

vertical-align: свойство, которое управляет всеми

Я еще не упомянул о свойстве vertical-align , несмотря на то, что оно важно для вычисления высоты line-box. Можно даже сказать, что vertical-align играет ведущую роль в форматировании текста.

Значение по умолчанию — baseline . Помните о показателях шрифта ascender и descender? Эти значения определяют, где базовая линия стоит, а значит определяет и ее соотношение. Т.к. соотношение между ascenders и descenders редко бывает 50:50.

Тег p> с двумя span> унаследовал значения font-family , font-size и имеют постоянный line-height . Базовые линии (baselines) будут соответствовать и высота line-box будет равна их line-height .

Те же значения шрифта, одинаковые исходные условия, кажется, что все в порядке

Что делать, если второй элемент имеет меньший font-size ?

Как ни странно, но по умолчанию базовая линия может выровнять выше (!) line-box так, как показано на картинке. Я хотел бы напомнить вам, что высота line-box вычисляется от самой высокой точки своего дочернего элемента к низшей точке своего дочернего элемента.

Меньший дочерний элемент может привести к увеличении высоты line-box

Это может быть аргументом в качестве использования безразмерного значения line-height , но иногда необходимо его фиксировать, чтобы создать идеальный вертикальный размер. Если честно, то независимо от того, что вы выберете, вы всегда будете иметь проблемы с inline выравниванием.

Рассмотрим еще один пример. Тег p> с line-height : 200px , содержащий один span> , унаследовал значение line-height

Насколько высок line-box? Следует ожидать, что 200px, но это не так. Проблема здесь заключается в том, что p> имеет свой собственный font-family (по умолчанию serif ). Базовые линии тега p> и span> скорее всего, будут различны, а высота line-box выше, чем ожидалось. Это происходит потому, что браузеры производят вычисления следующим образом: так, как если бы каждый line-box начинался бы с нулевой ширины символа.

В итоге, мы столкнулись с той же проблемой, что и в предыдущем примере.

Каждый дочерний элемент выравнивается так, как если бы его line-box появился бы с невидимой нулевой ширины символа

Базовая линия скачен, но что можно сказать на счет vertical-align : middle ? Как пишут в спецификации, middle “выравнивает вертикальную среднюю точку контейнера с базовой линией родительского контейнера плюс половина x-height родительского блока”. Соотношение базовых линий различны, а также как различно соотношение x-height, следовательно выравнивание middle не надежно. Как правило, middle никогда не бывает по “середине”. Этому способствуют много факторов в CSS (x-height, ascender/descender соотношение, и тд.)

В качестве примечания:


  • vertical-align : top / bottom выравнивает по верху и низу line-box
  • vertical-align : text-top / text-bottom выравнивает по верху и низу content-area

Vertical-align: top, bottom, text-top и text-bottom

Но используйте с осторожностью, это выравнивает virtual-area. Посмотрите это на простом примере, используя vertical-align : top . Невидимый line-height может привести к странным, но не удивительным, результатам.

vertical-align может привести к нечетным результат на первых порах, но предполагается, что line-height создаст визуализацию

И в заключении стоит отметить, что vertical-align также принимает числовые значения, которые повышают или понижают поле относительно базовой линии.

CSS превосходен

Мы поговорили о том, как line-height и vertical-align работают вместе, но теперь вопрос: можно ли управлять показателями шрифта с помощью CSS? Короткий ответ: нет.

Что делать, если, например, мы хотим, чтобы текст с помощью шрифта Catamaran, где высота заглавной буквы 100px стал выше? Давайте немного займемся математикой.

Сначала мы устанавливим все показатели шрифта в качестве CSS-свойств, а затем вычислим font-size ,чтобы получить высоту заглавной буквы 100px.

Высота заглавной буквы — 100px

Довольно просто, не так ли? Но что, если мы хотим, чтобы текст визуально стоял по середине? Так чтобы оставшееся пространство равномерно распределялось по верхней и нижней части буквы «B»? Для достижения этой цели, мы должны вычислить vertical-align базирующийся на соотношении ascender/descender.

Во-первых, установим line-height : normal и высоту content-area:

Затем нам нужно установить:

  • расстояние от нижней части буквы к нижнему краю
  • расстояние от верхней части буквы к верхнему краю

Теперь мы можем вычислить vertical-align , которая представляет собой разность между расстояниями, умноженное на величину font-size . (мы должны применить это значение для дочернего элемента inline)

В конце концов, мы устанавливаем желаемый line-height и вычисляем его при сохранении вертикального выравнивания:

Результат установки для line-height разных значений. Текст всегда располагается по середине.

Добавить значок, высота которого соответствует букве «B», теперь легко:

Иконка и буква B имеют одинаковую высоту

Обратите внимание, что это демо предназначено только для демонстрационных целей. Почему? На это есть много причин:

  • показатели шрифта могут быть не постоянными ¯⁠\⁠(ツ)⁠/⁠¯
  • если шрифт не загружен, то резервный шрифт, верноятно, будет иметь различные показатели шрифта и иметь дело с несколькими значениями, а значит — станет не управляемым.

6 методов вертикального центрирования с помощью CSS .

Центрирование элементов по вертикали с помощью CSS является задачей, которая представляет определенную трудность для разработчиков. Однако имеется несколько методов ее решения, которые достаточно просты. В данном уроке представлено 6 вариантов вертикального центрирования содержания.

Начнем с общего описания задачи.

Задача вертикального центрирования

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

Большинство людей, используя свойство text-align: , обращаются к свойству vertical-align для центрирования по вертикали. Все выглядит достаточно логично. Если вы использовали табличные шаблоны, то наверняка активно использовали атрибут valign , который укрепляет веру в то, что vertical-align правильный путь к решению задачи.

Но атрибут valign работает только в ячейках таблицы. А свойство vertical-align очень на него похоже. Оно также действует на ячейки таблицы и некоторые строчные элементы.

Значение свойства vertical-align действует по отношению к родительскому строчному элементу.

  • В строке текста выравнивание производится по отношению к высоте строки.
  • В ячейке таблицы используется выравнивание по отношению к величине, вычисляемой специальным алгоритмом (обычно получается высота строки).

Но, к сожалению, свойство vertical-align не действует в блочных элементах (например, параграфах внутри элемента div ). Такое положение может привести к мысли, что решения задачи вертикального выравнивания нет.

Но есть другие методы центрирования блочных элементов, выбор которых зависит от того, что центрируется по отношению к внешнему контейнеру.

Метод line-height

Данный метод работает, когда вы хотите центрировать вертикально одну строчку текста. Все что нужно сделать - это задать высоту строки больше, чем размер шрифта.

По умолчанию свободное пространство будет распределено равномерно сверху и снизу текста. И строка будет отцентрирована вертикально. Часто высоту строки делают равной высоте элемента .

Данный метод работает во всех браузерах, хотя использовать его можно только для одной строки. Значение 200 px в примере выбрано произвольно. Можно использовать любые величины больше размера шрифта текста.

Центрирование изображения с помощью line-height

А что если содержание представляет собой картинку? Будет ли выше описанный метод работать? Ответ заключается в еще одной строчке кода CSS.

Значение свойства line-height должно быть больше высоты изображения.

Метод таблиц CSS

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

Примечание: Таблица CSS не является тем же, что и HTML таблица.

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

В отличие от описанного выше метода, в данном случае содержание может быть динамическим, так как элемент div будет изменять размер в соответствии со своим содержанием.

Недостатком данного метода является то, что он не работает в старых версиях IE. Приходится использовать свойство display: inline-block для вложенного контейнера.

Абсолютное позиционирование и отрицательные поля

Данный метод также работает во всех браузерах. Но он требует, чтобы центрируемому элементу задавалась высота.

В коде примера выполняется одновременное центрирование по горизонтали и вертикали:

Сначала устанавливаем тип позиционирования элементов. Затем для вложенного элемента div устанавливаем значения свойств top и left равными 50%, что соответствует центру родительского элемента. Но в центр попадает левый верхний угол вложенного элемента. Поэтому нужно поднять его вверх (на половину высоты) и сдвинуть влево (на половину ширины), и тогда центр совпадет с центром родительского элемента. Так что знание высоты элемента в данном случае необходимо. Затем задаем элементу отрицательные значения верхнего и левого полей равными половине высоты и ширины соответственно.

Данный метод работает не во всех браузерах.

Абсолютное позиционирование и растягивание

В коде примера выполняется центрирование по вертикали и горизонтали.

Идея данного метода заключается в том, чтобы растянуть вложенный элемент до всех 4 границ родительского элемента с помощью установки свойствам top, bottom, right, и left значения 0.

Установка автоматического формирования полей по всем сторонам приведет к заданию равных значений по всем 4 сторонам и выведет наш вложенный элемент div по центру родительского элемента.

К сожалению, данный метод не работает в IE7 и ниже.

Равные отступы сверху и снизу

В данном методе явно задаются равные отступы сверху и снизу от родительского элемента.

В коде CSS примера отступы сверху и снизу задаются для обоих элементов. Для вложенного элемента установка отступов будет служить для вертикального центрирования. А отступы родительского элемента будут центрировать вложенный элемент в нём.

Для динамического изменения размеров элементов используются относительные единицы измерения. А для абсолютных единиц измерения придется проделать расчеты.

Например, если родительский элемент имеет высоту 400 px, а вложенный элемент - 100px, то необходимы отступы 150px сверху и снизу.

150 + 150 + 100 = 400

Использование % позволяет расчеты оставить браузеру.

Данный метод работает везде. Обратной стороной является необходимость в расчетах.

Примечание: Данный метод работает за счет установки внешних отступов элемента. Вы можете также использовать поля внутри элемента. Решение о применении полей или отступов нужно принимать в зависимости от специфики проекта.

Плавающий div

Данный метод использует пустой элемент div , который плавает и помогает управлять положением нашего вложенного элемента в документе. Обратите внимание, что плавающий div размещается до нашего вложенного элемента в коде HTML.

Мы смещаем пустой div влево или вправо и задаем для него высоту 50% родительского элемента. Таким образом, он будет заполнять верхнюю половину родительского элемента.

Так как данный div является плавающим, то он удаляется из обычного потока документа, и нам нужно отменить обтекание текстом для вложенного элемента. В примере используется clear: both , но вполне достаточно использовать тоже направление, что и смещение плавающего пустого элемента div .

Верхняя граница вложенного элемента div находится непосредственно под нижней границей пустого элемента div . Нам нужно сместить вложенный элемент вверх на половину высоты плавающего пустого элемента. Для решения задачи используется отрицательное значение свойства margin-bottom для плавающего пустого элемента div .

Данный метод также работает во всех браузерах. Однако его использование требует дополнительного пустого элемента div и знаний о высоте вложенного элемента.

Заключение

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

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: http://www.vanseodesign.com/css/vertical-centering/
Перевел: Сергей Фастунов
Урок создан: 21 Сентября 2011
Просмотров: 568625
Правила перепечатки

5 последних уроков рубрики "CSS"

Забавные эффекты для букв


Небольшой эффект с интерактивной анимацией букв.

Реализация забавных подсказок

Небольшой концепт забавных подсказок, которые реализованы на SVG и anime.js. Помимо особого стиля в примере реализована анимация и трансформация графических объектов.

Анимированные буквы

Эксперимент: анимированные SVG буквы на базе библиотеки anime.js.

Солнцезащитные очки от первого лица

Прикольный эксперимент веб страницы отображение которой осуществляется “от первого лица” через солнцезащитные очки.

Раскрывающаяся навигация

Экспериментальный скрипт раскрывающейся навигации.

vertical-align

Свойство CSS vertical-align используется для вертикального выравнивания элементов относительно своих родителей. В основном такое выравнивание опирается на базовую линию, как самого элемента, так и его родителя, поэтому для начала пояснение о том, что такое базовая линия.

  1. Базовая линия — это воображаемая линия, проходящая по нижнему краю символов. Некоторые буквы (щ, ц, у, д, р, ф) частично выходят за базовую линию.
  2. Если у элемента нет базовой линии (как, например, у изображений или блочных элементов), то в ее роли выступает внешний край нижнего поля (margin-bottom).
  3. Базовая линия ячейки таблицы — это базовая линия ее первой строки текста или первого блока (смотря, что стоит в начале). Если такого текста или блока нет, то это низ ячейки.
  4. Базовая линия ряда HTML-таблицы — это базовая линия, общая для всех ячеек этого ряда.

Тип свойства

Применяется: к встроенным (уровня строки) элементам, ячейкам таблиц ( , ) и элементам с display равным table-cell.

Значения

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

  • baseline — выравнивает базовую линию элемента относительно базовой линии его родителя.
  • m >vertical-align от родительского элемента.

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

  • baseline — базовая линия ячейки выравнивается по базовой линии ряда, в которой она расположена. Если ячейка объединена и состоит из нескольких рядов, то берется базовая линия первого ряда.
  • top — верх содержимого ячейки выравнивается относительно ее верха.
  • middle — центр содержимого ячейки выравнивается относительно ее центра.
  • bottom — низ содержимого ячейки выравнивается относительно ее низа.

Процентная запись: относительно line-height самого элемента.

Значение по умолчанию: baseline.

Хотя в спецификации CSS об этом и не сказано, но по умолчанию все браузеры выравнивают содержимое ячеек согласно vertical-align со значением middle, то есть по спецификации HTML.

Синтаксис

Пример CSS: использование vertical-align

Результат. Использование свойства CSS vertical-align в браузере Opera.

Версии CSS

Версия: CSS 1 CSS 2 CSS 2.1 CSS 3
Поддержка: Да Да Да Да

Браузеры

Браузер: Internet Explorer Google Chrome Mozilla Firefox Opera Safari
Версия: 6.0 и 7.0 8.0 и выше 2.0 и выше 2.0 и выше 9.2 и выше 3.1 и выше
Поддержка: Частично Да Частично Частично Да Частично

Internet Explorer 6.0 и 7.0 не понимают значение inherit .

Chrome, Firefox и Safari без причин увеличивают заданную высоту ячейки таблицы при vertical-align : baseline , если ее содержимое начинается с блочного или замещаемого элемента (как на примере выше).

Вертикальное выравнивание элементов с помощью CSS

28.11.2020 в 22:52, Евгений

Проблема вертикального центрирования элементов в CSS имеет ряд готовых решений. Выбор способа выравнивания в каждом отдельном случае зависит от типа, размеров, позиционирования элементов и других заданных им свойств.

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

Вот два элемента div:

Каждый из способов будет применен для выравнивания внутреннего блока по центру наружного.

line-height для одной строки

Когда родитель занимает одну строку текста и высота потомка известна, можно применить свойство line-height. Значение свойства должно быть равным высоте внешнего блока. Это работает только для одной строки, поэтому потомку полезно добавить overflow: hidden и запрет переноса строки white-space: nowrap.

Не получится воспользоваться процентной записью line-height=100%, потому что 100% в этом случае — высота шрифта.

Способ применим только при известной высоте внешнего блока.

Таблица с vertical-align

Для вертикального выравнивания элементов как нельзя лучше подходит таблица. Чтобы не нарушать семантику, табличные элементы лучше создавать средствами CSS. Положением содержимого ячейки управляет vertical-align. В таблицах работают четыре значения этого свойства:

• baseline — по умолчанию;
• bottom — содержимое внизу ячейки;
• middle — содержимое посередине ячейки;
• top — содержимое вверху ячейки.

В первом примере внешним блоком становится одинокая ячейка таблицы.

Способ хорош тем, что работает для элементов без заданной высоты, но в некоторых случаях его использованию мешает тот факт, что внешний блок, как любая ячейка таблицы, по ширине подстраивается под свое содержимое, а растянуть его можно только задав ширину для width явно. Для ячейки без таблицы проценты работают неадекватно.

Этот недостаток исправляется обертыванием ячейки в родителя со свойством display:table. Этому элементу размер можно задать в процентах. Окончательно код будет выглядеть так:

Position: absolute + отрицательный margin

Способ применяется, когда известна высота внутреннего элемента. Для внешнего блока она может быть неизвестной. Родителю задается относительное позиционирование, а потомку внутри него абсолютное.

Значение свойства top, равное 50%, заставляет вложенный элемент расположиться верхним краем посередине внешнего блока. Остается поднять его отрицательным margin-top на половину собственной высоты, чтобы он встал точно по центру вертикали.

Недостаток этого способа в необходимости знать высоту потомка.

Выравнивание в строке с vertical-align

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

При известной высоте родителя этим свойством можно воспользоваться для центрирования многострочного текста.

Для внешнего блока прописывается центрирование одной строки.

Значение line-height для внутреннего блока переопределяется на normal или на любую требуемую величину. Ему же задается выравнивание vertical-align: middle и преобразование в строчно-блочный тип — display: inline-block.

Недостаток способа — надо знать высоту родителя.

Выравнивание с помощью transform

Функция translateY свойства transform позволяет отцентрировать внутренний блок с неизвестной высотой. Для этого родитель должен быть спозиционирован относительно, а потомок — абсолютно.

Свойство top со значением 50% опускает внутренний блок так, что его верхний край располагается посередине родителя. Значение translateY: -50%, поднимает элемент на половину его собственной высоты и тем самым совмещает вертикальные центры блоков.

Недостаток приема в ограниченной поддержке функций transform браузером IE.

Выравнивание через псевдоэлемент

Способ работает, когда высота неизвестна ни для первого, ни для второго блока. Внутрь родителя с помощью before или after добавляется строчный псевдоэлемент inline-block. Высота добавленного элемента должна равняться высоте родителя — height: 100%. Вертикальное выравнивание содержимого задается посредством vertical-align: middle.

С помощью vertical-align: middle относительно этого псевдоэлемента выравнивается внутренний блок. Так как родитель и потомок имеют одинаковую высоту, внутренний элемент, выравниваясь по вертикали с псевдоэлементом, центрируется также и с внешним блоком.

Универсальный способ. Не работает если внутреннему блоку задано абсолютное позиционирование.

Flexbox

Самый новый и простой способ выравнивания элементов по вертикали. Flexbox позволяет расставлять элементы Web-страницы как угодно. Чтобы выровнять блок по центру, достаточно родителю прописать display: flex, а потомку margin: auto.

Flexbox работает только в современных браузерах.

Выбор способа

Какой техникой вертикального выравнивания воспользоваться зависит от задачи и тех, ограничений, которые могут присутствовать в каком конкретном случае.

Высота элементов неизвестна

В этой ситуации можно воспользоваться одним из четырех универсальных способов:

1. Таблица. Родителем становится ячейка таблицы, созданная в HTML или через display-table/display-cell. Этому элементу-родителю присваивается vertical-align: middle.

2. Псевдоэлемент. Для внешнего блока создается строчно-блочный псевдоэлемент с w >

3. Transform. Родитель получает position: relative. Потомку присваивается position: absolute, top: 50% и transform: translateY(-50%);

4. Flexbox. Внешнему блоку ставится display: flex, внутреннему — margin: auto.

Известна только высота потомка

Внешний блок позиционируется относительно; внутреннему элементу прописываются абсолютное позиционирование, top: 50% и margin-top, равный половине его высоты.

Одна строка в блоке с известной высотой

Внешнему блоку задается свойство line-height со значением, равным его высоте.

Высота внешнего блока известна, а внутреннего элемента – нет.

Родителю ставится line-height равный его высоте. У потомка значение line-height переопределяется на normal или на любую требуемую величину, и задаются ему display: inline-block и vertical-align: middle.

Илон Маск рекомендует:  Символьные метки
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL