• 0
Arinden

Кроссбраузерность line-height или как правильно центровать текст по вертикали

Вопрос

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

HTML:

<div class="lineHeight">
  HELLO // line-height method
</div>
<div class="padding">
  HELLO // padding method
</div>

CSS:

@import url('https://fonts.googleapis.com/css?family=Open+Sans');

div {
  font-family: 'Open Sans', sans-serif;
  font-size: 14px;
  height: 100px;
  background: lightgreen;
  margin: 5px;
  padding-left: 10px;
  box-sizing: border-box;
}

.lineHeight {
  line-height: 100px;
}

.padding {
  padding-top: 42px; /* (100px - 14px) / 2 - 1px */
}

Ситуация следующая:

В случаях с line-height и padding текст ровно по центру, отступы по 45px сверху и снизу:

001.png

- Google Chrome (v. 55.0.2883.87 m);
- Mozilla Firefox (v. 50.1.0);
- Opera (v. 42.0.2393.94);
- Safari (macOS, v. 10.0 12602.1.32.7);

Для line-height отступы по 45px, для padding 46px сверху и 44px снизу:

002.png

- Safari (Windows, v. 5.1.7 7534.57.2);

В случаях с line-height и padding текст ровно по центру, отступы 46px сверху и 44px снизу:

003.png

- Internet Explorer 11 (v. 11.576.14393.0);
- Microsoft EDGE (v. 38.14393.0.0);

Я понимаю, что в ряде случаев это не принципиально, но что делать если блок с текстом это, например, меню, а сбоку от текста расположена ровная иконка, положение которой задано через background-position. Выравниваешь иконку для одного браузера - плывёт в другом. Выглядит весьма заметно и некрасиво. И Бог бы с этим эксплорером, но дело вот в чём, на Android 6.0.1 (device pixel ratio 4.0) стандартный интернет браузер, а также скаченный Google Chrome центруют неровно, также наблюдается расхождение в 1 пиксель, а вот на это уже закрывать глаза не хочется (большой скрин с Android):

Скрытый текст

004_.png

Что примичательно, высота первой буквы на настольных компьютерах 10px, а на андроиде чуть больше.

Разумеется добиться идеальной картинки, да ещё и во всех браузерах одновременно, невозможно, но ведь это не какой-то частный случай, а вполне закономерное желание разместить текст по центру меню-бара. Я буду очень признателен за Вашу помощь и пояснения на предмет "best-practices".

Что я пробовал для решения данной проблемы:

- Использовал разные шрифты, а также разные методы подключения внешних шрифтов: link через html / @import в CSS для Google Fonts, а также @font-face url для скаченных шрифтов;
- Задавал размеры шрифта, отступы, line-height в em / rem / px;
- Пробовал различные комбинации line-height + padding;
- Для создания иконок меню пробовал псевдо элементы, это конечно же решает проблему расположения иконок относительно текста, но не решает проблему центровки по вертикали.

P.S. CSS сброшен. Meta viewport задан.

Доп. вопрос от новичка: Почему, задавая размер шрифта 14px, заглавная буква по факту занимает 10px? При этом если я использую буквы типа "Й" и "р", высота занимаемая текстом будет уже 16px, но никак не 14px. Что-же задают тогда эти пиксели в размере шрифта?

Изменено пользователем Arinden

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

8 ответов на этот вопрос

  • 1

Браузеры все равно будут немного по-разному расчитывать эти размеры. Идеального соответствия вы не добъетесь. Все, что можно сделать, привязать иконку к тексту. Прыгать все равно будут, но уже вместе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

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

https://jsfiddle.net/p4710ymL/

  j85YlYL.png

Ну и вместо вот этого

(100px - 14px) / 2 - 1px

лучше явно задать line-height и считать от него

(100px - <line-height>) / 2

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

Текстовый узел лучше оберни в элемент и сбрось ему высоту строки line-height:1. Тогда никаких лишних отступов у текста не будет. С иконкой поступи аналогично. А для выравнивание элементов подключай флекс модуль и оперируй его свойствами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
7 часов назад, Igor Schnaider сказал:

Вы не правильно замеры делаете. ... Шрифты все разные, высота букв будет отличаться.

Согласен, спасибо. Но шрифт для замеров импортирован в CSS с Google Fonts, получается рендер одного и того же шрифта на разных устройствах - разный? Как-то можно на это повлиять? Спасибо за Ваш пример на JSFiddle, но вот пример отображения в Safari на Windows:

005_.png

, а вот в Internet Explorer 11:

006_.png

Сам жёлтый блок по прежднему отцентрован по разному. При этом, высота жёлтого блока одинаковая, а вот его положение - нет, как бы я не производил замеры... =(

4 часа назад, by chris сказал:

Текстовый узел лучше оберни в элемент и сбрось ему высоту строки line-height:1. Тогда никаких лишних отступов у текста не будет. С иконкой поступи аналогично. А для выравнивание элементов подключай флекс модуль и оперируй его свойствами.

Спасибо за совет, попробую. Если у Вас есть несколько минут свободного времени, был бы очень рад получить пример с моим кодом на JSFiddle. :unsure:

Изменено пользователем Arinden

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
33 минуты назад, Arinden сказал:

но вот пример отображения в Safari на Windows

Вероятно, какие-то особенности у Safari для Windows. Но я не думаю, что на него вообще стоит тратить время. Так и до Netscape не далеко :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0
20 минут назад, Igor Schnaider сказал:

Вероятно, какие-то особенности у Safari для Windows. Но я не думаю, что на него вообще стоит тратить время. Так и до Netscape не далеко :-)

Не только Safari. Safari и Internet Explorer и EDGE выводят результат иначе чем Google Chrome для Вашего примера. В Chrome 45px - 40px оба значения.

 

47 минут назад, Switch74 сказал:

я обычно делаю так
https://jsfiddle.net/zfwpurxL/

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

Internet Explorer: 35px 44px;
EDGE: 35px 45px;
Google Chrome: 35px 44px;
Mozilla Firefox: 34px 44px;
Safari: 34px 44px;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
  • 0

разные браузеры по разному округляют некоторые 35,5px превращают в 35px, а некоторые в 36px

если вам нужно везде все одинаково до px делайте выравнивание через свой script.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

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

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Похожие публикации

    • Автор: dandirector
      Вот страница, которая не отображается https://dandirector.github.io/thermasteel/ проблема обнаружена на android 4.2.2 в uc brouser, хотел бы отметить, что вместо верстки видно просто белый экран. В других браузерах все гуд.
    • Автор: Joka
      Мобильная версия сайта скроллится идеально на андроиде http://imgur.com/XeFTTES
      Но на айфоне скролл ломается и он нереально быстрый http://imgur.com/5UruYUI
      Заметил, что при открытии сайта на айфоне в код добавляется новый <div> и правка в <body>, хотя в index.html их нет 
      <body class="scroll_wrapper" style="top: -184.702px; left: 0px;"><noindex></noindex><div id="webit_scroll_provider_wrapper" class="html" style="padding-top: 0px; padding-bottom: 0px; width: 100%; min-width: 480px;"> Так же в CSS нашел это: 
      .scroll_wrapper{ position: absolute; overflow: auto; left: 0px; right: 0px; top: 0px; bottom: 0px; padding-top: 0px; padding-bottom: 0px; margin-top: 0px; margin-bottom: 0px;} Но никак не пойму в чем проблема. Помогите, пожалуйста. Как исправить?
    • Автор: ekkl
      Есть плавающий блок содержащий одну строку за ней следует два значка (icon-font)
      Проблема в том, что значки визуально выше строки текста. Чего я только не пробовал и line-height и padding/margin все равно значки выше строки.
      Еще меня волнует непонятный отступ внутреннего контейнера от нижнего края плавающего блока. margin / padding здесь кадется ни при чем.
      Стили (LESS) и контейнер
      #confirm { position: absolute; height: auto; border: 1px #230D33 solid; z-index: 1000; display: inline-block; overflow: hidden; text-indent: 0; box-sizing: border-box; background: #f9f0ff; box-shadow: 0 0 6px rgba(0, 0, 0, 0.5); .content { padding: 2px 8px; display: inline-block; font-size: 12px; line-height: 24px; overflow: hidden; width: 250px; box-sizing: border-box; } .conflink { display: inline-block; } a { width: 100%; color: #333; font-size: 20px; text-decoration: none; margin-left: 1em; outline-color: #EAC9FF; } a[role="ok"]:hover { color: forestgreen; } a[role="cancel"]:hover { color: #C22; }} <span id="confirm"><span class="content">{{message}}?<span class="conflink"><a href="#" role="ok" data-icon="B"></a><a href="#" role="cancel" data-icon="A"></a></span></span></span> Все в действии http://jsbin.com/wekixa/26/edit?css,js,output