Краткий обзор плагина Sass CSS Importer для импортирования файлов CSS в файлы Sass.

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

Например, подключить файл typography.scss в файл main.scss можно так:

@import _typography;

Оба файла main.scss и typography.scss будут объединены препроцессором в один файл main.scss, который уже будет компилироваться в файл main.css.

Знак подчеркивания в данном случае является дополнительной опцией. Этим знаком препроцессору Sass указывается не выполнять предварительную компиляцию файла typography.scss в файл typography.css перед его подключением в main.scss.

Но что, если стоит задача подключения файлов формата CSS в файлы формата Sass? Директива @import в этом случае помочь не может. CSS-файл нельзя просто так подключить в Sass-файл.

Задача подключения CSS-файлов в Sass-файлы наиболее часто может возникнуть в случае использования различных готовых слайдеров или каруселей, которые зачастую идут “в комплекте” с минимальными правилами на CSS. Что же делать?

Плагин Sass CSS Importer

Совсем недавно (17 июля сего года) Chris Eppstein выпустил специальный плагин, задачей которого и является импортирование CSS-файлов в Sass-файлы. Страничка с официальной документацией по плагину Sass CSS Importer расположена на GitHub - Sass CSS Importer Plugin.

Там все описано кратко и предельно ясно. Однако, я был так доволен тем фактом, что теперь могу свободно подключать CSS в Sass, что решил потратить часть своего времени, чтобы описать его своими словами, по-русски.

Установка Sass CSS Importer

Установка плагина выполняется как обычно, через менеджер пакетов gem:

$ sudo gem install --pre sass-css-importer

Подключение Sass CSS Importer

При использовании фреймворка Compass нужно добавить строку в конфигурационный файл config.rb своего текущего проекта:

require sass-css-importer

Импортирование CSS в Sass

Теперь, чтобы импортировать CSS в Sass, нужно воспользоваться все той же директивой @import, но со специальным синтаксисом.

В общем случае этот синтаксис выглядит таким образом:

@import CSS:имя_директории/имя_css_файла;

В частном случае синтаксис будет выглядеть таким образом:

@import CSS:carousel;

Обратите внимание на важный момент: имя CSS-файла нужно указывать без расширения!

Можно запустить процесс компиляции через командную строку:

$ compass watch

… и проверить, что CSS-файл будет включен в общий вывод:

Плагин Sass CSS Importer

Заключение

В принципе, вот и все, что можно сказать о Sass CSS Importer.


Статья посвящена вопросу “тихих” placeholder’ов в препроцессоре Sass. Что это такое и в чем преимущество их использования.

Оригинал статьи размещен здесь - Understanding placeholder selectors.

Препроцессор Sass предоставляет несколько способов создания одного фрагмента кода, который будет многократно использоваться внутри CSS-кода.

Например, можно воспользоваться миксинами (mixins) для вставки группы CSS-свойств (или CSS-правил) в CSS-коде.

Или же использовать директиву @extend для расширения набора CSS-свойств одного HTML-элемента за счет CSS-свойств другого HTML-элемента.

В Sass версии 3.2 введена новая концепция под названием placeholder, которая делает использование директивы @extend еще более эффективным способом.

Но прежде чем мы перейдем к рассмотрению этого нововведенния, давайте остановимся на моменте, каким образом работает расширение (@extend) CSS-свойств в Sass.

Как работает @extend

Директива @extend в препроцессоре Sass позволяет CSS-селекторам с легкостью обмениваться между собой своими CSS-свойствами. Лучше всего вышесказанное можно проиллюстрировать на живом примере:

.icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  @extend .icon;
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  @extend .icon;
  /* здесь - специфичные стили класса .info-icon */
}

Результатом компиляции этого SCSS-кода в CSS-код будет следующий фрагмент:

.icon, .error-icon, .info-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  /* здесь - специфичные стили класса .info-icon */
}

Рассмотрим “механизм” показанного выше примера более детально. В нем директива @extend играет ключевую роль. С помощью нее селекторы .error-icon и .info-icon наследуют свойства селектора .icon. При изменении CSS-свойств селектора .icon автоматически будут меняться свойства селекторов .error-icon и .info-icon, так как они наследуют определенный набор CSS-свойств у селектора .icon. Довольно изящный подход, не правда ли?

А вот теперь наступает интересный момент. Что, если элемент с классом .icon не планируется использовать и он даже не будет присутствовать в HTML-разметке? Но CSS-свойства этого элемента нам нужны для стилизации элементов .error-icon и .info-icon.

Получается, что результирующий CSS-код будет неоправданно раздут из-за того, что в нем присутствует “лишний” элемент, который напрямую никогда не будет использован.

И тут наступает момент для выхода на сцену героя этой статьи - селектора placeholder (его еще называют “тихим” placeholder‘ом):

Тихий placeholder

Знакомимся с селектором placeholder

Селекторы placeholder были введены в Sass как раз для того, чтобы решать вышеназванную проблему. Синтаксис placeholder очень похож на синтаксис обычных CSS-классов, только вместо точки (.) перед именем ставиться символ процента %.

Селекторы placeholder имеют одну специфичную для них особенность - они никак не проявляют себя в скомпилированном CSS-коде. Можно сказать по другому - вы никогда не найдете селекторов placeholder в результирующем CSS-коде (поэтому они и носят такое название - “тихие” placeholder). В скомпилированном CSS-коде будут только селекторы, которые используют “тихие” placeholder‘ы, но никак не сами “тихие” placeholder‘ы.

Вернемся назад, к нашему начальному примеру. Заменим в нем имя класса .icon на имя “тихого” placeholder’а - %icon:

%icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  @extend %icon;
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  @extend %icon;
  /* здесь - специфичные стили класса .info-icon */
}

В результате скомпилированный CSS-код будет выглядеть таким образом:

.error-icon, .info-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  /* здесь - специфичные стили класса .info-icon */
}

Обратите внимание на важный момент - класс .icon теперь не присутствует в результирующем CSS-коде! Его там нет!

@extend или @include

На первый взгляд может показаться, что “тихие” placeholder - это почти тоже самое, что и миксины (mixin). С функциональной точки зрения такое утверждение абсолютно верно - результат в браузере получается идентичным. А вот с точки зрения CSS разница очень существенная!

Давайте снова изменим наш первоначальный пример и теперь воспользуемся миксином @mixin icon:

@mixin icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

.error-icon {
  @include icon;
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  @include icon;
  /* здесь - специфичные стили класса .info-icon */
}

Посмотрим на сгенерированный CSS-код:

.error-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
  /* здесь - специфичные стили класса .error-icon */
}

.info-icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
  /* здесь - специфичные стили класса .info-icon */
}

С точки зрения разработки данный пример ничем не хуже примера с использованием “тихого” placeholder‘а.

Но обратите внимание на тот факт, что CSS-правила transition: background-color ease .2s; и margin: 0 .5em; дублируются между селекторами .error-icon и .info-icon, что приводит к неоправданному раздутию кода. В случае использования “тихого” placeholder этого не происходит.

Ограничения

Использование директивы @extend имеет одно ограничение, связанное с тем, что применение “тихих” placeholder‘ов никак не оправдывает себя в медиа-запросах @media.

Рассмотрим такой пример:

%icon {
  transition: background-color ease .2s;
  margin: 0 .5em;
}

@media screen {

  .error-icon {
    @extend %icon;
  }

  .info-icon {
    @extend %icon;
  }

}

Видим, что в данном случае “тихий” placeholder добавлен для селекторов, находящихся внутри медиа-запроса @media.

Однако, при попытке компиляции этого SCSS-кода в CSS-код получиться ошибка:

You may not @extend an outer selector from within @media. You may only @extend selectors within the same directive. From “@extend %icon” on line 8 of icons.scss

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

Механизм работы директивы @extend основан на добавлении одного селектора к другому селектору без необходимости дублировать CSS-свойства этих селекторов. Однако невозможно объединять селекторы, находящиеся в разных медиа-запросах @media.

Но можно поступить по другому, чтобы выйти из данной затруднительной ситуации. Любой медиа-запрос, который служит оберткой для “тихого” placeholder, распространяют свои свойства на селекторы, не размещенные внутри этого запроса.

Выражение достаточно запутанное, поэтому лучше приведу пример:

@media screen {
  %icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}

.error-icon {
  @extend %icon;
}

.info-icon {
  @extend %icon;
}

Компиляция пройдет без ошибок и ее результатом будет CSS-код:

@media screen {
  .error-icon, .info-icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}

Заключение

Обе директивы @extend и @include являются очень полезными инструментами, между которыми существует тонкое различие. Если вопрос производительности генерируемого CSS-кода имеет для вас важное значение или же перед вами стоит проблема повторяемости кода, то решением будет являться директива @extend. В некоторых случая @extend значительно упрощает получаемый CSS-код и улучшает его производительность.

Конечно же, ничто не мешает вам смешивать между собой директиву @extend и миксин mixin (если этого требуют обстоятельства):

@media screen {
  %icon {
    transition: background-color ease .2s;
    margin: 0 .5em;
  }
}

@mixin icon($color, $url) {
  @extend %icon;
  background-color: $color;
  background-url: url($url);
}

.error-icon {
  @include icon(red, /images/error.png);
}

.info-icon {
  @include icon(blue, /images/info.png);
}

Однако, в разработке я придерживаюсь такого подхода, когда исходный код легко читается и поддерживается.


В этом посте поделюсь своим опытом реализации задачи компиляции jade-файлов в HTML-формат.

Рассмотрю два способа реализации этой задачи. Первый - самый нативный, с помощью родной утилиты jade. Второй - с помощью плагина gulp-jade под Gulp.

Но способов компиляции Jade в HTML существует больше - есть плагин под Sublime Text, существует плагин под Grunt. Обладатели Mac OS X могут воспользоваться прекрасной программой CodeKit. И я уверен, что это только малая часть того, чем можно воспользоваться.

Кратко остановлюсь на вопросе, зачем мне понадобился Jade. Честно сказать, до недавнего момента я даже не подозревал о сущестовании такого шаблонизатора. Тихо-спокойно пользовался Sublime Text + Emmet и считал, что я на вершине современных требований к web-разработчику.

Однако это оказалось не совсем так. Мне посоветовали посмотреть в сторону Jade и разобраться с работой в нем. Хотя бы с синтаксисом, для начала.

И я скажу вам - мне понравилось! Даже простое использование синтаксиса. Первое впечатление и ощущение - использование этого шаблонизатора освобождает от рамок HTML при написании кода. Точнее - при создании кода сосредотачиваешься на содержимом, которое создаешь.

Но у Jade есть еще и миксины, с которыми мне предстоит познакомиться. Так что - лучшее только впереди!

Написание кода в этом шаблонизаторе чем-то похоже на написание текста в Markdown. Под Markdown имеются (и должны иметься) утилиты\программы для компиляции в HTML. Точно также для Jade должны иметься (и имеются) утилиты\программы для компиляции в HTML.

Jade - синтаксис для Sublime Text

Прежде чем писать код в редакторе, в моем случае необходимо настроить поддержку синтаксиса Jade. Я использую Sublime Text 3, который изначально не имеет таковой.

Исправить это легко - достаточно через Package Control установить пакет Jade. Помимо подсветки синтаксиса, появиться поддержка автоматической табуляции, что значительно упрощает процесс написания кода.

Пример подсветки синтаксиса Jade в Sublime Text:

Пример подсветки синтаксиса Jade в Sublime Text

Jade - родная утилита шаблонизатора

Разработчиками была создана родная утилита для преобразования jade-файлов в HTML-файлы. Имя утилиты легко запомнить - это jade.

Утилита является модулем под Node.js, поэтому последний у вас должен быть заранее установлен (если еще не установлен по какой-то необъяснимой причине).

Инсталляция утилиты производиться банально:

$ sudo npm install -g jade

Утилита имеет немногочисленные параметры, с кратким описанием которых можно ознакомиться на странице официальной документации - Jade - Command Line.

Но стоит обратить внимание на некоторые интересные параметры:

К примеру:

  • -P, --pretty - создание “удобочитаемого” HTML-кода
  • -w, --watch - мониторинг изменений файлов

Использование утилиты также является простым делом. К примеру, можно указать ей производить компиляцию всех файлов в директории templates:

$ jade templates

Утилита может сама создавать jade-файлы:

$ jade {foo,bar}.jade

Или же можно реализовать два способа вывода:

$ jade > my.jade > my.html
$ echo "h1 Jade!" | jade

Или же осуществить рендеринг двух директорий foo и bar в директорию tmp:

$ jade foo bar --out /tmp

Gulp-jade - компиляция под Gulp

Кто знаком с task-manager’ом Gulp, тот может воспользоваться соответствующим плагином gulp-jade под него. Страничка плагина размещена здесь - gulp-jade.

Установка плагина стандартная:

$ npm install --save-dev gulp-jade

Затем нужно создать задачу (task) для компиляции jade-файлов в HTML-файлы. Ниже приведу свой рабочий task:

var gulp = require('gulp'),
jade = require('gulp-jade');

// Jade
gulp.task('jade', function(){
  gulp.src('./template/*.jade')
    .pipe(jade())
    .pipe(gulp.dest('./dist/'))
});

// Watch
gulp.task('watch', function(){
 gulp.watch('./template/*.jade',['jade']);
});

В Сети есть еще один интересный Gulp-task. Работоспособность его не проверял, взял как есть, для - “чтобы было”.

Как говориться на странице-оригинале, эта задача производит компиляцию файлов из директории app/ в директорию _public/:

jade = require 'gulp-jade'

gulp.task 'jade', ->
  gulp.src parameters.app_path + '/*.jade'
  .pipe jade pretty: true
  .pipe gulp.dest parameters.web_path
  .on 'error', gutil.log

Заключение

Я запомнил (записал для себя), а вы (уважаемый читатель) познакомились (если не знали) с двумя способами настройки компиляции jade-файлов в HTML-файлы.

На этом все.


Отличный пример создания parallax scrolling с помощью Stellar.js. Оригинал статьи размещен здесь - An Introduction to Parallax Scrolling Using Stellar.js.

Одним из наиболее обсуждаемых трендов в web-дизайне последние несколько лет является эффект parallax scrolling. Нравиться он вам или нет, но этот эффект сегодня применяется на очень многих сайтах. В этой статье будет дано краткое описание принципа parallax scrolling и будет показано, как применить этот эффект на странице с помощью jQuery-плагина под названием Stellar.js.

Что такое parallax scrolling

Основная идея parallax scrolling заключается в том, что при прокрутке страницы вниз фоновое изображение движется с меньшей скоростью, нежели содержимое страницы. Таким образом создается иллюзия 3D на странице. Этот эффект является прекрасным дополнением к web-странице, однако он становиться навязчивым при чрезмерном злоупотреблении им. Время от времени вы встречаете на просторах Сети сайты, перегруженные подобными эффектами. И вам не всегда может такое понравиться. Потому что в основном при реализации такого эффекта используется анимация фоновых изображений, что значительно увеличивает вес страницы, в результате чего она очень медленно загружается в браузере.

Примерами сайтов со злоупотреблением таких эффектов, на мой взгляд, могут послужить Saucony Kinavara 3 и Oakley Airbrake MX. Первый сайт “весит” 50Mb(!), второй сайт - около 20Mb.

Теперь, когда вы имеете представление о том, как на деле выглядит эффект parallax scrolling, давайте попробуем реализовать его с помощью плагина Stellar.js.

Что такое Stellar.js

Stellar.js - это jQuery-плагин, с помощью которого можно легко реализовать эффект parallax scrolling на web-странице. Несмотря на то, что этот плагин уже не поддерживается разработчиком, он все еще остается очень надежным, совместим с самыми последними версиями библиотеки jQuery и часто применяется web-разработчиками в проектах (что является показателем). Stellar.js в списке популярных плагинов The jQuery Plugin Registry находится на высших позициях, поэтому вы наверняка о нем слышали или же читали упоминание о нем.

Отлично, вкратце мы познакомились, что такое Stellar.js и можно приступать к процессу создания parallax scrolling на странице с его помощью.

Stellar.js - начинаем работу

Начать работать с плагином Stellar.js очень просто. Для начала нужно скачать этот плагин и подключить к странице. Получить плагин Stellar.js можно двумя способами - из Git-репозитория или с помощью менеджера пакетов Bower. Если остановится на использовании Bower, то в консоли нужно набрать такую команду:

bower install jquery.stellar

Когда плагин Stellar.js получен любым из вышеописанных способов, необходимо подключить его к странице как обычно.

После подключения плагина Stellar.js все готово для того, чтобы применить эффект parallax scrolling на странице. Этот плагин позволяет применить данный эффект к любому scrolling-элементу на странице, будь то объект window или любой другой. Для этого нужно выполнить выборку нужного элемента с помощью jQuery, а затем применить к выбранному элементу метод stellar().

Самый простой пример применения плагина Stellar.js к объекту показан ниже:

$(#someElement).stellar();

Для объекта window можно использовать и более краткий синтаксис вышеприведенного примера:

$.stellar();

В этом коде производится поиск фоновых изображений или элементов, к которым применяется эффект parallax; и для этих элементов выполняется пересчет их расположения на web-странице при ее прокрутке.

Если вам хочется взглянуть хотя бы на один готовый пример страницы с parallax scrolling, созданной с помощью Stellar.js, то можете посетить эту ссылку - Stellar.js Backgrounds Demo.

Настройки Stellar.js

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

Глобальные настройки передаются методу stellar() в качестве аргументов, в момент вызова этого метода. Специфичные для элемента настройки передаются в виде data-*-атрибутов. В этом разделе статьи я не буду подробно останавливаться на рассмотрении всех возможных параметров плагина Stellar.js. Если у вас возникнет желание детально ознакомиться с ними, то можно обратиться к разделу, посвященному этому вопросу - Configuring Everything.

Одной из основных настроек плагина, которая может понадобиться в первую очередь, является выбор направления, в котором будет осуществляться эффект. Классическим вариантом parallax scrolling является направление parallax по вертикали - сверху вниз или же наоборот. Однако, с помощью настроек можно задать parallax по горизонтали - слева направо и наоборот. И даже можно задать сразу два направления - по вертикали и по горизонтали. Для управления направлением parallax в плагине Stellar.js имеются два параметра Boolean-типа:

  • horizontalScrolling - для управления parallax по горизонтали
  • verticalScrolling - для управления parallax по вертикали

По умолчанию оба параметра имеют значение true.

Другим интересным параметров плагина Stellar.js является responsive. Данная настройка отвечается за возможность обновления содержимого блока с эффектом parallax при наступлении событий load и resize объекта window. Значением по умолчанию является false.

Последним (достойным внимания) глобальным параметром плагина Stellar.js является hideDistantElements. Значением по умолчанию этого параметра является true. Данный параметр отвечает за эффект скрытия объекта в том случае, когда он выходит на границы viewport. Если такое поведение вам не нужно, то можно поставить значение hideDistantElements в false.

Единственным специфичным для элемента параметром плагина Stellar.js, о котором я расскажу в этой статье, является data-stellar-background-ratio. Расскажу только потому, что он используется очень часто при работе с плагином Stellar.js. Параметр принимает в качестве значения положительное число и управляет скоростью parallax для выбранного элемента.

Например, data-stellar-background-ratio="0.5" означает, что скорость перемещения элемента при scrolling будет в два раза меньше обычной. Если вы будете использовать данный параметр со значением, меньшим 1, то, согласно документации, для элемента с parallax необходимо применить CSS-правило background-attachment: fixed;.

Теперь, когда мы познакомились с плагином Stellar.js и научились управлять им с помощью параметров, самое время посмотреть его в действии.

Demo

В этом разделе статьи мы создадим пример кода, в котором применим плагин Stellar.js и настроим его с помощью параметров, рассмотренных ранее. Первым делом нам понадобиться HTML-разметка. Для этого создадим шесть блоков div, внутри которых будет содержаться некоторый текст:

<div class="content" id="content1">
  <p>text here</p>
</div>
<div class="content" id="content2">
  <p>text here</p>
</div>
<div class="content" id="content3" data-stellar-background-ratio="0.5">
  <p>text here</p>
</div>
<div class="content" id="content4" data-stellar-background-ratio="0.5">
  <p>text here</p>
</div>
<div class="content" id="content5" data-stellar-background-ratio="0.5">
  <p>text here</p>
</div>
<div class="content" id="content6" data-stellar-background-ratio="0.5">
  <p>text here</p>
</div>

Для представленной выше HTML-разметки необходимо написать некоторые CSS-стили для задания фоновых изображений. В нашем примере будут использоваться три изображения, при этом каждое из них будет использоваться дважды. Так как к последним трем блокам div применен атрибут data-stellar-background-ratio, то в CSS-стилях также необходимо прописать правило background-attachment: fixed;.

Финальный вариант CSS-кода будет выглядеть таким образом:

@import "compass";
@import "compass/reset";

$white: #fff;
$black: #000;

body {
  font-size: 20px;
  color: $white;
  text-shadow: 0 1px 0 $black, 0 0 5px $black;
}

p {
  padding: 0 .5em;
  margin: 0;
}

.content {
  background-attachment: fixed;
  height: 400px;
  line-height: 400px;
  text-align: center;
}

#content1 {
  background-image: url("http://www.tamperlock.com/blog/wp-content/uploads/2014/08/london-england.jpg");
}

#content2 {
  background-image: url("http://ocdn.eu/images/pulscms/ZjU7MDQsMCwzMiwzODQsMWZhOzA2LDMyMCwxYzI_/1eb29a70dabd0994cdefaad01ca3c884.jpg");
}

#content3 {
  background-image: url("http://www.zeus.aegee.org/magazine/wp-content/uploads/napoli-golfo-vesuvio.jpg");
}

#content4 {
  background-image: url("http://www.tamperlock.com/blog/wp-content/uploads/2014/08/london-england.jpg");
}

#content5 {
  background-image: url("http://ocdn.eu/images/pulscms/ZjU7MDQsMCwzMiwzODQsMWZhOzA2LDMyMCwxYzI_/1eb29a70dabd0994cdefaad01ca3c884.jpg");
}

#content6 {
  background-image: url("http://www.zeus.aegee.org/magazine/wp-content/uploads/napoli-golfo-vesuvio.jpg");
}

Последний шаг, который нужно выполнить, это запустить эффект, вызвав метод stellar(). Этому методу также передадим несколько аргументов:

$.stellar({
  horizontalScrolling: false,
  responsive: true
});

Stellar.js - parallax scrolling with jQuery

Заключение

В данной статье был рассмотрен плагин Stellar.js для создания эффекта parallax на web-странице. Мною не были рассмотрены все настройки и возможности этого плагина. Но целью этой статьи было заинтересовать читателей плагином Stellar.js для того, чтобы продолжить его изучение самостоятельно.

Что вы думаете о плагине Stellar.js? Вы слышали о таком или же используете его давно?


Примечание переводчика: статья просто отличная и написана мастером своего дела Nick.

Немного лирики “для тех, кто в танке” - fallback можно в данном контексте перевести как - “откат”. То есть, если браузер по каким-то причинам не поддерживает SVG, то на web-странице выполняется “откат” - SVG-изображения заменяются на PNG-изображения.

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

Далее - текст автора по имени Nick (в вольном переводе).

В следующих четырех сниппетах я рассмотрю применение метода SVG fallback c помощью PNG-изображений четырьмя различными способами. Все четыре способа направлены на одну цель - обеспечение кросс-браузерной поддержки SVG на web-странице.

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

Ниже показаны сниппеты, которые тремя различными путями осуществляют применение SVG, а также SVG fallback к изображениям формата PNG, если браузер не поддерживает SVG.

Что мы будем рассматривать:

  • SVG в качестве фонового изображения, fallback с помощью Modernizr
  • SVG в качестве фонового изображения, fallback с помощью CSS
  • SVG в качестве встраиваемого изображения (тег img), onerror fallback
  • SVG в качестве встраиваемого изображения (тег img), , fallback с помощью Modernizr

Modernizr является прекрасным инструментом для определения возможностей браузера. Она автоматически добавляет ко всем HTML-элементам в DOM классы в зависимости от того, поддерживает браузер ту или иную возможность или нет. В нашем случае, Modernizr будет добавлять класс svg или no-svg для всех элементов в DOM в зависимости от того, поддерживает ли браузер SVG.

SVG в качестве фонового изображения, fallback с помощью Modernizr

Используя Modernizr, мы отпеределяем, поддерживает браузер SVG или нет. Если SVG используется в качестве фонового изображения, то тогда проще сохранить изображения для страницы в двух верысиях - SVG и PNG (прим. переводчика: например, IcoMoon умеет так делать). В таблице стилей CSS тогда нужно добавить дополнительный класс. При таком подходе исключается двойная загрузка файлов (SVG и PNG), так как класса no-svg просто не существует в DOM, если браузер поддерживает SVG, и наоборот.

.tomato {
  background-image: url(img/tomato.svg);
}
.no-svg .tomato {
  background-image: url(img/tomato.png);
}

SVG в качестве фонового изображения, fallback с помощью CSS

Этот способ будет даже немного покруче, так как он не зависит от какой-либо библиотеки. Даже если библиотека Modernizr подключена у вас в проекте, в этом случае она уже не играет никакой роли. Но если вы подключили библиотеку Modernizr в проект только для того, чтобы реализовать откат (fallback) для фоновых изображений SVG, то вам лучше воспользоваться рассматриваемым методом.

Данный метод основан на маленькой хитрости, заключающейся в том, что поддержка множественных фоновых изображений (multiple background) в браузерах почти точно такая же, что и поддержка SVG. Другими словами, если браузер не поддерживает множественные фоны (multiple background), то он не будет поддерживать и SVG. В результате по коду произойдет откат (fallback) до первой строки, в которой прописано отображение PNG-версии файла.

.tomato {
  background: url(img/tomato.png);
  background-image: url(img/tomato.svg), none;
}

SVG в качестве встраиваемого изображения (тег img), onerror fallback

Для этого метода необходимо редактирование HTML-кода. Основан метод на использовании Javascript-функции onerror, которая встраивается внутрь HTML-тега <img>. Благодаря этой функции осуществляется откат (fallback), если браузер не смог загрузить изображение по пути, указанному в атрибуте src.

Однако, с етим методом нужно быть осторожным. Если отката (fallback) не произойдет, то некоторые браузеры могут “зависнуть” в бесконечном цикле. Это явно не хорошо.

<img src="tomato.svg" onerror="this.src=tomato.png" />

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

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

Зависания браузера в бесконечном цикле можно избежать благодаря небольшой поправке, которую подсказал Roy Reed:

<img src="tomato.svg" onerror="this.src=tomato.png; this.onerror=null;" />

SVG в качестве встраиваемого изображения (тег img), fallback с помощью Modernizr

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

Если браузер поддерживает SVG, то строку с тегом img отставляем “как есть”:

<img src="tomato.svg" />

Если же браузер пользователя не поддерживает SVG, то запускается мальнький скрипт, который отыскивает в DOM все img-элементы с атрибутом src="*.svg" и производит у файлов-изображений замену расширения с svg на png.

Чтобы метод сработал, необходимо иметь две версии (SVG и PNG) одного файла; имена файлов должны быть идентичными.

Ниже показан HTML и Javascript. Чтобы пример сработал, убедитесь, что подключили библиотеку Modernizr:

<img src="tomato.svg" />
if(!Modernizr.svg) {
  var imgs = document.getElementsByTagName(img);
  var svgExtension = /.*\.svg$/
  var l = imgs.length;
  for(var i = 0; i < l; i++) {
    if(imgs[i].src.match(svgExtension)) {
      imgs[i].src = imgs[i].src.slice(0, -3) + png;
      console.log(imgs[i].src);
    }
  }
}

Заключение

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

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

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

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

Если открыть любой SVG-файл в редакторе кода, то можно увидеть SVG-код, на котором написан данный файл.

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

На этом все.