«Font-weight: bolder» для шрифтов со множеством начертаний

Если вы используете шрифт со множеством начертаний, то вам, вероятно, захочется, чтобы теги strong и b не увеличивали жирность шрифта до фиксированного значения font-weight:700, как это происходит по-умолчанию, а использовали промежуточные значения, рассчитанные исходя из жирности шрифта родительского элемента.
Ведь не очень красиво, когда в ультратонком шрифте появляются жирные кляксы тегов strong.


Возьмём для примера Open Sans.

Open Sans и все его начертания
Open Sans имеет пять начертаний: Light 300, Normal 400, Semi-Bold 600, Bold 700 и Extra-Bold 800.
Цифры соответствуют значению font-weight.

Пусть основной текст имеет начертание Light 300, заголовки и цитаты — Normal 400, а промо-блок — Semi-Bold 600:

body {
  font-family: 'Open Sans', sans-serif;
  font-weight: 300;
}
h1, h2, h3, h4, h5, h6,
blockquote {
  font-weight: 400;
}
.promo {
  font-weight: 600;
}


Тег strong может встечаться и в основном тексте, и в цитатах, и промо-блоке. Надо это учесть.

По-умолчанию:

strong, b {
	font-weight: bold; /* bold = 700 */
}


А нам хочется, чтобы у strong и b для основного текста было Normal 400, для цитат и заголовков — Bold 700, а для промо блока — Extra-Bold 800. Это сохранит контраст между жирным и нежирным текстом примерно равным во всех случаях.

Уверен, многие пробовали использовать strong {font-weight: bolder;}, но это не принесло ожидаемого результата — текст стал ещё жирнее, чем ожидалось.

А всё потому, что согласно спецификации, значение bolder (lighter) увеличивает (уменьшает) унаследованное значение font-weight до следующего возможного для данного шрифта значения, согласно следующей таблице.

наследуемое значение bolder lighter
100 400 100
200 400 100
300 400 100
400 700 100
500 700 100
600 900 400
700 900 400
800 900 700
900 900 700


Но в браузерной CSS прописано strong, b {font-weight: bold;}, т.е. унаследуется значение «700», а потом оно ещё и увеличивается до «900». Поэтому кажется, что bolder работает неправильно.

Исправить это можно так:

/* сбрасываем стандартное «bold», 
шрифт становится таким же как его родительский элемент */
strong, b {
  font-weight: inherit; 
}

/* теперь bolder будет вычисляться исходя из веса шрифта родительского элемента */
strong, b {
  font-weight: bolder;
}


Именно так, как два отдельных правила. Первое обнуляет значение font-weight из браузерной таблицы стилей, второе задаёт жирность уже в относительных, а не абсолютных единицах.

Теперь нам не придётся заботиться о вложенности элементов — каскад всё сделает автоматически. Мы можем вкладывать теги strong друг в друга.


Вложенные теги «strong». Толщина шрифта определяется исходя из значения родительского элемента.
Демка


Ограничения


Используя относительные значения font-weight мы получаем только по три градации жирности шрифта для bolder и lighter соответственно. Спецификация не гарантирует, что браузеры правильно сопоставят названия начертаний и числовые значения. Не гарантирует, что для шрифта найдётся более жирное или более тонкое начертание. У некоторых шрифтов всего два начертания, у некоторых может быть восемь.

Единственной гарантией при использовании bolder / lighter является то, что шрифт при значении «bolder» не будет тоньше, чем более легкие начертания этого шрифта, а при значении «lighter» будет не толще, чем более жирные начертания этого шрифта.

Чтобы более тонко настроить вес шрифта, надо использовать абсолютные значения.

Баги


Если у вас шрифт установлен в системе, но не подключен через @font-face, то Google Chrome определяет только Normal и Bold начертания шрифта. Чтобы локальный шрифт заработал, нужно дополнительно указать его font-family.

.fw300 {
  font-family: "Open Sans Light", "Open Sans";
  font-weight: 300;
}
.fw600 {
  font-family: "Open Sans SemiBold", "Open Sans";
  font-weight: 600;
}

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 8

    0
    Спасибо за рецепт. Редко вспоминаю про «inherit» в своей практике, хотя порой оно очень полезно и позволяет писать более гибкий код.
      0
      А мне кажется или у OpenSans действительно просто отвратительный кернинг для русского начертания?
        0
        Да вроде всё ровненько
          0
          Вот зашел на www.google.com/fonts# из Google Crome.




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

          Или у меня паранойя, доктор?
        0
        Первая картинка сжата по горизонтали, я сначала не поверил, что это OpenSans. Честно говоря, захотелось, чтобы он где-то таким бы и был, а то широкие знаки утомляют.
          0
          Это потому, что у меня в коде тега img остались width и height. Уже исправил. Любуйтесь пропорциональным ОпенСансом.
        • UFO just landed and posted this here
            0
            Да, под виндой. На винде я проверил Open Sans, Segoe UI и Source Sans Pro. В Хроме только два начертания видно. В остальных браузерах — все. На маке ещё не было возможности проверить.

            Вообще, этот баг заслуживает отдельного исследования. В багтрекере вебкита я его не нашел. Может, с некоторыми шрифтами работает. А с учётом того, что спецификация «не гарантирует» правильность сопоставления браузером начертания шрифта и его font-weight, то может это и не баг вовсе.

          Only users with full accounts can post comments. Log in, please.