Frontender Magazine

Ваш логотип — всё еще изображение… и мой тоже!

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

Две главные причины использования h1:

  1. Он позволяет поместить логотип в спрайт.
  2. Заблуждение что логотип — это своего рода заголовок.

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

В репозитории CSS Wizardry меня попросили более детально рассказать как я применяю свои утверждения на практике:

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

Внимание, дальше много букв. Поищем баланс между правильной семантикой и лучшей производительностью.

Итак, ранее я писал что для логотипа не стоит использовать h1, его лучше поместить в img. Вот разметка которую я сейчас (в феврале 2013 года) использую на CSS Wizardry:

<a href="/" class="site-logo">
    <img src="/img/dot.gif" alt="CSS Wizardry" class="s  s--csswizardry-logo">
</a>

Заметьте что в src указано не logo.png или что-то в этом роде, а dot.gif. Это, как можно догадаться, прозрачное изображение в формате gif с размерами 1×1px.

Обновлено: сейчас я использую прозрачный gif размером 1×1px, закодированный в Base64

Эм … что?

Я поместил маленькое прозрачное изображение в формате gif в тэг img и затем с помощью CSS добавил в качестве фона SVG-спрайт. Таким образом, я использовал подходящий с точки зрения семантики img и, немного схитрив, добавил из CSS изображение, которое увидят пользователи. Вот (S)CSS:

.s{
    background-image:url(/img/css/sprites/main.svg);
}
.s--csswizardry-logo{
    width:64px;
    height:64px;
    background-position:-5px -5px;
    @include vendor(background-size, 250px 250px);

    @include media-query(desk){
        @include vendor(background-size, 500px 500px);
        width:128px;
        height:128px;
        background-position:-10px -10px;
    }
}

Я всего-навсего указываю класс, в котором будет применен спрайт (.s) и затем более детально описываю его свойства в .s--csswizardry-logo (не забывая об отзывчивом дизайне).

Стоит подчеркнуть, что хоть в разметке мой логотип и представлен всего лишь прозрачным gif-ом размером 1×1px, он является изображением.

Прежде, чем объяснить зачем я так делаю, нужно понять вот что:

Люди и машины

Когда дело касается HTML и CSS, следует провести разграничение (хоть оно и будет сильно упрощенным) между людьми (нашими пользователями) и машинами. Как правило (в большинстве случаев) на наши сайты имеют доступ два типа субъектов: машины, например скринридеры и боты, и люди, которые могут видеть сайт и взаимодействовать с ним.

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

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

Семантика нужна машинам

Учитывая вышеизложенное, становится ясно, что только машинам есть дело до того что мы используем img. Для пользователя нет никакой разницы используем мы img, Flash-объект или div с фоновой картинкой. img ценны только для машин (скринридеров, поисковиков, и т.п.). Именно им нужна семантика.

Машины также пользуются alt-текстом. alt-текст не нужен пользователям, он нужен машинам, которые при необходимости передают его пользователям.

Таким образом, для добавления изображения семантически правильно будет использовать элемент img с alt-текстом, так как именно в этом нуждаются машины. Для машин (что мы, как фронтенд-разработчики должны понимать) не имеет никакого значения реальное содержимое изображения. Если у вас элемент img с прозрачным gif-изображением и «CSS Wizardry» в качестве alt-текста, машина знает только то, что это изображение с альтернативным текстом, она понятия не имеет что именно на изображении.

Изображения для людей

Для людей имеет значение что отображено на картинке и не имеет значения как выглядит код. Следовательно, пользователям все равно каким образом мы стилизируем элемент img (мы, естественно, будем использовать для этого CSS).

Вот в чем вся соль; img позволяет выполнить две задачи:

  1. Сообщить машине о наличии изображения и alt-текста.
  2. Отобразить графические данные для пользователя.

Теперь вы понимаете, как можно представить прозрачный gif размерами 1×1px в качестве семантически верного img и при этом управлять представлением логотипа через CSS используя спрайты.

Но зачем?!

Мы долго к этому шли, и вот наконец ответ на вопрос зачем так делать.

Вкратце: во имя производительности.

Все, кто последние несколько лет следит за публикациями на CSS Wizardry и моими постами в Twitter, знают, что проекты, над которыми я работаю, становятся все более сложными, архитектура и продуктивность все более важны и мне это нравится!

Что мне нравится больше всего в этой стороне веб-разработки — это сплав действительно впечатляющих и интересных хаков во имя производительности с «уродливой» разметкой. Года два назад я стремился к идеальной семантике и «полировал» свой код; теперь я рассматриваю код как потрясающий материал для создания больших, быстрых сайтов. Создание спрайтов для пустых элементов — это часть веселья.

Использование спрайтов — это азы продуктивности, мы все знаем зачем они нужны. Однако важно сохранять правильную семантику всюду где это возможно, потому я и использую спрайт для элемента img.

Если с точки зрения семантики логотип должен быть изображением, а вы хотите поместить его в спрайт, лучшим решением будет использовать просвечивающий img. Прозрачный gif размером 1×1px позволяет получить такое просвечивание для маленького изображения.

Это изображение создает дополнительный HTTP-запрос, что противоречит принципам производительности, однако:

Можно было бы, конечно, указать в src путь и к несуществующему изображению, что вернуло бы ответ 404 и убрало бы необходимость доставлять в браузер какое-либо изображение. Проблема здесь в том, что когда никакой объект не загружается, браузеру нечего кэшировать. Это значит что имея пять элементов img, для которых используется спрайт, вы получите пять ответов 404 и никакого кэширования. Изначальные расходы в виде одного HTTP-запроса на dot.gif быстро окупаются, так как маленькое изображение может быть кэшировано неограниченное количество времени и использоваться снова и снова. Стоит ли напоминать что изначальная причина всех этих действий — получение возможности использовать спрайты, которые экономят вам массу HTTP-запросов!

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

Итак, что мы имеем? Использование спрайта для img дает нам преимущества от семантически верного когда и спрайтов. Машина видит img с названием «CSS Wizardry» (отлично) и пользователь видит мой логотип (чудесно)! Все правильно, все счастливы.

Поправка: Как многие советуют, можно (если позволяет статистика) использовать data-URI в Base64 вместо gif и сэкономить HTTP-запрос. При таком подходе не будет происходить кэширование изображения, но мы можем использовать компрессию gzip.

Если вы заметили ошибку, вы всегда можете отредактировать статью, создать issue или просто написать об этом Антону Немцеву в skype ravencry.

Harry Roberts
Автор:
Harry Roberts
Сaйт:
http://csswizardry.com/
Twitter:
@csswizardry
GitHub:
csswizardry
Наталья Фадеева
Переводчик:
Наталья Фадеева
вКонтакте:
natatik_l
Twitter:
@very_busy_girl
GitHub:
NatalieF

Комментарии (13 комментариев, если быть точным)

Автар пользователя
smolnikov

Я считаю неправильным подход с использованием прозрачного однопиксельного гифа. Кроме машин и человеков, о которых говорит автор (машины в данном случае — клиентские компьютеры), есть еще машины, представляющие организационную структуру интернетов, и, в первую очередь, роботы поисковиков. Когда я ищу в гуглопоиске по картинкам "CSS Wizardry", я хочу увидеть в результатах логотип CSS Wizardry, а не проиндексированный однопиксельный гиф или скриншот главной страницы.

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

Автар пользователя
glebis

@smolnikov — полностью согласен, очень странное представление о семантике. Довольно простой и логичный вариант, когда нужно выдавать графику отдельно для ретины — вставить-таки нормальный лого как картинку, но скрыть её, а фон прописывать контейнеру (той же ссылке, например)

Автар пользователя
davidmz

Конкретно для логотипов (которым действительно важно присутствовать в поисковом индексе НЕ в виде прозрачных гифов), можно делать следующий финт: http://codepen.io/davidmz/pen/BEyDa

То есть, в HTML мы имеем обычный IMG с растровым логотипом, а в CSS мы заменяем контент на прозрачный гиф и дальше используем спрайт.

Автар пользователя
glebis

@davidmz Интересный вариант в случае, когде не нужна поддержка IE младше 8-ой версии. (http://caniuse.com/css-gencontent)

Автар пользователя
SelenIT

Разве content для img (и вообще пустых замещаемых элементов) работает не только в Presto?

Автар пользователя
davidmz

Н-да, я поторопился и не проверил во всех браузерах. Сорри, революция отменяется:)

Автар пользователя
mistakster

Когда я ищу в гуглопоиске по картинкам "CSS Wizardry", я хочу увидеть в результатах логотип CSS Wizardry

На самом нет ни какой гарантии, что именно логотип будет самой релевантной картинкой к этому запросу. Я нашёл несколько сайтов известных компаний, у которых логотип был сделан картинкой с соответствующим атрибутом alt. В поиске по названию компании мне, конечно же, выдавались логотипы, но, увы, все они были либо с совершенно других доменов, либо не были тем самым логотипом, о котором мы тут рассуждаем. По этому, данный аргумент — это совсем не аргумент.

Про семантику согласен.

Кстати, есть же «CSS Naked Day» (в этом году почему-то про него ничего не было слышно), когда отключаются все стили сайта — остаётся один контент без оформления. Для техники, описаной в статье, логотип попросту не будет виден. Однако, в случае с csswizardry.com там всё же будет отображаться хоть какая-то айдентика, которая вставлена… [барабанная дробь] обычной картинкой!

Автар пользователя
ihorzenich

А что он будет выводить в версии для печати? Я по-этому и ставлю logo в img в чистом виде - чтоб на печати было лого сайта.

Автар пользователя
smolnikov

@mistakster полностью согласен, что логотип может не быть самой релевантной картинкой (например, по запросу "Apple" я совершенно готов увидеть десяток страниц с различным яблоками), но я говорил о чуть более фундаментальных вещах — наверное, в некоторой части из области Semantic Web (я хочу сказать, что в теории поисковики могли бы принимать решение, что если я формирую запрос как "Логотип Apple", то мне стоит показать изображение с сайта apple.com, даже если его alt="Apple"не содержит слова "логотип").

Автар пользователя
mistakster

@delka, напечатано будет то, что задано через стили для печати.

В настройках можно задать печать как с фоновыми картинками (т.е. логотип будет виден), так и без них (логотипа не будет). Эти настройки есть как в OSX, так и в Windows. Но беда в том, что пользователь может не знать о них и печать фоновых картинок выключена по-умолчанию.

@smolnikov, есть масса стандартов микроразметок. Поисковики умеют работать с ними. В типе Organization, например, есть свойство logo. Почему бы не использовать его?! Явно укажем, что вот это логотип и файл с изображением можно загрузить по такому-то URL.

Автар пользователя
smolnikov

@mistakster, микроразметка — это ведь отдельный уровень абстракции, а использование логотипа имеет место быть на обсуждаемом уровне — HTML-структуре документа. Если я когда-нибудь заведу себе блог, я, наверняка, захочу придумать для него какой-то логотип. Но я не смогу использовать схему Organization, ведь я Person. В общем, все сложно :) Суть в том, что если разработчик вставляет в документ (страницу) логотип, то это должно быть изображение, а не однопиксельный гиф с фотовой картинкой.

Автар пользователя
SelenIT

напечатано будет то, что задано через стили для печати

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

Автар пользователя
mistakster

@smolnikov, для людей и продуктов тоже есть элегантное решение. Описал его в статье «Больше семантики для логотипа». Вкратце, если ты не организация, то добавь в разметку логотипа микроданные типа Brand и сошлись на них в поле brand. Для организаций можно сделать тоже самое.