Запасной вариант CSS для маленьких заглавных букв OpenType

Я работаю над сайтом, где важны маленькие заглавные буквы: настройка текста Библии. В Ветхом Завете имя Бога транслитерируется как Lord, но маленькими заглавными буквами, а не LORD. Однако состояние поддержки малых заглавных букв OpenType на данный момент… далеко не оптимальное. Safari (даже Safari 8 на Yosemite, из которого я пишу это) по-прежнему не поддерживает опцию -webkit-font-feature-settings: 'smcp', и многие обращения к этому веб-сайту будут поступать с мобильных устройств.

К сожалению, «изящная деградация» здесь проблематична: если вы укажете как font-variant: small-caps, так и font-feature-settings: 'smcp' в браузере, который поддерживает последний (например, Chrome), объявление font-variant переопределит его, поэтому ужасно уродливая версия в старом стиле все еще вступает в игру. (Примечание: это должно быть в соответствии с спецификацией. : объявление font-variant имеет более высокий приоритет, чем объявление font-feature-settings). Однако, учитывая текущую реализацию font-variant: small-caps — уменьшенные заглавные буквы, а не настоящие маленькие заглавные — результатом является то, что использование реалистов font-variant: small-caps не так изящно ухудшает качество чтения всех.

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

Хотя я могу сделать то же самое здесь (и, по крайней мере, теоретически мог бы создать довольно мелкий шрифт, поскольку мне действительно нужны только три символа: o, r и d), я бы предпочел просто включить разумные запасные варианты. Однако, как отмечалось выше, это невозможно. Я открыт, но предпочел бы избегать решений на стороне сервера (обнаружение браузера и т. д.) как сложность, которую лучше свести к минимуму, особенно с учетом того, как быстро меняются браузеры. Как еще можно решить эту проблему, и особенно существуют ли для нее решения?

Редактировать: уточнение на основе комментариев — в будущем font-variant: small-caps прекрасно с этим справится, согласно спецификации, он должен отображать вариант шрифта с маленькими заглавными буквами, если он предоставляется шрифтом. Однако в настоящее время ни один браузер не поддерживает это (по крайней мере, я не могу найти!). Это означает, что вместо этого все они отображают поддельные маленькие заглавные буквы, просто уменьшая настоящие заглавные буквы. Результат типографически неприятный и неприемлемый для этого проекта.


person Chris Krycho    schedule 20.07.2014    source источник
comment
Что именно не так с использованием варианта шрифта?   -  person user1795832    schedule 20.07.2014
comment
font-variant: small-caps следует использовать шрифт, запеченный маленькими заглавными буквами, если он присутствует, поэтому вам не нужно включать функцию smcp, базовый CSS уже должен работать правильно.   -  person Mike 'Pomax' Kamermans    schedule 20.07.2014
comment
@user1795832 user1795832, использование font-variant в настоящее время имеет недостаток, заключающийся в том, что в нем не используются фактические маленькие заглавные буквы; это просто уменьшает масштабы столиц. С точки зрения типографики это неприятно и всегда было так. @Mike'Pomax'Kamermans, это верно в теории, но это не работает ни в одном браузере, который я тестировал, и страницы MDN сообщают то же самое - нет поддержки для этого. Похоже, поставщики поддерживают только низкоуровневые дескрипторы (например, 'smcp') до тех пор, пока спецификация CSS3 не будет завершена, не поддерживают высокоуровневые объявления (поэтому также не поддерживаются font-variant-ligatures и т. д.).   -  person Chris Krycho    schedule 20.07.2014
comment
Спасибо за этот вопрос! Не могли бы вы вкратце описать метод, который вы использовали для создания отдельной версии Gentium для небольших компаний?   -  person chicken    schedule 02.09.2014
comment
@LeoKoppelkamm Я обновил ответ ниже, добавив подробности об использовании FontSquirrel для создания версии с маленькими заглавными буквами.   -  person Chris Krycho    schedule 05.09.2014


Ответы (4)


Последнее обновление: 28 февраля 2016 г.

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

@supports

Воспользуйтесь правилом @supports в браузерах. Это то, что я изначально решил сделать в этом проекте.[1] Вы используете правило следующим образом:

.some-class {
    font-variant: small-caps;
}

@supports(font-feature-settings: 'smcp') {
    .some-class {
        font-variant: normal;
        font-feature-settings: 'smcp';
    }
}

Я упростил, исключив версии с префиксом; вам нужно будет добавить префиксы -webkit- и -moz-, чтобы это действительно заработало. Обновление от 28 февраля 2012 г. вам больше не нужен префикс -moz-, и он будет работать в Safari в следующей версии (iOS 9.3 и OS X Safari 9.1).

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

Это не идеально: поскольку IE10/11 не реализует @supports, вы пропускаете один браузер. (Редактировать, 31 сентября 2015 г. В IE нет @supports, но в Edge 12+ есть, и это должно охватывать всех пользователей сайта.) Тем не менее, это дает вам большую часть пути, и это должно быть обращено в будущее: это должно постепенно улучшать сайт. Обычные (плохие, но функциональные) маленькие заглавные буквы отображаются в то же время, и когда браузеры в конце концов доберутся до использования маленьких заглавных букв OpenType по умолчанию для font-variant: small-caps, это будет продолжать работать нормально. Это прогрессивное улучшение, и оно отлично подойдет для большинства целей.[2]

Подмножество шрифта

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

Чтобы осуществить это, вам нужно начать с подстановки шрифта. Вы можете сделать это вручную с помощью инструмента шрифтов или (более простой способ) вы можете использовать пользовательский инструмент поднастройки FontSquirrel в их генератор веб-шрифтов. (Примечание. Вы должны проверить лицензию и подтвердить, что рассматриваемый шрифт допускает такие модификации. См. ниже.) В веб-шрифте генератор, сначала загрузите файл, который вы хотите изменить. Затем выберите переключатель Эксперт. Большинство настроек можно оставить как есть; это хорошие разумные значения по умолчанию. В середине страницы вы увидите параметры Сведение OpenType. Здесь выберите только маленькие заглавные буквы. Запустите генератор. Результатом будет полная замена обычных строчных букв набором прописных.[3]

В этом случае вы можете просто применить стиль к элементам, которые вы хотите иметь маленькими прописными буквами, например:

.divine-name {
    font-family: 'my_typeface_smcp', 'my_typeface', serif;
}

Основным преимуществом этого подхода является согласованность: этот шрифт будет отображаться в каждом браузере, вплоть до IE5.5, если вы правильно доставите его, используя различные хуки, требуемые @font-face.

Однако у этого подхода есть несколько недостатков:

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

  2. Это может нарушить лицензии рассматриваемых шрифтов. По крайней мере, для одного из шрифтов, которые я использую в этом проекте, это соответствует: лицензия явно запрещает перестраивать шрифт с помощью таких инструментов, как FontSquirrel. (FontSquirrel был инструментом, который я использовал для этого подхода раньше, и он работает довольно хорошо.) Это решающий вопрос для использования подмножества шрифта для достижения цели. При этом, если у вас есть веская причина для этого, вы можете получить поддержку от продавца (особенно если это небольшой магазин). Для проекта, который вызвал этот вопрос, я смог сделать это с помощью приятного электронного письма — дизайнер — отличный парень.

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


Заметки

  1. По разным причинам (особенно см. примечание 2 ниже) я фактически выбрал второй изложенный здесь подход, которого я пытался избежать. Увы.

  2. Проблемы остаются: даже в последней версии Chrome (38 на момент редактирования) использование подхода font-feature-settings: 'smcp' имеет некоторые проблемы. Например, если вы включите letter-spacing (довольно распространенная рекомендация для строчных букв),< s> маленькие заглавные буквы вернутся к обычным строчным буквам. Исправлено в Chrome 48. HT к ответчику ниже.

  3. #P20# <блочная цитата> #P21#
person Chris Krycho    schedule 07.08.2014

Поддержка font-feature-settings:"smcp" в последних браузерах улучшилась. Chrome 48 исправляет ошибку межбуквенного интервала. И, согласно caniuse.com, будущие версии Safari для iOS и рабочего стола будут его поддерживать. Однако версия с префиксом по-прежнему требуется для -webkit.

person sujato    schedule 28.02.2016

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

Используйте параметр font-feature, и если браузер не поддерживает функции opentype, пользователь будет получать все содержимое по-прежнему, причем в худшем случае это будут полноразмерные заглавные буквы; ничего не потеряно. Я бы сказал, что это изящная деградация.

В качестве альтернативы вы можете рассмотреть возможность использования Typogruby (http://avdgaag.github.io/typogruby/) или подобное, или вручную добавив класс к этому слову, на которое вы можете настроить таргетинг непосредственно в своем html, подделав его с помощью CSS2, например:

.caps {font-size: .83em; letter-spacing: .25em; text-transform: uppercase;}

Изменить. Конечно, с помощью описанного выше метода вы также можете указать другой шрифт для класса .caps, с полными заглавными буквами, который будет хорошо работать при небольших размерах вместо настоящих маленьких заглавных букв.

person Seth Warburton    schedule 20.07.2014
comment
Увы: изящная деградация здесь не работает. Вы не можете успешно преобразовать заглавные буквы в строчные: LORD ни при каких обстоятельствах не получится правильно: если вы напишете это так и будете использовать прописные, все заглавные станут прописными, включая первый. И Lord не является жизнеспособным вариантом по разным причинам, связанным с проблемой перевода, в первую очередь определяющей все это. Я знаком с подходом к классификации, и вы заметите, что я упомянул его выше. Я ищу любые известные другие решения. - person Chris Krycho; 20.07.2014
comment
Обратите внимание, что прогрессивное улучшение будет работать… в любой момент, когда спецификация CSS3 будет окончательно завершена. Когда бы это ни было. :п - person Chris Krycho; 20.07.2014

Перестаньте на мгновение думать об OpenType и подумайте о содержании: вам нужны разные стили для семантически разных данных (в данном случае стилизация заглавными буквами для специального религиозного слова). Это буквально то, для чего была изобретена HTML-разметка. Просто автоматически заверните эти слова в разметку <span class="smallcapped"> с помощью javascript, и пусть его класс использует специальный шрифт с маленькими заглавными буквами. Это очень легко сделать, и даже позволяет найти лучший набор малых заглавных букв, независимо от основного шрифта текста.

Просто запускайте некоторый код каждый раз, когда раздел загружается в DOM (категорически не после того, как весь ваш контент будет готов, если только вы не показываете только короткие фрагменты текста):

function wrapSmallcaps(element) {
  var content = element.innerHTML;
  ["LORD"].forEach(function(term) {
    var search = new RegExp("    W?"+term+"  W?",'g');
    content = content.replace(search, function(a,b) {
      return a.replace(term, "<span class='smallcapped'>"+term+"</span>");
    });
  });
  element.innerHTML = content;
}

пример: http://jsbin.com/cowumaxe/1/edit

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

(и, конечно, этот код буквально универсален для любого браузера, начиная с IE8 -- http://caniuse.com/#search=queryselector не показывает «нет поддержки» или даже «частичная поддержка» для всех браузеров, которые люди фактически используют)

person Mike 'Pomax' Kamermans    schedule 21.07.2014
comment
Да, это будет работать, хотя весь Javascript не нужен, так как у меня есть классы в исходниках. В любом случае обратите внимание, что я отметил это как одно из возможных решений в своем вопросе. Я искал альтернативы. :) - person Chris Krycho; 21.07.2014
comment
Если у вас уже есть классы в исходниках, то еще проще. Считайте этот ответ также замечанием о том, что даже если вы ищете альтернативы, это не означает, что альтернативы лучше. Даже когда браузеры полностью поддерживают весь OpenType, разметив исходный код, измените, какие части OpenType вам нужны: некоторые функции OpenType, такие как маленькие заглавные буквы (в отличие от лигатур и т. д.), имеют смысл только в контекстах набора текста, где нет доступной явной разметки (в дизайне, слово и др.). Если есть, управление стилем с помощью стилей, связанных с разметкой, бесконечно лучше. - person Mike 'Pomax' Kamermans; 21.07.2014
comment
Как я думаю, вопрос четко указывает: это контекст браузера, не какое-то место, где доступна явная разметка. Даже там активное использование функций OpenType является стандартом; существование отдельных маленьких заглавных букв вряд ли можно назвать инновацией, созданной браузерами: это многовековая практика, доступная через OpenType. - person Chris Krycho; 22.07.2014
comment
А? Контекст браузера буквально находится там, где в исходном коде доступна явная разметка. Вы сказали, что у вас уже есть классы в исходном коде, поэтому для меня это означает, что у вас есть [...] the <span class='lord'>lord</span> said [...]. Да, OpenType — это стандарт в Интернете, и я люблю OpenType, но функции с маленькими заглавными буквами — это одна из тех вещей, которые не имеют смысла в качестве слепых функций в Интернете (в отличие от номеров в старом стиле или росчерков и т. д.), потому что они буквально меняют шрифт. . Отдельный шрифт OpenType для заглавных букв, примененный к разметке для ваших слов, требует другого шрифта, это намного лучше. - person Mike 'Pomax' Kamermans; 22.07.2014
comment
Это… не то, как работают маленькие заглавные буквы OpenType, и OpenType как стандарт намного шире, чем Интернет (и не был изобретен для Интернета). Он работает точно так же, как и лигатуры: он заменяет другие символы в зависимости от контекста. Он использует тот же шрифт, просто делая соответствующие преобразования. Может быть, мы просто говорим мимо друг друга? - person Chris Krycho; 22.07.2014
comment
мы могли бы быть. Я знаю, как работает OpenType, писал для них парсеры и статьи о них; аргумент, который я приводил, заключался в том, что полагаться на замену маленькой заглавной буквы в среде, которая позволяет стилизовать на основе семантической разметки, не имеет смысла, чем разметка данных, требующая стиля маленькой заглавной буквы, и простое использование специального шрифта с маленькими заглавными буквами. , так как маленькие заглавные буквы — это просто еще один стилистический набор: альтернативный шрифт, закодированный в том же файле шрифта. Таким образом, использование разметки шрифтом с маленькой заглавной буквой вместо GSUB с маленькой заглавной делает ваш контент поддерживаемым практически во всех браузерах, как прошлых, так и будущих. - person Mike 'Pomax' Kamermans; 22.07.2014
comment
Я полагал, что мы должны были быть. :p Как отмечалось в оригинальном посте, лучшее решение, которое я придумал на сегодняшний день, в значительной степени зависит от такой разметки (или иного доступа через правила CSS, например, p:first-line) и прямой замены шрифта. В данном случае кажется, что это лучшее решение: шрифт, который заменяет обычные символы их эквивалентами с маленькими заглавными буквами и предоставляет этот шрифт в соответствующие файлы. (Это то, что я сейчас делаю на своем собственном веб-сайте, поэтому я знаю, что это работает надежно.) Спасибо за обсуждение! - person Chris Krycho; 22.07.2014