ИКФ: высота строки, часть 2 (4-я публикация цикла «Тайны CSS2.1»)
line-height
С помощью текста мы можем регулировать высоту строки только благодаря размерам шрифта, но что делать, если мы хотим задать высоту строки принудительно? Вот тут я должен ввести в игру следующего игрока: "line-height".
Свойство line-height устанавливает интерлиньяж строки, т.е. попросту её высоту, а само состоит из высоты кегельной площадки + half-leading-ов (о них позже). Рассмотрим по порядку, как это действует.
line-height для текста
Начнем с простейшего случая: пусть наша строка состоит из единственного инлайнового бокса, представляющего собой обычный текст, набранный одним шрифтом одного размера.
Сразу пример:
<p> Свойство line-height - устанавливает интерлиньяж строки </p>
p { border: 1px solid #000; background: #F90; font-size: 30px; line-height: 200px; padding-left: 20px; }
Как я и говорил, внутри параграфа находится обычный текст. Но, на самом деле, весь оранжевый блок — это и есть лайн-бокс, и как можно заметить, его высота прилично превышает высоту самого текста. Размер шрифта я выставил 30px, а шрифт я даже не стал трогать, и значит, весь текст состоит из одного шрифта, да к тому же простого, не экзотического. Следовательно, можно взять высоту по максимуму из всех площадок, которая может составлять… думаю, не больше 50px (и то вряд ли). line-height я выставил в 200px, и если отнять от этой цифры размер максимальной площадки (50px), то остаётся 150px, но простите, а куда они тогда делись? Что бы это понять, нужно углубиться и разобрать все составляющие line-height.
leading (междустрочие)
В старые времена leading-ом считались свинцовые бруски, которые прокладывали между рядами литер металлического набора, т.е. добавочная высота "свинцовых полосок", отсюда leading, от lead — свинец. Именно с помощью них в старые времена в типографиях раздвигали строки. Но вот в Вебе leading-ом принято считать математическую разность заданного line-height-а и высоты кегля. Но, если говорить уже знакомым нам языком, то leading — это разность line-height-а и самой большой площадки, которые отрендерились font-size'ом и метриками шрифта, о которых мы говорили выше.
А теперь вернёмся к нашему примеру. Мы допустили, что максимальная высота самой высокой площадки составляет 50px, а разность line-height-а и высоты этой площадки получилась 150px. Вот последняя цифра и будет тем самым leading-ом, добавочным "бруском".
Да, но, вы можете задать вопрос: "А почему же тогда текст находится посередине лайн-бокса?". Всё дело в том, что на самом деле leading делится на две равные части, а каждая часть называется "half-leading", что в переводе означает «половина междустрочия». И вот, как раз таки, к каждой стороне высоких площадок и прибавляется вот по такому half-leading-у. В нашем случае вышло, что к каждой стороне прибавилось по 75px, вот почему текст выровнялся посередине.
Я предлагаю рассмотреть эту ситуацию прямо на нашем примере:
На рисунке можно увидеть, из чего состоит высота строки: half-leading (75px) + font-size (50px) + half-leading (75px). Это и есть наш line-height.
Отрицательный leading
До этого момента мы разобрали ситуацию, когда line-height больше, чем размер шрифта, но что, например, произойдёт, если line-height окажется меньше? Именно на этот вопрос мы и должны ответить прямо сейчас.
Давайте рассмотрим конкретный пример.
<p> line-height = font-size + (half-leading * 2) </p>
p { border: 1px solid #000; background: #F90; font-size: 30px; line-height: 10px; padding-left: 20px; }
Если предположить, что самая большая площадка по высоте составляет 30px, а line-height равен 10px, то высота строки в нашем случае будет равна именно десяти пикселям. Почему? А дело в том, что в такой ситуации leading начинает работать в обратную сторону, т.е. попросту становится отрицательным, а так как он состоит из двух частей (half-leading*2), то уменьшаться, по сути, начинают именно последние. Ну, и, конечно же, высота укорачивается с двух сторон в абсолютно одинаковой степени. Например, в нашем случае, half-leading-и составляют по —10px (+-), так как шрифт установлен в 30, а line-height в 10.
leading можно сравнить с полями (margin), только последние делают отступы снаружи элемента, а leading снаружи самой высокой площадки в строке. Как и margin, leading тоже может быть отрицательным, но самое интересное то, что в итоге line-height будет всё равно равен конечному результату. Наш пример можно трактовать как: line-height = 30 + (-10 * 2).
Мы выяснили, что делая значение line-height меньше размера шрифта, на самом деле мы делаем отрицательным leading и уменьшаем именно его, за счёт чего вычисляется итоговая высота строки. Но есть ли какие-нибудь ограничения? Да, есть. На самом деле отрицательный leading не может быть больше высоты самой высокой площадки в строке. Т.е, если, например, размер шрифта составляет 30px, то half-leading-и с двух сторон могут быть максимум по -15px каждый. Что и логично, ведь посудите сами, мы же не можем вывернуть строку наизнанку и сделать line-height равным:-1, -2 и т.д.
Другими словами, half-leading-и не могут отобрать от высоты строки больше, чем по половине, и минимальный теоретический предел высоты строки — ноль. На практике он может быть еще больше, стандарт разрешает браузерам иметь "свое мнение" по этому поводу. Например, совсем недавно Webkit-браузеры не позволяли сжать высоту строки меньше высоты строчных букв.
Отрицательный leading и более одной строки
Учитывая, что из-за отрицательного leading -а высота строки становится меньше содержимого (в нашем случае текста), нужно учитывать ещё и то, что эта особенность может навредить в тех моментах, когда строк становится две или больше.
По традиции, сразу приведу пример:
<p> Свойство line-height - устанавливает интерлиньяж строки, т.е. попросту её высоту</p>
p { border: 1px solid #000; background: #F90; font-size: 30px; line-height: 10px; padding-left: 20px; }
Ну, и конечно же сам результат:
По результату можно сделать вывод, что вторая строка началась раньше, чем закончилась первая, а точнее раньше чем закончилась высота текста в первой строке. Такое поведение легко объясняется тем, что фактическая высота строки составляет всего 10px, и содержимое строк вынуждено подстраиваться под этот размер. В связи с чем происходит наложение второй строки на первую, третьей на вторую и т.д.
Другие публикации цикла
3. ИКФ: высота строки, часть 1 (3-я публикация цикла “Тайны CSS2.1″).
5. ИКФ: высота строки, часть 3 (5-я публикация цикла “Тайны CSS2.1″).
6. ИКФ: высота строки, часть 4 (6-я публикация цикла “Тайны CSS2.1″).
7. ИКФ: высота строки, часть 5 (7-я публикация цикла “Тайны CSS2.1″).
8. ИКФ: Вертикальное выравнивание в строке, часть 1 (8-я публикация цикла “Тайны CSS2.1″).
9. ИКФ: Вертикальное выравнивание в строке, часть 2 (9-я публикация цикла “Тайны CSS2.1″).
10. ИКФ: Вертикальное выравнивание в строке, часть 3 (10-я публикация цикла “Тайны CSS2.1″).
11. ИКФ: Горизонтальное выравнивание, часть 1 (11-я публикация цикла “Тайны CSS2.1″).
12. ИКФ: Горизонтальное выравнивание, часть 2 (12-я публикация цикла “Тайны CSS2.1″).
Нам необходимы ваши конструктивные коментарии в наших статьях! Пожалуйста, не проходите мимо.
P.S. Это тоже может быть интересно:
на сколько я помню "свинцовых полосок" ни что иное как шпация
ан нет ошибся шпация для меж словных пробелов, а шпоны для межстроковых
"leading" — это интерлиньяж. "Междустрочие" — страшный термин какой-то, где вы его взяли)?
Соответственно, высота строки и интерлиньяж — не одно и то же.
Всё не так просто. В современных источниках по-русски интерлиньяжем чаще называют именно 'line-height' (1, 2, последний абзац в 3). Даже в обсуждении статьи в Википедии не избежали путаницы.
Не переводить, наверное, безопаснее :)
Безопаснее упоминать о путанице тогда уж :)
Тоже верно.
Читал ваши статьи, сплошная вода. Очень тяжело воспринимается и практического применения не вижу.
Воообщем искал ответ на свой вопрос, но прочитав все ваши статьи про "тайны ксс" так и не нашёл ответ: есть Загловок h1 ( 21px/22px — высота шрифта и лайн-хейт соотв., ещё стоит добавить что он bold) Под ним есть p (параграф 12px/18px) (паддингов и маргинов нет — они сброшены файлом reset.css)
Какое будет расстояние между этими строчками? (шрифт Ариал самый обычный) и какое задать расстояние что бы расстояние от базовой линии параграфа p до базовой линии заголовка h1 было 27px?
Да, интересная задачка.
Исходя из этой статьи, можно предположить, что лайн-хейт в большинстве случаев, «исходит» из середины текстовых площадок, по-умолчанию халф-лидинги равны половине высоты шрифтовой площадки. Правда тут есть нюансы, сам интерлиньяж показывает расстояния между базовыми линиями и равен высоте очка (расстояние между самыми высокими выносными элементами сверху и самыми низкими снизу) + верхние и нижние заплечики + расстояние между строчками (шпон, для небольших размеров шрифта Хром и Лиса назначают на это дело по одному пикселю, правда Лиса добавляет шпон и к верхней строчке блока. Вот здесь наглядно — http://indians.ru/a-font-sizes.htm — правда остаётся главный вопрос, что же показывает кегель шрифта, если шрифты одинакового кегля несколько различаются как по размеру самих грифов, так и по размеру текстовых площадок).
Возникает вопрос, что из этого, в нашем случае, будет от верхнего шрифта, а что от нижнего, каким образом это мерить? Если у нас размер шрифтов одинаковые, то расстояние от середины шрифта до базовой линии тоже одинаковое, а если разные, то мы можем назначить расстояния между серединами, но расстояния от этой середины до базовой линии будут разные.
Значит нам нужно «посадить» наши строчки на базовые линии с одинаковыми размерами шрифтов. Вот, как-то так можно попробовать: https://jsfiddle.net/Launder/96s04b5r/4/
ЗЫ: ну почему 28 и 26, думаю, ясно, пиксель всё же целая величина, и если мы 27 разделим на два непонятно как он округлится, кроме этого, нам желательно чтоб размер line-height был больше размера шрифтовых площадок. Поскольку когда лайн-хейт меньше шрифтовых площадок, то центр «исхождения» лайн-хейт может смещаться: https://jsfiddle.net/Launder/gmg3u1tL/2/ (предпоследний пример).
Для p, размер лайн-хейта значительно больше шрифтовых площадок, так что можно не волноваться, а для h — желательно перестраховаться, насколько видно по полосочкам сверху и снизу шрифтовых площадок(я думаю что спаны как раз им соответствуют), у нас всё нормально.
Впрочем, поскольку размер пикселя равен 1/96 дюйма (таким образом, чтоб при этом умещалось целое число экранных пикселей, поэтому значение примерное), указание дробных пикселей, по видимому, не запрещено спецификацией CSS 2.1.
Тем не менее, когда нужна высокая точность, насколько я понимаю, чаще используют rem-ы, поэтому пример, пожалуй, можно решить так: https://jsfiddle.net/Launder/96s04b5r/5/
У Вас, наверное, опечатка:
«Размер шрифта я выставил 30px» Вы жирным выделили 0px, а хотели, наверное, выделить 30px.
Исправьте, пожалуйста, и, наверное, удалите это моё особо ценное сообщение :-)
Отрицательный leading
«Ну, и, конечно же, высота укорачивается с двух сторон в абсолютно одинаковой степени.»
Похоже есть нюансы, как строчный элемент «ползёт» относительного своего содержащего блока. А именно, ползёт вверх :-)
https://jsfiddle.net/Launder/gmg3u1tL/2/
(возможно будут ещё апдейты этого поля)
последний и предпоследний пример. в текущем апдейте комментарии и CSS-код начиная с 46 строчки.
если не в лом, можете посмотреть остальные примеры и вопросы в этом примере. но писал это я больше для себя, поэтому там всё это не слишком причёсанное. поэтому, если влом — как более чётко сформулирую — задам вопросы отдельно.