CSS-live.ru

Универсальная независимость при помощи SVG

В этой статье мы рассмотрим масштабируемую векторную графику (Scalable Vector Graphics или сокращённо SVG), как одну из наиболее недостающих технологий в современном сайтостроении.

Прежде чем приводить конкретные примеры, давайте посмотрим на уровень web’а сегодня и то, куда он движется. За последние годы дизайн сайтов обозначил новую тенденцию в развитии техники универсального дизайна (Responsive Website Design). И это к лучшему. По существу, универсальный дизайн обеспечивает переход от использования полюбившихся нам фиксированных по ширине страниц, к вёрстке плавающих форм с интеллектуальным перемещением их содержимого. Добавьте к этому продуманную стратегию содержимого и мобильный подход, и мы уже начинаем предлагать универсальный опыт адаптации под множество устройств и браузеров, удовлетворяя потребности конечного пользователя.

Когда мы смотрим на многочисленные устройства, предполагающие выход в интернет, приходит осознание того, что универсальный дизайн — это лучшее, что можно предложить современному пользователю интернета. Использование горизонтальной прокрутки, панорамирования и масштабирования окна браузера имеет место быть, как часть дополнительного интерфейса, но принуждение пользователей к выполнению данных действий для навигации по сайту, быстро становится утомительным занятием. Подгонка сайта под размеры окна просмотра основана не только в вёрстке, но и в разрешении. В этой статье я покажу, почему SVG прекрасно дополнит будущие интернет разработки.

ЗНАКОМЬТЕСЬ, SVG

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

Рассмотрим область применения: пользовательский интерфейс, иконки навигации, иллюстрации в векторном стиле, паттерны и повторяющийся фон. Для всего этого, масштабируемая графика является наилучшим решением с визуальной точки зрения, но ограничение разрешения картинок по-прежнему является нормой. В примере, приведённом ниже, мы покажем, как в целом расширить техники разработки и воспользоваться преимуществами SVG.

Рассмотрим спрайты CSS

Всем нам хорошо знакомы методы использования CSS спрайтов (если вам не знакомы данные техники, можете быстро глянуть статью Свена Леннартца. А также ознакомиться с доводами «за и против» Луиза Лазариса). Ниже, мы продемонстрируем с какой лёгкостью SVG способен заменять обыкновенные растровые изображения. Если данный пример не для вас, мы уверены, вы сможете представить целый ряд подобных ситуаций с аналогичным использованием SVG

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

Я попробовал на этом примере:

Я попробовал на этом примере:

Я буду первым, кто отметит, что этот комплект иконок не достоин дизайнерских наград, но его вполне достаточно для этой статьи. Давайте взглянем на HTML:

<div class="actions">
	<a class="a-share" href="#">Share</a>
	<a class="a-print" href="#">Print</a>
	<a class="a-tag" href="#">Tag</a>
	<a class="a-delete" href="#">Delete</a>
</div>

Я выдержал код в минимальном стиле, но на практике, вы захотите создать тоже самое при помощи маркированного списка. И, вполне вероятно, вы замените знаки решётки на URL адреса (даже если функциональность будет обеспечиваться при помощи JavaScript, иметь запасной вариант всегда приятно).
Посмотрим на CSS:

.actions {
   display: block;
   overflow: auto;
}

.actions a {
   background-image: url('sprite.png');
   background-repeat: no-repeat;
   background-color: #ccc;
   border-radius: 5px;
   display: block;
   float: left;
   color: #444;
   font-size: 16px;
   font-weight: bold;
   line-height: 20px;
   text-decoration: none;
   text-shadow: 0 -1px 2px #fff;
   padding: 10px 20px 10px 40px;
   margin-right: 5px;
}

.a-share  { background-position: 10px 0; }
.a-print  { background-position: 10px -40px; }
.a-tag    { background-position: 10px -80px; }
.a-delete { background-position: 10px -120px; }

Обратите внимание на фиксированные размеры в пикселях и фон .png, который, как вы можете видеть ниже, оформлен по всем правилам Photoshop:

Данная реализация CSS спрайтов является основой, но уже не годится по сегодняшним стандартам! И как мы можем это улучшить? Во-первых, давайте рассмотрим следующие вопросы:

  1. Мы растрировали изображение на очень ранней стадии. Даже в полном размере, местами, имеется размытость.
  2. Если мы приблизим, размытие усилится, т.к. процесс ререндеринга невозможен из-за отсутствия данного изображения в больших размерах.
  3. У всего фиксированный размер, что не хорошо, как для универсального дизайна, так и для удобства, учитывая игнорирование стандартного размера шрифта самого браузера.

Как вы, наверное, уже догадались, мы покажем вам, как SVG справляется со всеми из перечисленных проблем. Но для начала рассмотрим каждую из проблем более детально, чтобы понять суть проблемы в целом.

1. РАСТЕРИЗАЦИЯ

Устройства, на подобии современных смартфонов, имеют очень большую плотность пикселей. Так, некоторые из них превышают 300 пикселей на дюйм (PPI), что практически на грани возможностей человеческого глаза различать столь мелкие детали. Пиксель не имеет эквивалента в реальном мире до тех пор, пока он не окажется на экране фиксированного размера (скажем, диагональю 3,5 дюйма) и фиксированного разрешения (скажем, 640 x 960 пикселей). При таком раскладе, текст, с размером шрифта в 16 пикселей, будет невероятно мелким для его прочтения. По этой причине, устройства просто не могут перевести единицу CSS пикселя в единицу пикселя самого устройства, вместо этого они удваиваются. Таким образом, шрифт, размером 16 пикселей, фактически преобразуется в шрифт, размером 32 пикселя, после своего отображения.

То же самое происходит и с картинками, однако, они уже растрированы, так что от удвоения пикселей нет абсолютно никакой пользы. В нашем примере, каждая иконка была растрирована в 25 x 25 пикселей (полный спрайт получился 30 x 160 пикселей), поэтому они не смогут воспользоваться преимуществом удвоения пикселей. Одно из решений заключается в использовании CSS запросов по определению соотношений пикселей. Эта возможность уже реализована в WebKit- и браузерах на движке Gecko.

Для улучшения нашего примера, мы может добавить в CSS следующее:

@media only screen and (-webkit-min-device-pixel-ratio: 2)  {
   .actions a {
      background-image: url('sprite@2x.png');
      background-size: 30px 160px;
   }
}

Альтернативное фоновое изображение, указанное в коде выше, сохранено в размере 60 x 320 пикселей (т.е. в два раза больше от первоначального размера). Свойство background-size сообщает CSS о том, что спрайт меньше. Отметим, что теперь у устройства есть дополнительные данные для подгрузки при отображении лучшего изображения (если есть такая возможность).

Это решение не плохое, но оно не решает проблемы, с которыми мы столкнулись в пунктах 2 и 3. Это также требует от нас создания увеличенных копий изображений, что доставляет немало хлопот и увеличивает нагрузку на пропускную способность. Для невекторных изображений, таких как фотографии в формате .jpg, мы не можем сделать чего-то большего.

2. УВЕЛИЧЕНИЕ

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

Первое, что делает пользователь испытывающий дискомфорт при просмотре мелкой страницы сайта — это увеличение. Подобные сайты весьма распространены. В действительности, нет «идеального» размера, в силу ухудшения зрения, неизбежно приходящего к нам с возрастом. Во-вторых, стремительное развитие устройств с сенсорным экраном сделало нормой необходимость постоянного увеличения фиксированных страниц (это большая часть интернет проектов на сегодня), созданных для больших экранов.

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

3. ФИКСИРОВАННЫЕ РАЗМЕРЫ

Представление элементов страницы в фиксированных размерах не только провоцирует множество пользователей к увеличению, но и отключает одну из полезных возможностей браузера. Пользователь может задать предпочтительный для него размер шрифта (стандартный используемый размер 16 пикселей). Задавая все размеры в пикселях, мы перекрываем эти настройки. Размер элементов, который зависит от стандартных значений, куда более предпочтителен. Если текст больше, то и всё остальное подстраивается под него. По существу, это имитирует эффект увеличения, только происходит это без каких-либо манипуляций при каждом посещении. Этан Маркотт написал достойную статью на тему относительных размеров шрифта.

Давайте повторно реализуем пример с нашим спрайтом и применим решения для трёх существующих проблем.

МАСШТАБИРУЕМАЯ РЕАЛИЗАЦИЯ

И снова HTML код. Здесь мы ничего изменять не будем.

<div class="actions">
	<a class="a-share" href="#">Share</a>
	<a class="a-print" href="#">Print</a>
	<a class="a-tag" href="#">Tag</a>
	<a class="a-delete" href="#">Delete</a>
</div>

Обновим CSS и сотворим в нём немного магии:

body { font-size: 100%; }

.actions {
   display: block;
   overflow: auto;
}

.actions a {
   font-size: 1em;
   line-height: 1.25em;
   padding: 0.625em 1.25em 0.625em 2.5em;
   margin-right: 0.3125em;
   border-radius: 0.3125em;
   background-image: url('sprite.svg');
   -webkit-background-size: 1.875em 10em;
   -o-background-size: 1.875em 10em;
   -moz-background-size: 1.875em 10em;
   background-size: 1.875em 10em;
   /* styles carried over from the original implementation */
   background-repeat: no-repeat;
   background-color: #ccc;
   color: #444;
   display: block;
   float: left;
   text-decoration: none;
   text-shadow: 0 -1px 2px #fff;
}

.actions-em .a-share { background-position: 0.625em 0; }
.actions-em .a-print { background-position: 0.625em -2.5em;  }
.actions-em .a-tag { background-position: 0.625em -5.0em;  }
.actions-em .a-delete { background-position: 0.625em -7.5em;  }

В эту версию мы внесли следующие изменения:

  • background-image теперь использует .svg файл
  • — Все размеры основаны на стандартных 16-ти пикселях, или 1 em. Если стандарт для пользователя больше или меньше, всё будет изменено взаимосвязано. (Если вы помножите каждый размер в em на 16, вы получите число пикселей, которое использовалось в первоначальном примере с фиксированными размерами).
  • Обратите внимание на background-size. Выставляя размер в em, мы говорим браузеру масштабировать спрайт в зависимости от всего другого. Вы заметили, что 1.875 * 10 em помноженное на 16 равно 30 x 160 – размер в пикселях, в котором мы представлен наш спрайт.
  • background-position каждой иконки спрайта также заданы в относительных единицах.

Теперь, используя SVG и относительные размеры, мы решили три большие проблемы, описанные выше. Масштабируемая графика может быть растрирована в зависимости от потребностей для отличного отображения на любом разрешении и при любом увеличении. А используя относительные размеры, мы можем продолжить развитие универсального дизайна, сводя к минимуму потребность пользователей в увеличении. Мы также учитываем размеры шрифта браузера и адаптируем наш дизайн соответствующим образом.

На самом деле сначала я создал SVG спрайт, а лишь потом при его помощи и PNG версию. (Я импортировал SVG в Photoshop, прежде чем экспортировал его в качестве PNG – экспорт PNG через Illustrator имел плохую растеризацию). Ниже приведён заголовок моего SVG файла, размер тот же (30 x 160 пикселей).

<svg enable-background="new 0 0 30 160" height="160px" id="Layer_1" space="preserve" version="1.1" viewbox="0 0 30 160" width="30px" x="0px" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" y="0px">
</svg>

В открытом SVG теге вы можете видеть, что атрибуты ширины и высоты заданы в пикселях (width=”30px” height=”160px”, сгенерировано Illustrator’ом). Это заставляет выполнять рендер в Firefox’е раньше, чем график масштабируется в соответствии с em размерами background-size. Webkit-браузеры, вроде, масштабируют SVG превосходно. Я заметил, что в SVG файле можно проставить единицы этих двух атрибутов в em для решения проблемы с Firefox.

<svg enable-background="new 0 0 30 160" height="160em" id="Layer_1" space="preserve" version="1.1" viewbox="0 0 30 160" width="30em" x="0px" xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" y="0px">
</svg>

Я не знаю, какой из браузеров выполняет масштабирование правильнее, нам лишь необходимо позаботиться о кроссбраузерной совместимости. В Mozilla MDN есть замечательная и углублённая статья «Масштабирование фоновых изображений SVG», которая рассматривает множество практических примеров. Более подробно, читайте статью Алекса Уокера «Прощание с градиентами CSS3».

Вот детальный скриншот, демонстрирующий SVG спрайт:

Спрайт масштабируется превосходно (чего, к сожалению, нельзя сказать о моём текстовом shadow эффекте).

Лучше один раз увидеть, чем сто раз услышать. Я подготовил live demo, где продемонстрированы масштабируемые спрайты в действии, с обозначением техники сверху каждого примера.

Поддержа со стороны Браузеров

В начале статьи я заметил, что SVG недостаточно распространён. Хочется верить, что причина была в плохой поддержке со стороны браузеров. Но сейчас всё по-другому! Расцвет SVG происходил последние несколько лет, в связи с пониманием эффективности его использования.

По данным сайта Когда я смогу пользоваться?, поддержка SVG выглядит следующим образом (я объединил поддержку для свойств background-image (CSS) и img source (HTML) – как наиболее важных):

  • Internet Explorer 9+
  • Firefox 4+
  • Chrome 4+
  • Safari 4+
  • Opera 9.5+

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

В соответствии с некоторыми дополнениями к веб-стандартам, мы спокойно может реализовывать их, зная, что старые браузеры просто проигнорируют их и, что они даже не требуются. Мы называем это «progressive enchancement»: чем лучше браузер, тем лучше реализация. SVG — это немного другое, ведь он в большинстве случаев просто заменяет изображения в элементах CSS и HTML. Форматы изображений, будь-то SVG, PNG, JPG или GIF, они либо поддерживаются, либо нет. Здесь мы не можем просто следовать практике прогрессивного улучшения, т.к. изображения, которые невозможно отобразить, неприемлемы для реализации

ОПРЕДЕЛЯЕМ БРАУЗЕР ПОЛЬЗОВАТЕЛЯ ИЛИ ПОДДЕРЖКУ САМОЙ ВОЗМОЖНОСТИ

Мы можем сделать предположение и сказать, что беспокоиться следует только о пользователях Internet Explorer с 6-ой по 8-ую версию. В этом случае техника условных комментариев для IE позволяет применить в CSS второй background-image в одном из поддерживающихся форматах, таких как PNG, вместо используемого по умолчанию SVG.

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

Безопасный и настоятельно рекомендуемый способ заключается в определении поддержки SVG и использовании данной возможности, только в случае её поддержки. Я предлагаю использовать Modernizr, когда вам необходимо определить ряд функций. В случае обнаружения, Modernizr применяет класс SVG к вашему корневому html элементу (к которому можно добавить SVG в качестве background-image). Но всё немного сложнее, если вы используете SVG в качестве источника для изображения в HTML. Придётся дописать JavaScript, чтобы найти и заменить все источники разом, на случай, если поддержка была подтверждена.

Проблема этого метода в том, что браузер будет загружать запасные изображения до того, как поддержка SVG будет установлена — единственным исключением являются условные комментарии для IE. Пользователи могут также заметить моргание при перестроении содержимого, когда источник будет изменён. Это не будет долго продолжаться, но, по меньшей мере, на сегодня, эти проблемы могут быть достаточными, чтобы остановить вас от использования SVG.

ВЕС ФАЙЛА

В нашем примере вес SVG файла составил 2445 байт. Версия PNG весит всего 1064 байт (версия PNG 60 x 320 для удвоенных пикселей весит 1932 байта). На первый взгляд, векторное изображение проигрывает во всём, но при больших размерах, растровые изображения значительно набирают в весе.

Ещё SVG файлы удобны для чтения, благодаря использованию XML формата. Как правило, они содержат весьма ограниченный набор символов, что способствует их существенному GZip — сжатию при передаче по HTTP. Фактически, это значит что скачиваемый размер файла в разы меньше исходного, до 30% и, возможно, больше. Растровые изображения, такие как PNG и JPG уже изначально сжаты по-максимуму.

ПРОИЗВОДИТЕЛЬНОСТЬ

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

В качестве платформы для анимированной векторной графики SVG при последовательном испытании оказался медленнее Canvas, но нас интересует основное отображение, а не тысячи манипуляций в секунду, но если и это возможно, тогда простое отображение не должно быть проблемой. Более напряжёнными остаются такие возможности SVG, как маски и фильтр — эффекты. Они не нужны для большинства практических целей (таких как наш пример), но, при необходимости их использования, наилучшим путём оценки производительности остаётся тестирование. Множество интернет разработок поддерживается только в теории, а на практике результаты далеки от совершенства.

Альтернативные Методы

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

CSS3

Вы уже возможно начали комбинировать такие свойства CSS3, как linear-gradient, text-shadow и box-shadow с целью создания совокупных стилей. Веб разработчик Лиа Веру курирует CSS3 галерею образцов, которые демонстрируют впечатляющий потенциал одних только градиентов.

В своей статье «Мобильный Интернет в Высоком Разрешении», Бред Бирдсалл демонстрирует технику сохранения pixel-perfect для высокого разрешения, при помощи использования свойства pixel-ratio.

Кроме того, есть чистые CSS «иконки», которые Фарук Атеш справедливо считает «безумием» — естественно это так, если вы создаёте логотип при помощи CSS! Вы можете возразить, сославшись на небольшое количество полезных техник, таких как CSS треугольники, описанные Крисом Койером.

ВЕБ ШРИФТЫ

Шрифты с графическими маркерами (dingbat) и символы Unicode — вот две интересные альтернативы векторных иконок, как с семантической точки зрения, так и со стороны их доступности. Джон Хикс описал, пожалуй, лучшее об их использовании. SVG выглядит подходящим решением для иконок и имеет высокий потенциал касательно высокого разрешения. Мы, в ближайшем будущем, будем уделять этому повышенное внимание.

ЗАГЛЯДЫВАЯ В БУДУЩЕЕ

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

Принимая во внимание «one web» философию и широкий спектр устройств можно сделать вывод об отсутствии единого случая для всех пользователей. Чем больше мы можем сделать для познания новых устройств — тем лучше. Универсальный дизайн сайта способен удовлетворить большинство потребностей и дать ряд преимуществ. Использование векторной графики может быть не столь очевидным плюсом, но даже это незначительное улучшение даёт большую разницу.

Уже сегодня множество пользователей могут насладиться масштабируемой графикой… или, возможно, так неправильно думать. Большинство пользователей не скажет: «Вау! Слава вектору». Боюсь, они даже не примут это во внимание (и не оценят затраченных на это усилий). И это хорошо. Каждый раз, когда мы улучшаем что-то для пользователей, мы не нуждаемся в посвящении этому песен с танцами. Оправдывайте ожидания пользователей в визуальной эстетике и со временем они сами научаться замечать «низкопробные» сайты. Если этого не сделаете вы, это сделают другие.

Оригинал

P.S. Это тоже может быть интересно:

10 комментариев

  1. Правильный ли я делаю вывод- судя по тенденции Responsive Website Design-а желательно размер шрифта(или изображения) вычислять в em-ах?

    1. С em-ами просто удобнее «адаптировать» только размер шрифта внешнего элемента (body), а внутри уже «плясать» от него. С rem-ами, конечно, будет еще удобнее — вопрос лишь как скоро…

      Кстати, по сильно непроверенным слухам, в довольно скором времени на этом сайте может выйти шикарнейшая статья о единицах длины в сегодняшнем и завтрашнем CSS, так что следите за обновлениями!

      1. Вот тут как раз поясни, Макс. Мне как начинающему верстальщику. То есть дочерние элементы от body должны уже задаваться в процентах?
        Просто я пробовал все задавать в em.
        Но если я уже прописываю body {font: normal 1.2em Arial,sans-serif;}
        то получается что следующие за ним теги, например:
        h3 {font-size: 1.4em}
        Будут отсчитывать em от той величины, которая присвоена body?
        Надеюсь, что понятно объяснил…

        1. Именно так. Можно даже для body задавать размер в пикселах (через медиазапросы, для разных размеров окна — разные), тогда дочерние элементы будут автоматически менять свой размер шрифта пропорционально размеру шрифта body (напр. если для h1 задать 2em — заголовки всегда будут вдвое крупнее основного текста, неважно, отображается ли тот 30-пиксельным шрифтом на 27-дюймовом мониторе либо 10-пиксельным на крошечном нетбуке).

          Ну а векторные картинки, если их «правильно готовить», будут масштабироваться как надо и вовсе независимо от этого.

  2. SVG — технология хоть и старая, но будет по-настоящему полезна только в будущем, сейчас же она слабо применима как минимум на коммерческих проектах. Во-первых, IE7/8, во-вторых — дефолтные андроидные браузеры. А костыли не всегда справляются.
    Можно делать конечно по принципу graceful degradation, но опять же — не подходит для проектов с ограниченными бюджетами и естимейтами, т.к. требует дополнительного времени на все ветки.

  3. По-настоящему SVG можно будет, когда вступит в силу CSS3 Images, а браузеры внедрят запись image() из этого модуля. Она хороша тем что позволяет перечислять картинки, и браузер загрузит ту, которую поддерживает. Например:
    background-image: image(«wavy.svg», ‘wavy.png’).
    Для старых браузеров тогда можно будет просто оставить стандартный PNG:
    background-image: url(«wavy.png»).
    background-image: image(«wavy.svg», «wavy.png»).

  4. Я предполагал, что сделать спрайт в svg возможно, но сомневался, а тут уже точно убедился в этом. Очень полезная статья, правда про SVG некоторые моменты не понятны, например, откуда взялся первоначальный svg-файл?
    И да, еще можно в CorelDRAW сложить спрайт и сохранить в svg формате.
    Делал относительные размеры для одного изображения, интересно получилось. А вот спрайт с относительными размерами надо попробовать, пока не уверен, получится ли позиционировать фон в таком спрайте.. :)

Оставить комментарий

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

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