Каскадные Таблицы Стилей / Новый метод замены текста картинкой, или избавляемся от -9999px

в 23:24, , рубрики: css, html-верстка, переводы, метки: , ,

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

Каскадные Таблицы Стилей / Новый метод замены текста картинкой, или избавляемся от  9999px

Немного об истории решения этого вопроса.

Самой первой популярной техникой была так называемая FIR (она же — Fahrner Image Replacement), которая <a rel="nofollow" href="http://www.zeldman.com/daily/0703b.shtml#firflies">появилась в 2003-м году. Она проста как пень, и многие начинающие верстальщики ее до сих пор используют:

<style>
h1.text-hide span { display: none; }
h1.text-hide {
height: 35px; /* height of the replacement image */
background-image: url("hello-world.gif");
background-repeat: no-repeat;
}
</style>
<h1 class="text-hide"><span>Hello world!</span><h1>

Знакомая штука? По сути, внутрь тега, в фоне которого лежит наша картинка, мы добавляем инлайновый тег, который дублирует текст на картинке, а потом его скрываем с помощью display:none;
Многие сразу же признали кривизну этой техники, как с точки зрения семантики, так и с точки зрения утяжеления html лишними тегами. Ко всему прочему, ее полюбили серые оптимизаторы, в результате чего некоторые поисковые системы применяли санкции к страницам, перегруженным такими объектами.

В том же году появилась еще одна техника замены. Работала она примерно так:

#ID_OF_ELEMENT {
padding: HEIGHT_OF_IMAGEpx 0 0 0;
overflow: hidden;
background-image: url("hello_world.gif");
background-repeat: no-repeat;
height: 0px !important;
height /**/:HEIGHT_OF_IMAGEpx;
}

Как видно, здесь был использован хак для IE5.5, в котором совсем все плохо было с блочной моделью. Впоследствии, эта техника не прижилась, так как переставала работать в ряде случаев, плюс многие не любят хаки.

-9999px

После всего этого появилась на свет техника Phark’s Accessible Image Replacement, которая является самой популярной на текущий момент и состоящая всего из одной строки:

.text-hide {
text-indent: -9999px (или -999em);
}

Техника не идеальна, однако если не забывать о некоторых нюансах ее работы, то она сойдет для большинства случаев. В частности, проверять, чтобы text-align был направлен в ту же сторону, что и text-indent (в большинстве случаев — text-align:left). А также, не забывать, что применив ее на элемент со свойством display: inline-block;, этот элемент улетит в IE7 вслед за скрываемым текстом.

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

Новое решение

И вот, несколько дней назад товарищ Zeldman предложил такой вариант:

.text-hide {
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
}

Такой способ решает сразу несколько проблем:

  • Во-первых, можно быть уверенными, что даже самый длинный текст, который скрывается, никогда не достигнет видимого контейнера, даже если длина этого текста будет превышать 9999px
  • Во-вторых, сначала обнаружилась, а потом этим же способом решилась проблема, которая состояла в следующем: каждый раз при задании -9999px в dom-дереве добавлялся невидимый блок такой ширины. И если на обычных браузерах это сказывалось мало, то на iPAD обнаружились серьезные проблемы с производительностью анимации (демо для проверки)

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

Вариант Зелдмана немного оживил ведущих фронт-енд разработчиков, которые ведут оживленные дискуссии в комментах и блогах.
Также, он был замечен командой разработчиков html5boilerplate, которые сейчас активно дискутируют на github на тему включения нового способа скрытия текста в набор вспомогательных классов своего бойлерплейта.

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

.text-hide {
font: 0/0 serif;
text-shadow: none;
color: transparent;
}

Этот способ тоже кроссбраузерен — проверено в IE7-10, Opera 11.61, Chrome 17.0, Firefox 10.0, и Safari 5.1.2. Правда, для старых браузеров такой вариант не прокатит — многие из них не понимают нулевое значение шрифта. Например, какой-то из старых Safari вместо нуля может принять значение 6 или 8.

Большую часть информации об истории и новом способе почерпнул из этого поста

Автор: derSmoll


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js