Сподіваюся, ні для кого вже не секрет, що оформительскую графіку на сайтах давно пора переводити в формат SVG з растровим фолбеком (при необхідності). Хто зрозумів це раніше, ніж екрани з ретиной, готові посперечатися за якістю картинки з поліграфією, з'явилися на 4-му айфоне, новому Айпад, а тепер і на новому макбуки - той великий молодець. Але якщо хтось досі не в курсі, у мене спеціально для вас є комікс SVG vs PNG .
На відміну від складних методів, на зразок -webkit-image-set, для яких потрібно вказувати кілька джерел картинки в залежності від дозволу, у випадку з SVG потрібна всього одна векторна картинка для всіх випадків:
E {background: url (image.png) no-repeat; background: rgba (0, 0, 0, 0) url (image.svg) no-repeat; }
Здивовані, навіщо перед другою декларацією стоїть прозорий чорний колір? Браузери, які не розуміють SVG і про які поки доводиться дбати, в нашому випадку це всіма улюблені IE6, IE7 та IE8, крім іншого, не підтримують колірну модель rgba (...) в CSS, тому декларація для них виявиться невалидность і буде відкинута. На жаль, це не спрацює в Firefox 3.6 і в старих браузерах на движку Webkit, які стоять на системах на кшталт Android 2.2 (як на моєму HTC Desire), тому для них буде доречніше використовувати визначення поддержікі SVG за допомогою Modernizr . Тоді вам доведеться написати щось на кшталт:
E {background: url (image.png) no-repeat; } .Inlinesvg E {background: url (image.svg) no-repeat; }
Оскільки в Firefox 3.6 є базова підтримка SVG (через елемент <object>), але немає підтримки SVG в для фонових зображень в CSS, то визначати підтримку потрібно буде не через клас .svg, а через .inlinesvg, який з'явився в Firefox 4.0 разом з підтримкою векторних фонових картинок.
Далі ми просто експортуємо SVG-картинку з улюбленого векторного редактора, чистимо від сміття, розставляємо відсутні параметри, вставляємо в CSS фоном. Але диявол, як відомо, в дрібницях, і навіть просту кнопку з векторної іконкою можна зробити п'ятьма різними способами. Тому давайте пройдемо крок за кроком процес створення кнопки, вирішуючи різні проблеми, що виникають по дорозі, і навіть просто вигадуючи собі нові.
Якщо ви не дуже добре знайомі з SVG, то перш ніж читати далі, ви можете відволіктися на мою доповідь « Веб в кривих. Друге народження SVG »Або хоча б перегорнути презентацію до нього і подивитися приклади.
Найпростіша кнопка
Проста кнопка, збільшена приблизно в 10 разів для наочності
Давайте почнемо з найпростішої кнопки «Play», яка згідно первісної дизайнерської ідеї є чорний трикутник, який повинен бути вписаний в білий квадрат розміром 25 × 25 пікселів. Любителі CSS-графіки тут же спробують зробити її за допомогою кінських розмірів рамок, діагоналі яких нормально згладжуються лише при кутах, кратних 45 °, а ми з вами поки продовжимо.
Починати завжди стоїть з HTML, і ми візьмемо для нашої кнопки елемент «кнопка», що може бути логічніше! Передбачимо відразу абстрактну кнопку .button і її підвид .play.
<Button class = "button play"> Play </ button>
І додамо простий CSS:
.button {display: inline-block; padding: 0; width: 25px; height: 25px; border: none; background: # 000 no-repeat; text-indent: -9999px; } .Button.play {background-image: url (images / play-button.png); background-image: rgba (0, 0, 0, 0) url (images / play-button.svg); }
Якщо ми збираємося робити векторну графіку, зрозуміло, що без вектор початкових кодів нам не обійтися. Насамперед хочеться вчинити з цим трикутником так само, як ми раніше надходили з растровою графікою: просто зберегти його як SVG і поставити фоном. Але в нашому випадку фігура настільки проста, що замість експорту її буде простіше написати руками. Заодно ми зможемо зрозуміти, як працює SVG, і нам не доведеться чистити експорт від сміття. Візьмемо шаблон мінімального SVG-файлу і вставимо в нього елемент <polygon> з трьома крапками, відповідними вершин нашого трикутника. Координати точок в Illustrator можна підглянути, навівши курсор на кожну з них. Пари координат через кому розділяються пробілами: x1, y1 x2, y2.
<Svg xmlns = "http://www.w3.org/2000/svg" width = "8" height = "9"> <polygon fill = "# 000" points = "0,0 8,4.5 0,9 "/> </ svg>
Якщо ми поставимо розміри SVG-елементу за допомогою атрибутів width і height, іконка буде вести себе як растрова і завжди буде зазначених розмірів, куди б ми її не встаючи. Це цілком нормально і виконує нашу задачу по отрисовке чіткої графіки для дисплеїв з високою роздільною здатністю. Але вказівка явних розмірів позбавляє нас одного з переваг формату - можливості подстаіваться під розміри об'єкта, фоном до якого він вказаний.
Тому давайте замість розмірів вкажемо нашої іконці атрибут viewBox (саме з великої «B», інакше не спрацює) зі значенням 0 0 8 9, де 8 і 9 - це ширина і висота нашої іконки в пікселях. Детальніше про viewBox і інші його параметри читайте в специфікації SVG .
<Svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 Народився 8 9"> <polygon fill = "# 000" points = "0,0 8,4.5 0,9" / > </ svg>
А тепер відкрийте по черзі два файли play-fixed.svg і play-viewbox.svg в нових вкладках і порівняйте результат. При зазначених розмірах SVG зберігає їх, а з зазначеним viewBox намагається вписатися в розміри вікна або елемента, зберігаючи пропорції. Тому якщо ми захочемо зробити ще одну кнопку не 25 × 25, а 100 × 100 пікселів, то нам не доведеться створювати нову іконку для неї.
Але в нашому випадку потрібно не просто вписати трикутник в усі 25 × 25 пікселів кнопки, а зберегти пропорції відступів і розташування трикутника. Тому давайте зробимо нашу картинку відразу потрібних розмірів і спозіціоніруем іконку рівно так, як на макеті з додатковим зміщенням для координат. У підсумку вийде файл play-button.svg .
<Svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 25 25"> <polygon fill = "# 000" points = "9,8 17,12.5 9,17" / > </ svg>
Але це занадто просто. Зробимо щось цікавіше.
Кнопка без тіні - гроші на вітер
Непроста кнопка з синьою заливкою і внутрішньої тінню
І тут до нас забігає дизайнер чорного трикутника (і великий шанувальник Малевича, мабуть) і каже, що зовсім забув про активний стан кнопки. Під час відтворення вона повинна горіти блакитним кольором і виглядати втиснула. Поміняти колір заливки нашої картинки тепер просто як ніколи, адже ми самі писали цей трикутник і знаємо, як там все влаштовано. А ось внутрішню тінь дизайнер намалював за допомогою одного з сотні спецефектів в Photoshop або Illustrator. І ми могли б скомбінувати десяток SVG-фільтрів і спробувати зробити справжню тінь, але це стає занадто складним завданням, і з кросбраузерністю у фільтрів не завжди добре.
Градієнти для імітації внутрішньої тіні
Тому ми спробуємо імітувати цю тінь за допомогою двох градієнтів. Один ми пустимо по верхній межі нашого трикутника, інший по лівій, трохи повернемо кожен з них і доб'ємося розмиванням потрібного ефекту. Для того щоб градієнти правильно наклалися в одну тінь поверх фонового кольору, вони повинні починатися в 100% прозорості і виходити в нульову. Градієнти в SVG з'явилися набагато раніше, ніж в CSS, і мають свій особливий синтаксис, трохи відрізняється від того, до чого ми звикли.
Сам градієнт, як і інша метаінформація, задається в спеціальній секції <defs> і описується елементом <linearGradient>, який можна повернути за допомогою атрибута gradientTransform. Кожен колір, його зміщення і прозорість описуються у вкладеному елементі <stop ».
<LinearGradient x1 = "0" y1 = "0" x2 = "0" y2 = "100%" id = "shadow-left" gradientTransform = "rotate (-75 0.5,0.5)"> <stop stop-color = " # 0020FF "offset =" 0 "/> <stop stop-color =" # 1ABEF1 "stop-opacity =" 0 "offset =" 40% "/> </ linearGradient>
Ми з вами опинилися біса завбачливі і задали кожному з двох градієнтів ID shadow-left і shadow-top, і тепер зможемо викликати їх за допомогою атрибута fill = "url (# shadow-left)" і значенням ID в якості параметра. Але для того, щоб цей трюк спрацював, нам потрібно буде додати до кореневого елементу <svg> ще один атрибут xmlns: xlink, що описує простір імен xlink.
Мені так і не вдалося застосувати кілька градієнтів до одного елементу одночасно з заливкою, і, здається, це просто неможливо. Тому доведеться продублювати наш трикутник тричі: спочатку із суцільною заливкою, потім з лівим і з верху градієнтом. Ті елементи, що підуть останніми, виявляться вищими, як і в HTML.
<Svg xmlns = "http://www.w3.org/2000/svg" xmlns: xlink = "http://www.w3.org/1999/xlink" viewBox = "0 0 25 25"> <defs> <! - Опис градієнтів -> </ defs> <polygon points = "9,8 17,12.5 9,17" fill = "# 1ABEF1" /> <polygon points = "9,8 17,12.5 9,17 "fill =" url (# shadow-left) "/> <polygon points =" 9,8 17,12.5 9,17 "fill =" url (# shadow-top) "/> </ svg>
Можна було б звичайно створити символ трикутника, а потім застосувати його знову за допомогою елемента <use>, але у цього способу погано з кросбраузерністю в Webkit. Отже, наш супер-трикутник з градієнтами, що складаються в тінь: play-active.svg .
Якщо поєднати картинку з нашої кнопкою і додати активний стан за допомогою класу .active, то вийде ось така краса: play-plain.html . У цьому прикладі, в силу очевидності, спеціально немає реєстрового фолбека, а кнопки спеціально збільшені в 10 разів, щоб можна було розглянути, наскільки прекрасна векторна графіка.
Звичайна і активна кнопки і їх збільшені варіанти
Маски шоу
Наша красива кнопка готова, але не знаю, як вам, а мені все мало і хочеться більше чудес. Було б добре не бігати в SVG, налаштовуючи всі параметри кнопки, а робити все прямо в CSS. І навіть більше - хочеться мати одну форму трикутника в SVG, а все його подробиці малювати в CSS, включаючи стану по наведенню і навіть плавні переходи. Дуже нагадує маску, чи не так?
принцип псевдомаскі
Як ви пам'ятаєте, повноцінних кросбраузерності масок в CSS немає. На жаль, поки немає навіть специфікації, в якій вони були б описані. Маски вже давно є в SVG, але в нашому випадку це не допоможе.
Допоможе нам старий добрий трюк, допустимий тільки для однорідного та постійного фону під об'єктом. Припустимо, що наша кнопка завжди буде на білому тлі або нам не лінь намалювати маски для кількох інших фонів. Ми намалюємо SVG-картинку, залиту суцільним кольором і зробимо в ній дірку якраз тієї форми, що і наш трикутник. А все інше оформлення будемо малювати в CSS.
І якщо наш простий трикутник складався з трьох точок, то маску з двома контурами потрібно буде малювати вже за допомогою кривих Безьє, прямо в редакторі. Насправді, все просто. Ми беремо квадрат 25 × 25, кладемо на нього трикутник і віднімаємо форми, пробиваючи в прямокутнику дірку потрібного виду, будь векторний редактор це вміє.
Але в використанні таких масок є невеликий нюанс. На жаль, браузери досі не надто точно розраховують розміри і розташування фону при масштабуванні об'єктів, особливо це помітно на мобільних пристроях, як з растровою, так і з векторною графікою. Вирішити цю проблему можна, додавши додатково один або кілька пікселів фонової заливки з кожної зі сторін. У випадку з SVG ці додаткові пікселі можуть лежати за межами видимої області і все одно будуть нам допомагати.
Тому розміри нашої маски будуть на 3 пікселі більше з кожного боку, при тому ж viewBox 25 × 25 пікселів. Почитати, як формується крива Безьє в атрибуті d для елемента <path>, можна у Ярослава Карандашева . А ми просто експортували її з векторного редактора.
<Svg xmlns = "http://www.w3.org/2000/svg" viewBox = "0 0 25 25"> <path fill = "# FFF" d = "m-3-3v31h31v-31h-31zm12 20v- 9l8 4.5-8 4.5z "/> </ svg>
Після того, як маска створена, нам потрібно перенести градієнт в CSS. На жаль, зробити це навіть простим копіюванням значень не вийде. Адже в CSS поки інша система повороту градієнтів і у нас дещо інша ситуація. Якщо для трикутника ми малювали градієнт прямо в межах його контуру, то маска буде приховувати градієнт, намальований в межах всієї кнопки. Тому градієнт ми пишемо заново.
Основний колір активної кнопки ми вкажемо в background-color, а в background-image перерахуємо через кому маску і два градієнта. Тут все навпаки - хто перший, той і вище.
.button.play.active {background-color: # 1ABEF1; background-image: url (images / play-mask.svg), linear-gradient (105deg, # 0020FF 38%, rgba (26, 190, 241, 0) 49%), linear-gradient (200deg, # 0020FF 41% , rgba (26, 190, 241, 0) 52%); }
Всі необхідні префікси для роботи градієнтів (-webkit, -moz і -o) перераховані в підсумковому файлі. Але це не єдина різниця: градієнти з префіксами повинні отримати ще й інші значення градусів. Справа в тому, що з моменту впровадження градієнтів в браузерах, специфікація змінилася і якщо раніше значення відлічувалися від трьох годин (уявіть циферблат годинника) і проти годинникової стрілки, як на уроках геометрії, то зараз відлік йде від полудня і за годинниковою стрілкою, що природніше для CSS в цілому. Значить по старому синтаксису повороти будуть -15deg і -110deg, а по новому, без префікса, 105deg і 200deg, відповідно.
У підсумку ми отримаємо ту ж саму розкішну кнопку, але все з одним SVG-файлом для маски і з оформленням прямо в CSS: play-mask.html . Ви можете спробувати модифікувати цей приклад і переконатися, наскільки зручно працювати з іконкою прямо в CSS. Всі приклади, використані в цій замітці, можна завантажити одним архівом: play.zip (17 КБ)
Сподобалася кнопка? Можна зробити краще? Не соромтеся, розкажіть в коментарях.
Дуже нагадує маску, чи не так?Можна зробити краще?