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

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



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


    Самой первой популярной техникой была так называемая 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
    Поделиться публикацией

    Комментарии 87

      0
      Да, заранее прошу прощение за форматирование, первый пост :(
        0
        А ларчик-то просто открывался )))
        Спасибо!
        • НЛО прилетело и опубликовало эту надпись здесь
            0
            Еще можно использовать способ line-height: 9999em; который вытолкнет текст не в стороны а вниз. И который также не зависит от выравнивания.
              0
              Я уже давно втаких случаях использовал «color: transparent», но без обнуления шрифта. Проблем особых не наблюдается.
                +3
                «В таких» раздельно, конечно же.
                +3
                h1 {
                	background-image:url(img/1326900333.jpg);
                	height:240px;
                	width:384px;
                	background-repeat: no-repeat;
                	
                	color:transparent;
                	overflow:hidden;
                }
                

                Что я сделал не так? link
                Попробуйте выделить картинку.
                  –2
                  А каким методом вы пытаетесь спрятать текст? У вас нет ни padding, ни text-ident, ни font:0…
                    0
                    Очевидно при помощи color: transparent;
                    А overflow: hidden; не даёт «вылазить» тексту дальше указанного элемента.

                    Единственная досадная мелочь − это то, что при выделении текст всё же проявится.
                      0
                      Единственная досадная мелочь − это то, что при выделении текст всё же проявится.


                      Об этом и речь… Чтобы избежать этого и нужен или text-indent:-9999px, или padding:%height_image% px, или font:0
                        +2
                        Или переопределить ::selection.
                        +4
                        Это же здорово! пользователи смогут полноценно копировать контент.
                          0
                          Досадно, но можно красиво стилизировать текст и использовать это как «пасхальное яйцо».
                          0
                          Это был вопрос пользователю IkaR49
                          Просто не на тот линк нажал…
                          Я уже давно втаких случаях использовал «color: transparent», но без обнуления шрифта. Проблем особых не наблюдается

                            0
                            Добавьте «curesor: pointer» или «cursor: default» и пользователю не придёт в голову, что здесь можно что-то выделить :) Костыль, основанный на психологии, но любой метод скрытия текста является костылём. Зато нет проблем с кроссбраузерностью.
                          +1
                          Я вот так делал:
                          del {
                              font-size: 0px;
                              letter-spacing: 0px;
                              color: white;
                              color: transparent;
                              color: rgba(0,0,0,0);
                              text-decoration: none;
                              line-height: 0;
                          }
                          
                          +1
                          А вот вам ещё один способ.
                          Используются псевдоэлементы. Так что IE8+.
                            0
                            Тут обязательно у картинки должен быть фон в цвет background'а родителя. Не подойдёт если используется какая-нибудь текстура.
                              +1
                              Свой пример я написал сразу же после прочтения заголовка поста. Пример как бы намекает, что проблема, поднятая в статье несколько надумана.
                              –1
                              А вот вам ещё один способ.

                              много буков
                              +9
                              А почему бы встраивать шрифты в сайт и писать текст текстом?
                                +5
                                Ну вот, заминусовали и не объяснили. У меня возник похожий вопрос. Есть же cufon, google font в конце концов… Боязнь «утяжелить» страницу?
                                  0
                                  Редко, когда чистый текст, например логотипы. Даже если и будут шрифт подходящий, то придется решать задачу совмещения с графикой. А логически — это единый объект — картинка.
                                    +1
                                    Простите, но логотип это логотип, и он должен быть одной картинкой. В статье же разговор о тексте, например, заголовках.
                                      0
                                      Извиняюсь, ввел в заблуждение. Имел ввиду не логотипы, а иконки.

                                      С лого я согласен на все 100%, что семантически это картинка, а не фон.

                                      Тем не менее, полно плохих примеров, где весь хидер одним джепегов в бекгроунде.
                                    –1
                                    вы вообще сути не поняли или не верстали никогда

                                    Сейчас меню навигации верстают примерно так:
                                    <nav>
                                    	<ul>
                                    		<li><a href="#">главная</a></li>
                                    		<li><a href="#">неглавная</a></li>
                                    		<li><a href="#">контакты</a></li>
                                    	</ul>
                                    </nav>
                                    

                                    При этом ссылки стилизуются всевозможными картинками, в том числе необычной формы и даже вообще без шрифтовых элементов при помощи background-image.
                                    А сама ссылка должна содержать текст для поисковиков, вот его-то и прячут.
                                      +7
                                      Название звучит как: «Новый метод замены текста картинкой, или избавляемся от -9999px». Замена текста. Вот и возникли вопросы.
                                      Если текст для заголовка, который может меняться, то есть более удобные способы, мне кажется.
                                      Если ссылку нужно стилизировать картинкой (домик, например, для возврата на главную), то почему не использовать «alt» и «title»?

                                      Объясните пожалуйста, чем alt у картинки в ссылке хуже скрытого текста с точки зрения поисковика? Если уж речь зашла о них.
                                        +4
                                        Да стилизовать можно как угодно эти пункты меню, прятать текст то зачем? Если пункты меню в виде иконок, то правильнее использовать атрибуты alt и title

                                        А как вы думаете, поисковикам понравится скрытый текст? Это будет напоминать поисковой спам, за который всегда банили.
                                          –4
                                          забавно читать такой ответ от человека, который постит тут мануалы по верстке
                                            +2
                                            К чему вы это написали я не понял, видимо, других аргументов не нашли.

                                            Но может вы приведете конкретный пример в каких случаях приходится прятать текст?
                                            0
                                            Есть желание максимальное количество графики переложить в одно изображение — спрайт.
                                            Тем самым снижая количество запросов к серверу.
                                            • НЛО прилетело и опубликовало эту надпись здесь
                                          0
                                          Насколько я помню, была проблема в рендеринге шрифтов. Они при разных условиях (браузер, ОС) выглядели по разному.
                                            0
                                            Последнее время не замечал такой проблемы. Это у cufon? В каких браузерах, ОС?
                                              0
                                              Извиняюсь. Сейчас проверил в Opera, Firefox, Safari, Chrome все отображается одинаково.
                                              Использовал в одном из проектов его где-то год-полтора назад и были различия, вроде в Opera шрифт отображался не гладким.
                                          0
                                          Все верно, это самый прогрессивный метод. Проблема только в том, что шрифты не сглаживаются пока что. Впрочем, зачастую это и не является проблемой — тогда да, @фонт-фэйс — и вперед.
                                          –2
                                          alt — аттрибут тега img, он не имеет никакого отношения к оформлению элементов стилями
                                          тайтл тоже совсем для других целей
                                            0
                                            ой, это ответ сюда
                                              +5
                                              Ну естественно, alt и title не имеют отношения к оформлению, но вы же говорите о том, что ссылка должна иметь текст для поисковика и использовать картинки (иконки) без текста — не хорошо. Вот и возник вопрос, а почему нельзя использовать иконку в ссылке как картинку и задать ей alt, title на радость поисковикам? В чем минус этой идеи?
                                                –3
                                                Альты привязаны к картинкам и используются для индексации поисковиками этих самых картинок. По ним никакой поисковик не построит карту сайта, что тут сложного, не пойму?
                                                Самый базовый принцип создания ссылок — использование анкоров.
                                                  0
                                                  Кроме того, если вы вставите картинки для кнопок прямо в html, что само по себе противоречит принципу разделения контента, как потом их стилизовать по :hover и т.п.?
                                                    +2
                                                    Мы уже о кнопках говорим? А начали с «заголовков».
                                                      0
                                                      В общем, не хочу углубляться с сео-дебри, в которых относительно слабо компетентен.
                                                      Весь интернет использует отрицательный text-indent, а вы можете использовать картинки с альтами, никаких проблем. Тем более, товарищ вон подтвердил про «рабочие примеры».
                                                      Анкор всегда влиял на релевантность в первую очередь, возможно со временем альты будут равноценны или даже лучше.
                                                      Удачи.
                                                        +4
                                                        Т.е. вы точно не знаете, но спорите? И единственный ваш аргумент: «миллионы мух не могут ошибаться». Странная позиция.
                                                    +1
                                                    Если картинка — это сслылка, то нет никакой проблемы в построении карты сайта поисковиком.
                                                      +3
                                                      Я не силен в оптимизации, вот и спрашиваю. Я считал, что alt для картинки обернутой в ссылку нормально индексируется. Я ошибался?
                                                        +3
                                                        Нет, вы правы. Все отлично индексируется. Есть рабочие примеры.
                                                  +3
                                                  Это все плохие решения. Почему? Потому, что надо исходить не из абстрактной «семантики», а из решения минимум 2 задач: корректного отображения текста на разных устройствах (в т.ч. при отключеннных картинках) и корректного понимания текста поисковыми системами.

                                                  Этот способ не решает ни первой проблемы (если отключить картинки, текст не виден), ни второй (поисковики, увидев что у текста нулевой размер шрифта, могут игнорировать его).

                                                  Потому я обычно делаю так: спан с position:relative, display: inline-block, overflow: hidden, в нем текст, поверх него спан с position: absolute и фоном в виде картинки (с непрозраным фоном). Если картинка не загрузилась, виден текст под ней.

                                                  Но этот способ не позволяет использовать прозрачную картинку (так как через нее будет просвечивать текст). Может, можно его как-то доработать? Чтобы, например, поместить текст и картинку в общий контейнер и картинка при загрузке сдвигала текст за пределы видимости? Что-то у меня нет решения.
                                                    +1
                                                    При использовании alt'а с примененным к нему CSS, можно получить адекватный текст на месте отключенной картинки.
                                                      +1
                                                      Чем не устраивает вариант встраивания нужного шрифта в сайт?
                                                        0
                                                        Вообще, хороший вариант, лучше чем приведен в статье, и чем приведен у меня (просто раньше внешние шрифты не всеми браузерами поддерживались, вот с тех времен я этот способ и использую), единственное, что может быть иногда ради 10 букв тянуть шрифт (пусть даже порезанный) неоправданно. Плюс, надо еще проверить, не будет ли это тормозить в ИЕ6/7.

                                                        0
                                                        Я бы сформулировал по-другому — эти решения неплохие, просто они не идеальны. Ваш способ имеет право на жизнь, но во многих случаях он будет избыточен из-за двух спанов, а position:absolute может повести себя непредсказуемо в некоторых мобильных браузерах. Да и в старых ИЕ могут возникнуть нюансы, если на странице есть куча лайтбоксов и поп-апов — нужно отслеживать, чтобы правильно наследовался z-index.

                                                        Мне кажется, что хороший вариант решения этой задачи может быть решен с помощью js или средствами сервера — отслеживать состояние окна браузера и делать соответствующую развилку, как это сейчас делается с помощью тех же yepnope.js или если более глобально — modernizr.

                                                        Для нас, как для разработчиков, это будет более геморно, однако в конечном итоге до пользователя дойдет самый оптимальный вариант
                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                            0
                                                            Что за подход? Для ИЕ можно сделать через старый добрый одноразовый CSS expression вставку тега IMG.
                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                          0
                                                          варианты с нулевым размером шрифта и псевдоэлементами не применимы к старым браузерам. А то светлое будущее, в котором не осталось старых браузеров, пока еще далеко за горами. Так что зря вы, на мой взгляд, привели эти примеры.
                                                          Надо будет опробовать метод Зельдмана. Даже если он не работает в ИЕ6, для того старичка неизбежно пишется отдельный стилевой файл, в который никто не мешает воткнуть -9999px.
                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                              0
                                                              В эти 6%, довольно часто попадают заказчики со своими офисными компьютерами. Обычно у директора все ок. Но все начинается с момента, когда открывает страничку нового сайта компании помощница помощницы бухгалтера.

                                                              А если говорить про зарубежных клиентов то это вообще мрак. Не так давно имел дело с компанией, в которой у 4 из 7 человек на iPad 2 стояла iOS 3, а на маках 3 версия Firefox и древний Safari.
                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                            0
                                                            всегда писал -999em и экономил байт!
                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                              0
                                                              Мне ближе два других варианта:
                                                              <a href="#"><img src="картинка.png" alt="тут писать текст"></a>

                                                              либо, который кстати чаще использую:
                                                              <a href="#"><span>тут писать текст</span></a>

                                                              в стилях так:
                                                              a {background:url('картинка.png') no-repeat} /* соответственно ширина, высота и display: block */
                                                              a span {display:none}
                                                              

                                                              отрицательными отступами и т.д. как-то не пользовался никогда, уж простите.

                                                              Разумеется использую их там, где font-face не помогает!
                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                  0
                                                                  Без твоих комментов этот пост был бы неполным, спасибо :)
                                                                    0
                                                                    Что-то я не пойму, разве при отключенной графике будет виден текст в способе с -9999px? Тем более второй вариант с display:none полезен для ПС имхо, и, когда я так делаю (надо было об это сразу написать), думаю именно о ПС, а не о слепых и тех, кто за МКАДом, — в чем возможно не прав.
                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                        0
                                                                        Последнее было проверенно мною на практике — несколько сайтов, где неумышленно было приличное количество элементов с display:none и visibility:hidden, серьезно выпали из индекса сначала яндекса, потом гугла…
                                                                          +1
                                                                          Способе с display: none я не считаю клоакингом, потому что имеется в виду следующее:
                                                                          На изображении «Hello world!» и в коде соответственно
                                                                          <a href="#"><span>Hello world!</span></a>
                                                                          

                                                                          а не
                                                                          <a href="#"><span>купите Hello world! бесплатно  Hello world! скачать  Hello world! и т.п.</span></a>
                                                                          

                                                                            0
                                                                            Кстати, кроме ПС, текст будет виден при отключенных картинках и css, что тоже важно.
                                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                              0
                                                                              И еще в защиту способа с display: none :) Если картинка образована спрайтом, способ также весьма полезен, имхо.
                                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                                  0
                                                                                  Хорошо, убедил! :) Пересмотрю свое отношение к другим способам или же предпочту использовать тег img с аттрибутом alt ;)
                                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                                  0
                                                                                  На сколько мне известно поисковый бот не читает css, а потому такое скрытие (если говорить именно о ПС) более «человечно», чем куча рекламы в теге . Хотя, про ПС это уже отдельный разговор.
                                                                                    0
                                                                                    надо же, тег съелся.
                                                                                    *в теге
                                                                                    <noindex>
                                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                          +2
                                                                          IMHO, нужен SVG+Web-fonts. При этом индексироваться будет сам текст на картинке. Плюс появляется возможность отображать текст на картинке на том языке, который установлен в браузере.
                                                                            +1
                                                                            Зелдман пишет:
                                                                            My friend Scott Kellum, design director at Treesaver, has now sent me this refactored code for hiding text, which I hereby christen the Kellum Method:
                                                                            .hide-text {
                                                                            text-indent: 100%;
                                                                            white-space: nowrap;
                                                                            overflow: hidden;
                                                                            }

                                                                            Т.е. не Зелдман этот метод придумал, а просто о нём рассказал.
                                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                              0
                                                                              смею предложить еще один способ, которым я периодически пользуюсь. Его смысл заключется в ацки огромном размере шрифта:

                                                                              .logo {
                                                                                background: url(logo.png);
                                                                                font-size: 999em;
                                                                                height: 50px;
                                                                                overflow: hidden;
                                                                                width: 100px;
                                                                              }
                                                                              
                                                                                0
                                                                                А такой размер шрифта не может влиять на производительность?
                                                                                  0
                                                                                  замеров производительности не производил, тормозов не замечал
                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                    0
                                                                                    Спасибо, добавил в пост
                                                                                    0
                                                                                    Эмм. А в чем проблема-то? Почти как начал верстать и понимать SEO принципы, верстаю так и не думал, что есть методы даже чьим-то именем названные.
                                                                                    <style>
                                                                                    .logo{
                                                                                       display:block;
                                                                                       overflow:hidden;
                                                                                       width:imgWidth px;
                                                                                       height:imgHeight px;
                                                                                    }
                                                                                    </style>
                                                                                    <a href="/" class="logo"><img src="img.png" align="left"/>название сайта</a>
                                                                                    

                                                                                    Если картинки нет или отключена — видим текст. Есть — выталкивает текст и видим только картинку. Из старого тестил только в IE6-7, но ничего не указывает на не кроссбраузерность.

                                                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                                    Самое читаемое