[Перевод] Магия одного div. Мастеркласс от создателя a.singlediv.com

Почему Single Div? В мае 2013 года я присутствовал на CSSConf и услышал, как Ли Верой говорит об укрощении свойства border-radius. Это было поучительно и позволило мне понять о CSS то, чего я раньше не понимал. Это напомнило мне времена, когда я изучал изящные искусства, когда я постоянно стремился повысить свой профессиональный уровень. Мой уровень владения CSS можно назвать средним, поэтому я бросил себе вызов, чтобы узнать все, что я смогу, исследуя и экспериментируя со свойствами

Но почему именно один DIV?

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

Я решил запустить проект a.singlediv.com, где намеревался каждые несколько дней размещать нечто новенькое, созданное с помощью CSS. Я поставил перед собой ограничение использовать только один DIV.Инструментарий

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

Псевдо-элементы

Один DIV в HTML позволяет работать с тремя элементами, благодаря использованию псевдо-элементов. Таким образом, с div, div: before, and div: after, мы можем получить что-то вроде этого:

image div { background: red; } div: before { background: yellow; } div: after { background: blue; } Для упрощения вы можете думать об этих элемента, как о трех слоях. Выглядит это примерно так:

image Формы

С помощью CSS и одного элемента мы получили три основных формы. Мы можем использовать свойства width и height для создания квадратов / прямоугольников, а также border-radius, чтобы создать круги/эллипсы, и border для создания треугольников/трапеций.

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

Множественность формы

С несколькими box-shadows мы можем создать множество версий одной и той же формы, в том или ином размере, цвете, или использовать размытие. Использование осей х и у дает нам почти бесконечные вариации.

image div { box-shadow: 170 px 0 10 px yellow, 330 px 0 0 -20 px blue, 330 px 5 px 5 px -20 px black; } Мы можем использовать box-shadows для box-shadows. Обратите внимание на порядок объявления. Здесь также уместен образ слоев.

Градиенты

Градиенты могут быть использованы, чтобы добавить затенение и глубину, подразумевая источник света. Это делает простые, плоские формы более реалистичными. Свойство background-images позволяет использовать несколько видов градиента для получения более сложного элемента.

image div { background-image: linear-gradient (to right, gray, white, gray, black), } div: after { background-image: radial-gradient (circle, yellow 50%, transparent 50%), linear-gradient (to right, blue, red), } Визуализация

Самой трудной частью является визуализация того, как собрать все эти части в единое целое, в узнаваемый рисунок. Эта часть процесса имеет решающее значение. Чтобы помочь себе в этом, я часто смотрю на фотографию предмета, и мысленно разделяю его на составляющие, все формы и все цвета. Я разбиваю общую картину на более мелкие формы или цветовые блоки, которые я смогу создать с помощью CSS.

Пример

Давайте внимательнее посмотрим на два рисунка и выделим некоторые части, которые составляют большие объекты.

Для начала возьмем зеленый карандаш:

Карандаш состоит из двух основных форм: прямоугольный корпус и треугольный наконечник.

image Я должен был реализовать следующие вещи, чтобы добиться реалистичности:

разноцветная обертка; графика и слова на обертке; иллюзия округлости; глянцевость, которая подчеркивает форму и имитирует влияние источника освещения.

Итак, сначала я создал основной корпус карандаша:

image Обратите внимание, я использую смешение black (a) и white (a) вместо RGBA

div { background: #237449, background-image: linear-gradient (to bottom, transparent 62%, black (.3) 100%), box-shadow: 2 px 2 px 3 px black (.3), } Затем я добавил линейный градиент на обоих концах, чтобы создать обертку. Он имеет значение альфа-0,6, так что нижняя заливка немного проглядывает.

image div { background-image: linear-gradient (to right, transparent 12 px, rgba (41, 237, 133, .6) 12 px, rgba (41, 237, 133, .6) 235 px, transparent 235 px), } Далее я использовал ту же технику градиента, чтобы создать полосы на карандаше.

image div { background-image: linear-gradient (to right, transparent 25 px, black (.6) 25 px, black (.6) 30 px, transparent 30 px, transparent 35 px, black (.6) 35 px, black (.6) 40 px, transparent 40 px, transparent 210 px, black (.6) 210 px, black (.6) 215 px, transparent 215 px, transparent 220 px, black (.6) 220 px, black (.6) 225 px, transparent 225 px), } А для нанесения эллипса прекрасно работает радиальный градиент! image div { background-image: radial-gradient (ellipse at top, black (.6) 50 px, transparent 54 px); } Я разделил код, чтобы продемонстрировать каждый элемент, но имейте в виду: изображение будет на самом деле выглядеть следующим образом:

div { // эллипс background-image: radial-gradient (ellipse at top, black (.6) 50 px, transparent 54 px), // полосы linear-gradient (to right, transparent 25 px, black (.6) 25 px, black (.6) 30 px, transparent 30 px, transparent 35 px, black (.6) 35 px, black (.6) 40 px, transparent 40 px, transparent 210 px, black (.6) 210 px, black (.6) 215 px, transparent 215 px, transparent 220 px, black (.6) 220 px, black (.6) 225 px, transparent 225 px), // обертка linear-gradient (to right, transparent 12 px, rgba (41,237,133,.6) 12 px, rgba (41,237,133,.6) 235 px, transparent 235 px), // оттенение linear-gradient (to bottom, transparent 62%, black (.3) 100%) }

Таким образом, после завершения div, я использовал псевдо-элемент before для создания трехстороннего наконечника. Используя свойства solid и transparent, я создал треугольник и разместил его рядом с div

image div: before { height: 10 px, border-right: 48 px solid #237449, border-bottom: 13 px solid transparent, border-top: 13 px solid transparent, }

Это выглядит немного плоско, но это будет исправлено посредством псевдо-элемента after. При этом я добавил линейный градиент, чтобы создать эффект блеска, который охватывает всю ширину карандаша.image div: after { background-image: linear-gradient (to bottom, white (0) 12 px, white (.2) 17 px, white (.2) 19 px, white (0) 24 px), }

Как последний штрих, я добавил текст с помощью after, и разместил его на карандаше:

image div: after { content: 'green', font-family: Arial, sans-serif, font-size: 12 px, font-weight: bold, color: black (.3), text-align: right, padding-right: 47 px, padding-top: 17 px, }

Еще один пример (фотоаппарат):

Вот корпус камеры, созданный с помощью background-image и border-image.

image Вот GIF, иллюстрирующая некоторые элементы, которые будут добавлены с помощью псевдо-элементов и box-shadows.

image div: before { background: #333, box-shadow: 0 0 0 2 px #eee, -1 px -1 px 1 px 3 px #333, -95 px 6 px 0 0 #ccc, 30 px 3 px 0 12 px #ccc, -18 px 37 px 0 46 px #ccc, -96 px -6 px 0 -6 px #555, -96 px -9 px 0 -6 px #ddd, -155 px -10 px 1 px 3 px #888, -165 px -10 px 1 px 3 px #999, -170 px -10 px 1 px 3 px #666, -162 px -8 px 0 5 px #555, 85 px -4 px 1 px -3 px #ccc, 79 px -4 px 1 px -3 px #888, 82 px 1 px 0 -4 px #555, }

Следующий этап:

image div: after { background: linear-gradient (45deg, #ccc 40%, #ddd 100%), border-radius: 50%, box-shadow: 0 3 px 2 px #999, 1 px -2 px 0 white, -1 px -3 px 2 px #555, 0 0 0 15 px #c2c2c2, 0 -2 px 0 15 px white, -2 px -5 px 1 px 17 px #666, 0 10 px 10 px 15 px black (.3), -90 px -51 px 1 px -43 px #aaa, -90 px -50 px 1 px -40 px #888, -90 px -51 px 0 -34 px #ccc, -90 px -50 px 0 -30 px #aaa, -90 px -48 px 1 px -28 px black (.2), -124 px -73 px 1 px -48 px #eee, -125 px -72 px 0 -46 px #666, -85 px -73 px 1 px -48 px #eee, -86 px -72 px 0 -46 px #666, 42 px -82 px 1 px -48 px #eee, 41 px -81 px 0 -46 px #777, 67 px -73 px 1 px -48 px #eee, 66 px -72 px 0 -46 px #666, -46 px -86 px 1 px -45 px #444, -44 px -87 px 0 -38 px #333, -44 px -86 px 0 -37 px #ccc, -44 px -85 px 0 -34 px #999, 14 px -89 px 1 px -48 px #eee, 12 px -84 px 1 px -48 px #999, 23 px -85 px 0 -47 px #444, 23 px -87 px 0 -46 px #888, } Немного сложно, но, как вы видите, несколько box-shadows могут добавить много деталей к одному элементу.

Серьезные вызовы

Два самых больших препятствия, с которыми я столкнулся, — ограничения при создании треугольника и поведение градиентов.

Проблема с треугольниками

Методика создания треугольников ограничивает возможные действия. Добавление градиента с помощью border-image затрагивает все границы объекта, а не одну конкретную сторону. Box-shadows применяется к форме блока, а не к его границам. Все это затрудняет создание нескольких треугольников с помощью одного объекта. Вот пример, как это выглядит:

image div { border-left: 80 px solid transparent, border-right: 80 px solid transparent, border-bottom: 80 px solid red, } div: before { border-left: 80 px solid transparent, border-right: 80 px solid transparent, border-bottom: 80 px solid red, border-image: linear-gradient (to right, red, blue), } div: after { border-left: 80 px solid transparent, border-right: 80 px solid transparent, border-bottom: 80 px solid red, box-shadow: 5 px 5 px 5 px gray, } Расслоение градиента

Градиент стремится заполнить весь элемент. Это решается наложением нескольких градиентов друг на друга. Потребуется немного времени, чтобы обдумать прозрачность и Z-индекс, а также, чтобы понять, что именно будет видно, а что нет. Но эффективное использование этой техники позволит придать вашим рисункам высокий уровень детализации.

Вот рисунок в процессе создания, показывающий градиенты, которые охватывают всю ширину контейнера.

image Используя градиенты, направленные слева-направо и справа-налево, я могу скрыть часть градиента:

image В результате создается иллюзия того, что объект выполнен из множества элементов.

Теория в действии

Прекрасная вещь, которая стала побочным результатом этого проекта, — расширение для Сhrome, которое называется CSS Gradient Inspector. Оно позволяет включить и выключить отображение каждого из градиентов по аналогии с видимостью слоев в Photoshop.

© Habrahabr.ru