Кроссбраузерный SVG логотип
Продолжая тему SVG предлагаю вам ознакомиться с кроссбраузерным вариантом логотипа, который будет замечательно выглядеть на Ретина дисплеях и обычных мониторах благодаря совместному использованию SVG и PNG графики. Также в конце статьи вы увидите, как сделать его еще и адаптивный. Ну а заодно затрону тему семантики верстки.
Конечно, еще проведено мало тестов, не во всех браузерах проведены испытания, ибо нет такой возможности, но данный пример уже можно использовать, не боясь, и, по мере нахождения багов и испытания в разных браузерах, буду обновлять пост.
Поддержка на данный момент:
- SVG «режим» Firefox 4+, Сhrome 4.0+, Opera 11.6+, Safari 4.0, IE10+
- PNG «режим» Firefox 3.6-, IE9-
Содержание:
Семантичный код
Для логотипа самая правильная конструкция является следующей
<h1>
<a href="#" id="logo">Фирма "Логотип"</a>
</h1>
Использование надписи полезно для поисковиков и для индивидов с отключенными CSS или особенными браузерами.
Стили
#logo {
background: url('logotype-trans.png') center center no-repeat transparent;
background-image: url('logotype.svg'), -khtml-linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), -webkit-linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), url('logotype-trans.png');
background-image: url('logotype.svg'), -ms-linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), -o-linear-gradient(transparent, transparent);
background-repeat: no-repeat, no-repeat;
-moz-background-size: 0 0, 100% 100%; /* FF3.6 */
background-size: 100% 100%, 0 0;
/* Скрываем текст */
overflow: hidden;
text-indent: -9999px;
font-size: 0;
color: rgba(255,255,255,0);
/* Устанавливаем размеры логотипа */
display: block;
height: 83px;
width: 300px;
}
И вот тут самое интересное.
Первым background’ом мы делаем фон для старых браузеров типа IE6-7 и отдаем ему PNG картинку. В примере использован логотип с прозрачностью, но ведь Internet Explorer не поддерживает прозрачные PNG! Для него я использовал скрипт фиксов ie7(9).js
<!--[if lt IE 9]>
<script src="http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script>
<![endif]-->
Следующим этапом необходимо было как-то подключить SVG, но при этом для старых версий браузеров оставить PNG. И тут выяснилось, что почти все браузеры примерно одновременно с поддержкой SVG выпустили поддержку Multiple Backgrounds и градиенты. Воспользовавшись этими данными, мы прикручиваем SVG через Multiple Backgrounds. Таким образом, если в браузере нет поддержки Multiple Backgrounds и Linear Gradient, то браузер не поймет данную конструкцию и воспользуется первым условием. И всё бы хорошо, но тут всплыли два бага:
- Firefox 3.6 поддерживает Multiple Backgrounds и Linear Gradient, но не поддерживает SVG. Так же выяснил, что FF3.6 поддерживает
background-size
только с префиксом, а FF4 уже без префикса. Этим и воспользуемся. Теперь для FF3.6 — будет отдаваться PNG, а для старших версий — SVG. - В Опере пока полностью протестировать не получилось. Был баг, что она не хотела показывать SVG. Однако, сегодня при тестах она уже передумала и показывает.
Далее мы скрываем текст несколькими способами сразу, для кучи. Хотя, для этого достаточно только первых двух строк (overflow и text-indent).
В последнем блоке идет отстраивание размера и позиции в зависимости от требований к макету/дизайну.
Responsive / Adaptive
Если верстка подразумевает Responsive Web Design или Adaptive Web Design, то разумеется без CSS3 Media Queries не обойтись. В основном, при вёрстке под Responsive Web Design или Adaptive Web Design разделение идёт «для нормального разрешения» и «для уменьшенного разрешения» за счет CSS3 Media Queries. В первом случае всё понятно, и вполне может подойти вариант выше. Вот для маленьких разрешений приходится подстраиваться.
Первым делом надо определиться, какой высоты будет шапка и отведенное место под логотип, а затем подстраиваться под эту высоту. Остальное браузер сделает за нас с помощью атрибута contain для background-size:
background-size: contain;
Таким образом наш предыдущий код меняется всего в одной строке
#logo {
background: url('logotype-trans.png') center center no-repeat transparent;
background-image: url('logotype.svg'), -khtml-linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), -webkit-linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), url('logotype-trans.png');
background-image: url('logotype.svg'), -ms-linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), linear-gradient(transparent, transparent);
background-image: url('logotype-trans.png'), -o-linear-gradient(transparent, transparent);
background-repeat: no-repeat, no-repeat;
-moz-background-size: 0 0, contain; /* FF3.6 */
background-size: contain, 0 0;
/* Скрываем текст */
overflow: hidden;
text-indent: -9999px;
font-size: 0;
color: rgba(255,255,255,0);
/* Устанавливаем размеры логотипа */
display: block;
height: 83px;
width: 300px;
}
А далее, уже с помощью Media Queries меняем третий блок кода, не забывая указывать высоту. Например:
@media (max-width:800px){
#logo {
/* Устанавливаем размеры логотипа */
height: 50px;
width: 100%;
}
}
Преимущества и недостатки
Преимущества
- В современных браузерах, таких как Firefox, Chrome, Safari и Opera, в том числе и мобильные версиях, логотип будет векторный, что позволяет его масштабировать как душе угодно без потери качества
- SVG версия логотипа весит в несколько раз меньше. Для примера логотип из статьи в PNG 300×83 весит 6 Кб, в SVG — 2,8 Кб, в SVGZ — 1,2 Кб. При использование SVGZ советую его проверить во всех браузерах, в том числе для надежности и в FF4, ибо Firefox очень привередливый к SVGZ, точнее в нём есть баг. Будьте аккуратны или даже воздержитесь от использования SVGZ.
- Помимо мобильных версий, логотип будет прекрасно работать без танцев с бубнами на Ретина дисплеях.
Недостатки
- Решение пока в бета стадии, ещё не все браузеры проверены
- В опере замечен неприятный баг — при зуме страницы SVG увеличивается не равномерно. Это давно известный баг оперы, который исправлять не спешили. С переходом Оперы на chromium можно надеяться что этот баг они собой не прихватят.
Без изменений
- Для IE6-9, равно как и для других старых браузеров, логотип пока остается неизменным, в формате PNG
Демонстрация
Уменьшите размер окна браузера до ширины менее 800px, чтобы увидеть результат работы
Демонстрация на отдельной странице
Вот и всё, ребята!
Хак для IE8
Добавлено 16 марта 2014
Internet Explorer 8 не захотел работать как предполагалось, а я это ранее проморгал. Спасибо Александру за найденный баг. Для IE8 придется применить хак.
#logo {
background: url('logotype-trans.png') center center no-repeat transparent;
background-image: url('logotype.svg'), -khtml-linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), -webkit-linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), url('logotype-trans.png');
background-image: url('logotype.svg'), -ms-linear-gradient(transparent, transparent);
background-image: url('logotype.svg'), linear-gradient(transparent, transparent);
background-image: url('logotype-trans.png'), -o-linear-gradient(transparent, transparent);
background: url('logotype-trans.png') center center no-repeat transparent\0/; /* IE8 hack */
background-repeat: no-repeat, no-repeat;
-moz-background-size: 0 0, contain; /* FF3.6 */
background-size: contain, 0 0;
/* Скрываем текст */
overflow: hidden;
text-indent: -9999px;
font-size: 0;
color: rgba(255,255,255,0);
/* Устанавливаем размеры логотипа */
display: block;
height: 83px;
width: 300px;
}
Ваше мнение на счет вот такого метода:
.selector { background: url(../path_to_png/apple.png) no-repeat; }
html.svg .selector { background-image: url(../path_to_svg/apple.svg); }?
Я так понимаю, что данный метод (html.svg .selector) используется в фреймворках типа Modernizr?
В данном варианте если вручную проставить тегу html класс svg, то всем браузерам будет назначаться вторая строка кода, в том числе и тем, которые не понимают SVG. Но если используется фреймворк типа Modernizr, то он сам определяет, поддерживает браузер SVG или нет и добавляет, если надо тегу html класс svg. Всё бы хорошо, но:
1) Много лишнего кода подключается, следовательно, увеличивается время загрузки + лишняя нагрузка на браузер пользователя (хотя всем на это наплевать)
2) Если отключены скрипты у пользователя, то пользователь не увидит SVG.
В общем, другими словами — мой пример использует штатные средства и CSS возможности браузера. Твой вариант, Александр, использует JS и лишние фреймворки.
Запустил адаптивный сайт, планирую сделать его также готовым к просмотру с Retina-дисплеев. Работать с .svg буду впервые. Часть изображений, составляющих интерфейс, подготовил в этом формате, точнее, иконки и прочие «плюшки» уже были готовые. Есть ли возможность переконвертировать .png в .svg (часть только в первом формате)? Пытался — получается просто белое полотно. Скорее всего, я делаю что-то неправильно.
Буду делать так, как Вы описали.
Можно ли .svg объединить в спрайт?
Чтобы не возникало таких вопросов — стоит начать с основ и ознакомиться с самими форматами подробнее (PNG и SVG)
Также стоит понять, чем отличается растр от вектора
Конечно, ни чем не отличается принцип от растрового спрайта. Только вот кроссбраузерно замучаешься прописывать стили. В общем очень сложно будет, возможно стоит подумать об отказе поддержки старых браузеров.
Думаю, лучше будет методика определения плотности экрана посредством запросов @media. Изначально загружается .png, при значении, соответствующем параметрам retina — svg. Вот только во многих статьях описывается использование увеличенного в два раза .png. Реализовать вставку svg возможно же?
Хотя Ваш метод подразумевает использование png в случае неподдержки svg. Его использование не приведет к отказу от поддержки старых браузеров? Правильно? Ослы ниже 9-ой версии будут кушать png…
Да.
По сути, если подключать «ретинаPNG» или SVG через @media, то вариант весьма действенный. Шансов «промахнуться» почти нет, ибо браузеры на системах с ретина дисплеями с 99% вероятностью поддерживают SVG.
Да.
Изготовил в программе iDraw изображения svg, загрузил на сайт — все работает, за исключением того, что в Opera и Mozilla Firefox не отображается корректно шрифт: использовал ‘Sensation’ в логотипе, вставляет обычный ‘Arial’. Лучше, наверное, скачать Illustrator (что и делаю)?
Скачал иконки, они идут сплошным полотном, каким образом их оттуда можно взять по отдельности?
Спасибо!
Не системные шрифты необходимо преобразовывать в кривые.
К сожалению карт ТАРО нету под рукой, но могу предположить, что они или сгруппированы, или вообще растром.
Кстати, сделал все так, как Вы описали. Стал проверять в Opera версии 12.15 подгружается .png.
Александр, проверил сейчас свою демонстрацию на Opera 12.10 и Opera 12.15 — подгружается SVG. Покажи ссылку, посмотрим что у тебя не так.
Снова я!
Хотел поблагодарить Вас за этот метод!
Теперь только его и использую. Отлично, все работает, как часы!
Большое Вам спасибо!
Сегодня обнаружил, что методика не работает в IE8.
Спасибо! Исправлено.
SVG, заданный через фон, не может управляться внешними стилями. К нему нельзя применять CSS-анимацию, транзишины в отличии от встроенного SVG на страницу. Попробуйте, например, сделать плавное изменение цвета с помощью фона — http://jsfiddle.net/b4zTN/
С SVGZ нет ни каких проблем. Просто нужно что бы сервер отдавал правильные заголовки на клиента.
Можно добавить в .htaccess следующие строки и все будет ок.
# SVG и корректная работа сжатого SVG
AddType image/svg+xml svg svgz
AddEncoding gzip svgz
Григорий, я об этом писал в статье «SVG на собственной шкуре. Часть 1 — создание SVG файла в CorelDraw» и даже ссылку специально оставил. Там описывается данная проблема и другие, а также данное решение.
Однако проблема может всё равно появится:
1) если сервер/хостинг неправильно настроен и отдает неверные заголовки
2) если на хостинге не предоставляется доступ к .htaccess и туда не добавишь описание файлов и их заголовков.
3) если хостер или пользователь хостинга что-нибудь начудил и данные записи перестают работать
Именно третий пункт у меня однажды случился. Хостер хотел как лучше и добавил в мои .htaccess защиту админки Вордпресса паролем (.htpasswd), когда была волна взломов (брута) Вордпресса и Жумлы. В конец файла были добавлены строки, а отбивки (последней пустой строки) не было и они не учли добавление отбивки в своём скрипте, который обходил папки на поиск и внедрение защиты. В итоге получилось, что в конце моей последней строки, в которой описывались как раз заголовки, появилась их защита. И как следствие ни заголовки, ни их защита в данном случае не сработали. Разумеется я им отписал, как узнал об этом. Но прошло достаточно много времени.
Это мой реальный пример. И подобное может произойти с каждым. Поэтому я и предупредил в статье о возможных проблемах. Предупреждён — значит вооружен.