Хотелось бы поговорить о техниках замены текста изображением. Думаю, практически все сталкивались с моментами в верстке, когда, к примеру, для заголовка страницы нужно использовать графический объект, при этом сохранив под ним текст и для поисковых роботов, и для печатной версии. Да и в принципе, никогда не хочется ломать семантинку страницы.
Самой первой популярной техникой была так называемая FIR (она же — Fahrner Image Replacement), которая появилась в 2003-м году. Она проста как пень, и многие начинающие верстальщики ее до сих пор используют:
Знакомая штука? По сути, внутрь тега, в фоне которого лежит наша картинка, мы добавляем инлайновый тег, который дублирует текст на картинке, а потом его скрываем с помощью display:none;
Многие сразу же признали кривизну этой техники, как с точки зрения семантики, так и с точки зрения утяжеления html лишними тегами. Ко всему прочему, ее полюбили серые оптимизаторы, в результате чего некоторые поисковые системы применяли санкции к страницам, перегруженным такими объектами.
Как видно, здесь был использован хак для IE5.5, в котором совсем все плохо было с блочной моделью. Впоследствии, эта техника не прижилась, так как переставала работать в ряде случаев, плюс многие не любят хаки.
После всего этого появилась на свет техника Phark’s Accessible Image Replacement, которая является самой популярной на текущий момент и состоящая всего из одной строки:
Техника не идеальна, однако если не забывать о некоторых нюансах ее работы, то она сойдет для большинства случаев. В частности, проверять, чтобы text-align был направлен в ту же сторону, что и text-indent (в большинстве случаев — text-align:left). А также, не забывать, что применив ее на элемент со свойством display: inline-block;, этот элемент улетит в IE7 вслед за скрываемым текстом.
Я, как и многие, был приверженцем "-9999px", но в то же время понимал, что это не самый лучший вариант и что должно быть более красивое решение этой задачи. Каждый раз, прописывая -9999px, я задумывался а не повлияют ли эти пиксели на сайт в будущем.
И вот, несколько дней назад товарищ Zeldman предложил такой вариант:
Такой способ решает сразу несколько проблем:
Однако этот способ также не идеален — если на элементе есть padding, то часть текста будет из него выглядывать. Проблема решается обнулением паддингов для тех блоков, где скрывается текст.
Вариант Зелдмана немного оживил ведущих фронт-енд разработчиков, которые ведут оживленные дискуссии в комментах и блогах.
Также, он был замечен командой разработчиков html5boilerplate, которые сейчас активно дискутируют на github на тему включения нового способа скрытия текста в набор вспомогательных классов своего бойлерплейта.
Этот способ тоже кроссбраузерен — проверено в IE7-10, Opera 11.61, Chrome 17.0, Firefox 10.0, и Safari 5.1.2. Правда, для старых браузеров такой вариант не прокатит — многие из них не понимают нулевое значение шрифта. Например, какой-то из старых Safari вместо нуля может принять значение 6 или 8.
Большую часть информации об истории и новом способе почерпнул из этого поста
UPD: Еще один интеренсный метод от Николаса Галлахера с псевдоэлементом, спасибо за подсказку SelenIT2
UPD2: В комментах к html5-boilerplate на гитхабе появились результаты теста трех способов IR (отрицательный text-indent, положительный text-indent и font: 0/0 a) в нескольких скринридерах. Вариант с font: 0/0 a не фурычит в Window-Eyes (как я понял, вымирающем, его сравнивают с IE5.5), остальное работает везде (хотя при положительном text-indent текст становится видимым во время его озвучки в старых версиях JAWS).
Спасибо SelenIT2, ссылка на комментарий
UPD3:Chris Coyier проделал огромную работу и собрал целый музей, посвященный техникам Image Replacement: CSS Image Replacement Museum
Немного об истории решения этого вопроса.
Самой первой популярной техникой была так называемая FIR (она же — Fahrner Image Replacement), которая появилась в 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></code>
Знакомая штука? По сути, внутрь тега, в фоне которого лежит наша картинка, мы добавляем инлайновый тег, который дублирует текст на картинке, а потом его скрываем с помощью 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.
Большую часть информации об истории и новом способе почерпнул из этого поста
UPD: Еще один интеренсный метод от Николаса Галлахера с псевдоэлементом, спасибо за подсказку SelenIT2
UPD2: В комментах к html5-boilerplate на гитхабе появились результаты теста трех способов IR (отрицательный text-indent, положительный text-indent и font: 0/0 a) в нескольких скринридерах. Вариант с font: 0/0 a не фурычит в Window-Eyes (как я понял, вымирающем, его сравнивают с IE5.5), остальное работает везде (хотя при положительном text-indent текст становится видимым во время его озвучки в старых версиях JAWS).
Спасибо SelenIT2, ссылка на комментарий
UPD3:Chris Coyier проделал огромную работу и собрал целый музей, посвященный техникам Image Replacement: CSS Image Replacement Museum