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

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

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

Самой первой популярной техникой была так называемая FIR (она же — Fahrner Image Replacement), которая появилась в 2003-м году. Она проста как пень, и многие начинающие верстальщики ее до сих пор используют:

<style type="text/css">
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.

И, напоследок, еще один похожий вариант из той же ветки с симпатичной css-анимацией:

Hello World

This is example content.

UPD: Chris Coyier проделал огромную работу и собрал целый музей, посвященный техникам Image Replacement: CSS Image Replacement Museum

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *