Ваш логотип — всё еще изображение… и мой тоже!
Почти два года назад я написал статью о семантике изображений, в которой описал какой должна быть правильная разметка для логотипа сайта. В двух словах, в ней приведены доводы в пользу того, что логотипы — это контент, следовательно они должны быть прописаны в разметке как элементы img , а не h1 , как это часто делают.
Две главные причины использования h1 :
- Он позволяет поместить логотип в спрайт.
- Заблуждение что логотип — это своего рода заголовок.
В своей статье (я все еще придерживаюсь мнения, которое в ней высказано), я опроверг второй пункт, однако первый не перестает меня волновать.
В репозитории CSS Wizardry меня попросили более детально рассказать как я применяю свои утверждения на практике:
Я недавно перечитывал Вашу статью о том, что логотип — это изображение и заметил, что на своем сайте Вы применяете другой подход. Расскажите нам о нем подробнее, пожалуйста.
Внимание, дальше много букв. Поищем баланс между правильной семантикой и лучшей производительностью.
Итак, ранее я писал что для логотипа не стоит использовать h1 , его лучше поместить в img . Вот разметка которую я сейчас (в феврале 2013 года) использую на CSS Wizardry:
Заметьте что в src указано не logo.png или что-то в этом роде, а dot.gif . Это, как можно догадаться, прозрачное изображение в формате gif с размерами 1×1px.
Обновлено: сейчас я использую прозрачный gif размером 1×1px, закодированный в Base64
Эм … что?
Я поместил маленькое прозрачное изображение в формате gif в тэг img и затем с помощью CSS добавил в качестве фона SVG-спрайт. Таким образом, я использовал подходящий с точки зрения семантики img и, немного схитрив, добавил из CSS изображение, которое увидят пользователи. Вот (S)CSS:
Я всего-навсего указываю класс, в котором будет применен спрайт ( .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 позволяет выполнить две задачи:
- Сообщить машине о наличии изображения и alt -текста.
- Отобразить графические данные для пользователя.
Теперь вы понимаете, как можно представить прозрачный gif размерами 1×1px в качестве семантически верного img и при этом управлять представлением логотипа через CSS используя спрайты.
Но зачем?!
Мы долго к этому шли, и вот наконец ответ на вопрос зачем так делать.
Вкратце: во имя производительности.
Все, кто последние несколько лет следит за публикациями на CSS Wizardry и моими постами в Twitter, знают, что проекты, над которыми я работаю, становятся все более сложными, архитектура и продуктивность все более важны и мне это нравится!
Что мне нравится больше всего в этой стороне веб-разработки — это сплав действительно впечатляющих и интересных хаков во имя производительности с «уродливой» разметкой. Года два назад я стремился к идеальной семантике и «полировал» свой код; теперь я рассматриваю код как потрясающий материал для создания больших, быстрых сайтов. Создание спрайтов для пустых элементов — это часть веселья.
Использование спрайтов — это азы продуктивности, мы все знаем зачем они нужны. Однако важно сохранять правильную семантику всюду где это возможно, потому я и использую спрайт для элемента img .
Если с точки зрения семантики логотип должен быть изображением, а вы хотите поместить его в спрайт, лучшим решением будет использовать просвечивающий img . Прозрачный gif размером 1×1px позволяет получить такое просвечивание для маленького изображения.
Это изображение создает дополнительный HTTP-запрос, что противоречит принципам производительности, однако:
- Это лишь несколько дополнительных байтов, которые загрузятся практически незаметно.
- Использовать его можно бесконечное количество раз, так как браузер не будет его запрашивать повторно.
- Его можно кэшировать раз и навсегда так как вряд ли когда-нибудь потребуется обновление прозрачного gif размером 1×1px.
Можно было бы, конечно, указать в src путь и к несуществующему изображению, что вернуло бы ответ 404 и убрало бы необходимость доставлять в браузер какое-либо изображение. Проблема здесь в том, что когда никакой объект не загружается, браузеру нечего кэшировать. Это значит что имея пять элементов img , для которых используется спрайт, вы получите пять ответов 404 и никакого кэширования. Изначальные расходы в виде одного HTTP-запроса на dot.gif быстро окупаются, так как маленькое изображение может быть кэшировано неограниченное количество времени и использоваться снова и снова. Стоит ли напоминать что изначальная причина всех этих действий — получение возможности использовать спрайты, которые экономят вам массу HTTP-запросов!
Отмечу, что не всегда нужно или можно поместить изображения в спрайт. Я и не говорю что это нужно делать всегда, наоборот я бы сказал что довольно часто создать спрайт у вас возможности не будет (например для изображений с гибким размером). Я просто предлагаю вам дополнительный инструмент для работы.
Итак, что мы имеем? Использование спрайта для img дает нам преимущества от семантически верного когда и спрайтов. Машина видит img с названием «CSS Wizardry» (отлично) и пользователь видит мой логотип (чудесно)! Все правильно, все счастливы.
Поправка: Как многие советуют, можно (если позволяет статистика) использовать data-URI в Base64 вместо gif и сэкономить HTTP-запрос. При таком подходе не будет происходить кэширование изображения, но мы можем использовать компрессию gzip.