Существует не так много статей об отзывчивых логотипах. Самый популярный пример – сайт responsive logos. Он демонстрирует разные вариации знаменитых логотипах при различных масштабах окна. Когда я увидел этот сайт в первый раз, то решил, что это какая-то уловка. Как-никак, это же всего лишь div с крупным изображением на фоне. Позднее я больше заинтересовался в этой теме.
Я обнаружил две вещи, которые меня воодушевили:
- При применении SVG можно забыть об атрибуте viewBox и создать новую координатную систему для вложенных элементов при использовании нового значения viewBox. (признаю, выглядит запутанно. Позднее я расскажу об этом подробнее);
- При использовании медиа-запросов в SVG-файлах и последующей вставки изображения через img-tag или CSS background-image медиа-запросы привязываются к ширине изображения. Проявляется практически то же поведение, как при использовании запросов контейнера.
Родилась идея
После прочтения материалов по этой теме у меня появилась идея – создать логотип для компании, который не только реагирует на изменение ширины окна браузера, но и адаптируется, сохраняя соотношение собственных размеров. Такой логотип можно будет использовать где угодно. Файл самостоятельно будет выбирать, какую версию показывать, в зависимости от размеров окна.
Результат:
Если вы уже в восторге, то скачайте финальный файл демонстрацию. Увидеть логотип в действии можно на CodePen.
Пошаговое объяснение создания адаптивного логотипа
Когда создается собственное адаптивное изображение, нужно проделать шаги, представленные ниже. У вас должны быть хотя бы основные знания о SVG и CSS. Кроме того, стоит порадоваться: JavaScript не будет использоваться совсем. В основном нам просто надо будет копировать код из одного файла в другой.
1. Разработка логотипа
Начнем с дизайна 4 версий логотипа. Для этого я использовал Sketch.
Для элементов, которые есть в нескольких версиях, стоит использовать символы в Sketch. В будущем это упростит для вас задачу. SVG, которую мы будем создавать, будет применять такие же символы.
Как вы можете заметить, логотип (будущее адаптивное изображение) состоит из графического элемента и текста – названия компании. В версии в виде квадрата я решил убрать текст. Причина такова: я хотел, чтобы логотип был узнаваем даже при маленьком размере (32х32 px).
2. Создание файла SVG
Перед тем как совершать экспорт изображения, нужно создать новый графический файл. Может, начинать SVG с написания кода – немного страшно. К счастью, все не так сложно. Все, что нам нужно – это открывающий и закрывающий теги:
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
</svg>
Если вы внимательнее взгляните на атрибуты, то обнаружите, что атрибута viewBox нет. Мы только придали высоте и ширине значения 100%.
Также присутствует 2 атрибута xmlns. Честно говоря, понятия не имею, почему именно они должны быть там, нужно поискать информацию… В любом случае, если вы их удалите, то не сможете использовать никакие символы в SVG, а вместо этого получите сообщения об ошибках.
3. Экспорт SVG-файлов
Так как в итоговой SVG мы будем использовать элементы как символы, нужно поместить каждый из них на отдельную панель и сохранить в формате SVG.
Обязательно не экспортируйте объекты, а помещайте их на разные панели. Если вы экспортируете элементы с крупной панели, то к вашим группам будут прикреплены странные атрибуты transform. Этот шаг также поможет отделить друг от друга символы и уничтожить все группы, которые не используются. Наконец, назовите элементы. Проверьте: возможно, где-то применена неиспользуемая маска.
Посмотрим, как будет выглядеть код:
<?xml version="1.0" encoding="UTF-8"?>
<svg width="160px" height="160px" viewBox="0 0 160 160" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
<title>ix</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="ix" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group">
<rect id="Rectangle" fill="#000000" x="0" y="0" width="160" height="160"></rect>
<path d="M121.660503,96.7351709
...
120.725167,110.589044 Z" id="X" fill="#FFFFFF"></path>
</g>
</g>
</svg>
Стоит использовать сервис типа SVGOMG для уменьшения веса файла и удаления бесполезных фрагментов. Не очищайте ID. Если вы называли слои в Sketch, то вам будет проще опознавать их по ID в конечном файле. Вот так будет выглядеть оптимизированный файл:
<svg viewBox="0 0 160 160" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="ix" fill="none" fill-rule="evenodd">
<rect id="Rectangle" width="160" height="160" fill="#000" fill-rule="nonzero"/>
<path id="X" fill="#FFF" fill-rule="nonzero" d="M121.660503,96.7351709
...
120.725167,110.589044 Z"/>
</g>
</svg>
Если все сделано верно, то вы заметите группу, которая имеет такой же ID, как название вашей панели. В этой группе содержится интересующий нас контент. В этом случае это прямоугольник, который является фоном, и сложный путь, создающий IX (римская 9, повернутая на 90 градусов… если вас интересует).
4. Создание символов
Наши файлы были подготовлены, так что их можно объединить. Начните с написания тегов symbol в финальном файле. Придайте каждому уникальный ID, а также атрибут viewBox, который совпадает с viewBox экспортированных файлов.
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="ix" viewBox="0 0 160 160">
<!-- Insert Symbol Content here -->
</symbol>
<symbol id="typography" viewBox="0 0 144 16">
<!-- Insert Symbol Content here -->
</symbol>
</svg>
Вставьте в теги symbol то, что содержится в экспортированных файлах, то есть все, что находится в группе с тем же именем, что и ваша панель. Как только вы закончите, файл должен выглядеть так:
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="ix" viewBox="0 0 160 160">
<rect id="Rectangle" width="160" height="160" fill="#000" fill-rule="nonzero" />
<path id="X" fill="#FFF" fill-rule="nonzero" d="M121.660503,96.7351709
...
120.725167,110.589044 Z"
/>
</symbol>
<symbol id="typography" viewBox="0 0 144 16">
<path fill="#000" d="M34.98 12.42h7.64v3.
...
8.6h2.89V.34h-3.72v8.82z"
/>
</symbol>
</svg>
5. Использование символов
К сожалению, при открытии файла в браузере ничего не будет отображаться. Мы уже определили символы, но никуда их не поместили. Чтобы разместить символ, нужно в файле прописать тег use:
<use xlink:href="#ix" x="0" y="0" width="100" height="100"/>
Рассмотрим, что конкретно здесь происходит.
Сначала xlink:href
находит символ с уникальным ID, а также обрабатывает его содержимое… Под обработкой здесь понимается копирование. Затем появляется странная вещь – shadow DOM. Ее не нужно бояться. Вам не о чем беспокоиться, если вы не хотите изменять что-либо в символе с помощью CSS.
Далее идут атрибуты x, y, width и height. Как вы могли догадаться, эти атрибуты отвечают за координаты и размеры обработанного символа. Но ведь не указано никаких единиц измерения; насколько большим будет символ? В SVG все единицы определяются атрибутом viewBox, установленном в теге SVG. Так как мы не устанавливали viewBox и только определили высоту и ширину (100%), одна единица будет равняться одному пикселю. Ширина нашего символа будет равна 100px Ничего не изменится, если вы поменяете ширину SVG. Ширина всегда будет оставаться равной 100px.
Попробуйте поменять значения высоты и ширины на CodePen. Вы увидите, что символ постоянно будет сохранять соотношение размеров. К счастью, именно это и нужно в нашем случае. Если бы вы захотели изменить поведение при изменении размеров, то вам бы пришлось создать атрибут preserveAspectRatio.
Помимо значений без единиц измерения, для определения позиции и размеров через атрибуты можно также использовать проценты. Чтобы этот символ выглядел так же, как квадратная версия, просто для рамки изображения используйте ширину 90%; позиция левого верхнего угла соответствует 5%.
<use xlink:href="#ix" x="5%" y="5%" width="90%" height="90%"/>
Возможно, вам кажется, что поставить для ширины или высоты значение «auto» - хорошая идея. Это не так. Safari и Firefox проигнорируют это, а Chrome ничего не обработает.
6. Объединение символов в новый символ
Для версии с портретным форматов нам понадобятся оба символа. Для того чтобы они пропорционально масштабировались и всегда имели одинаковое расстояние до границ и друг до друга, нужно просто создать еще один символ. У него тоже есть свой атрибут viewBox, который позволяет поместить символы в новую координатную систему. Чтобы увидеть, где именно все символы должны быть помещены, можно вновь обратиться к файлу Sketch и исследовать размеры и расстояния.
Теперь нужно перенести все цифры в новый SVG-символ. Это будет выглядеть так:
<symbol id="portrait" viewBox="0 0 160 180">
<use xlink:href="#ix" x="40" y="32" width="80" height="80"/>
<use xlink:href="#typo" x="3" y="130" width="154" height="16"/>
</symbol>
Когда мы будем использовать символ, его ширина не должна быть равна 100%. Давайте уменьшим его, как квадратный символ.
<use xlink:href="#portrait" x="5%" y="5%" width="90%" height="90%"/>
7. Прячем и показываем элементы
Мы уже создали 3 символа. В нашей SVG есть 2 тега use.
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol id="ix" viewBox="0 0 160 160">
<rect id="Rectangle" width="160" height="160" fill="#000" fill-rule="nonzero" />
<path id="X" fill="#FFF" fill-rule="nonzero" d="M121.660503,96.7351709
...
120.725167,110.589044 Z"
/>
</symbol>
<symbol id="typography" viewBox="0 0 144 16">
<path fill="#000" d="M34.98 12.42h7.64v3.26H31.26V.34h3.72v12.08zm-19.04
...
8.6h2.89V.34h-3.72v8.82z"
/>
</symbol>
<symbol id="portrait" viewBox="0 0 160 180">
<use xlink:href="#ix" x="40" y="32" width="80" height="80"/>
<use xlink:href="#typography" x="3" y="130" width="154" height="16"/>
</symbol>
<use xlink:href="#ix" x="5%" y="5%" width="90%" height="90%"/>
<use xlink:href="#portrait" x="5%" y="5%" width="90%" height="90%"/>
</svg>
Наконец, начинается веселая часть. Теперь мы можем сделать адаптивное изображение путем нескольких махинаций. Сейчас оба символа показываются друг на друге. Чтобы спрятать части, которые нам не нужно отображать, нужно добавить пару классов в теги use.
<use class="square" xlink:href="#ix" x="5%" y="5%" width="90%" height="90%"/>
<use class="portrait" xlink:href="#portrait" x="5%" y="5%" width="90%" height="90%"/>
Теперь недостает только CSS для того, чтобы показывалась единственная версия логотипа. Можно добавить тег <style>
в SVG и использовать медиа-запросы, как и в случае с обычным CSS-файлом.
В CSS вы, вероятно, использовали бы что-то вроде @media (min-width: 768px) { … }
, но здесь вы смотрите только на ширину изображения. Мы заинтересованы в соотношении размеров, а не в ширине, так что наши медиа-запросы будут прописаны так: @media (min-aspect-ratio: 1/2) { ... }
.
В случае первых двух версий сделаем портретную версию той, что отображается по умолчанию. Версию с IX будем показывать только тогда, когда ширина совпадает с высотой. Другими словами: когда изображение переходит из портретного режима в ландшафтный, мы больше не будем показывать текст, только графику.
<style>
.square { visibility: hidden; }
.portrait { visibility: visible; }
@media (min-aspect-ratio: 1/1) {
.square { visibility: visible; }
.portrait { visibility: hidden; }
}
</style>
Символ с ландшафтным разрешением вы, наверное, захотите показывать, когда ширина изображения будет как минимум в 2 раза превышать высоту. Посмотрим, как изменится style:
<style>
.square,
.landscape { visibility: hidden; }
.portrait { visibility: visible; }
@media (min-aspect-ratio: 1/1) {
.portrait,
.landscape { visibility: hidden; }
.square { visibility: visible; }
}
@media (min-aspect-ratio: 2/1) {
.portrait,
.square { visibility: hidden; }
.landscape { visibility: visible; }
}
</style>
Все! Мы создали адаптивное изображение в виде SVG-логотипа. Здесь вы можете увидеть полный код с тремя версиями логотипа, от портретной до ландшафтной версий.
8. Чуть-чуть трансформаций
Ладно, ладно… Знаю, в приведенном выше примере нет вертикального баннера. Все потому, что для создания нужного символа в этом случае нужно произвести трансформацию. Я не буду объяснять подробно, но нужный код находится ниже:
<symbol id="skyscraper" viewBox="0 0 64 328">
<use xlink:href="#ix" x="0" y="264" width="64" height="64"/>
<use xlink:href="#typography" x="-90" y="109" width="246" height="27" transform="rotate(-90 32 123)"/>
</symbol>