Pull to refresh
0
Rating

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

PAYSTO corporate blog CSS *
Translation
Original author: Lynn Fisher
Почему 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: 170px 0 10px yellow,
                330px 0 0 -20px blue,
                330px 5px 5px -20px 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 :  2px  2px  3px  black (.3), 
}


Затем я добавила линейный градиент на обоих концах, чтобы создать обертку. Он имеет значение альфа-0,6, так что нижняя заливка немного проглядывает.

image


div { 
    background-image : linear-gradient (to right, 
                                  transparent  12px, 
                                  rgba (41, 237, 133, .6)  12px, 
                                  rgba (41, 237, 133, .6)  235px, 
                                  transparent  235px), 
}


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

image


div { 
    background-image : linear-gradient (to right, 
                                  transparent  25px, 
                                  black (.6)  25px, 
                                  black (.6)  30px, 
                                  transparent  30px, 
                                  transparent  35px, 
                                  black (.6)  35px, 
                                  black (.6)  40px, 
                                  transparent  40px, 
                                  transparent  210px, 
                                  black (.6)  210px, 
                                  black (.6)  215px, 
                                  transparent  215px, 
                                  transparent  220px, 
                                  black (.6)  220px, 
                                  black (.6)  225px, 
                                  transparent  225px), 
}

А для нанесения эллипса прекрасно работает радиальный градиент!

image

div {
    background-image: radial-gradient(ellipse at top,
                                  black(.6) 50px,
                                  transparent 54px);
}


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



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

image


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


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

image


div :after { 
    background-image : linear-gradient (to bottom, 
                                    white (0)  12px, 
                                    white (.2)  17px, 
                                    white (.2)  19px, 
                                    white (0)  24px), 
}



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

image


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



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

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

image


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

image


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



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

image


div :after { 
    background : linear-gradient (45deg,  #ccc  40%,  #ddd  100%), 
    border-radius :  50%, 
    box-shadow :  0  3px  2px  #999, 
                1px  -2px  0  white, 
                -1px  -3px  2px  #555, 
                0  0  0  15px  #c2c2c2, 
                0  -2px  0  15px  white, 
                -2px  -5px  1px  17px  #666, 
                0  10px  10px  15px  black (.3), 
 
                -90px  -51px  1px  -43px  #aaa, 
                -90px  -50px  1px  -40px  #888, 
                -90px  -51px  0  -34px  #ccc, 
                -90px  -50px  0  -30px  #aaa, 
                -90px  -48px  1px  -28px  black (.2), 
 
                -124px  -73px  1px  -48px  #eee, 
                -125px  -72px  0  -46px  #666, 
                -85px  -73px  1px  -48px  #eee, 
                -86px  -72px  0  -46px  #666, 
                42px  -82px  1px  -48px  #eee, 
                41px  -81px  0  -46px  #777, 
                67px  -73px  1px  -48px  #eee, 
                66px  -72px  0  -46px  #666, 
 
                -46px  -86px  1px  -45px  #444, 
                -44px  -87px  0  -38px  #333, 
                -44px  -86px  0  -37px  #ccc, 
                -44px  -85px  0  -34px  #999, 
 
                14px  -89px  1px  -48px  #eee, 
                12px  -84px  1px  -48px  #999, 
                23px  -85px  0  -47px  #444, 
                23px  -87px  0  -46px  #888, 
}


Немного сложно, но, как вы видите, несколько box-shadows могут добавить много деталей к одному элементу.

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

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

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

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

image


 div { 
    border-left :  80px  solid  transparent, 
    border-right :  80px  solid  transparent, 
    border-bottom :  80px  solid  red, 
}
  
div :before { 
    border-left :  80px  solid  transparent, 
    border-right :  80px  solid  transparent, 
    border-bottom :  80px  solid  red, 
    border-image : linear-gradient (to right,  red,  blue), 
}
  
div :after { 
    border-left :  80px  solid  transparent, 
    border-right :  80px  solid  transparent, 
    border-bottom :  80px  solid  red, 
    box-shadow :  5px  5px  5px  gray, 
}


Расслоение градиента

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

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

image


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

image


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

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

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

Tags:
Hubs:
Total votes 74: ↑71 and ↓3 +68
Views 48K
Comments Comments 23

Information

Founded
Location
Россия
Website
www.paysto.ru
Employees
11–30 employees
Registered