Написать пост

Знакомство с созданием изображений на чистом CSS. Часть первая. Для начинающих

Аватар Alexey Gorshkov

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

Обложка поста Знакомство с созданием изображений на чистом CSS. Часть первая. Для начинающих

Рассказывает Майкл Мэнгиаларди, фронтенд-разработчик и векторный иллюстратор

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

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

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

Изучение основ векторной графики знакомит вас с макетами, цветовыми паттернами, динамикой форм и в целом с творчеством, которое присутствует в работе фронтенд-разработчика.

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

Создание изображения на чистом CSS подразумевает, что вместо программного обеспечения для создания векторных иллюстраций (такого, как Inkscape, Illustrator, Affinity Designer или Sketch) вы напрямую работаете с CSS-кодом.

Несмотря на схожесть профессий, я думаю, что иллюстратору тонна CSS-кода, необходимого для создания изображения, может показаться устрашающей, впрочем, как и фронтенд разработчику — перспектива создания изображения с помощью кода.

По этой причине представляю вашему вниманию руководство по созданию вашего первого изображения на чистом CSS, которое, как я надеюсь:

  • повысит доверие к созданию картинок на чистом CSS;
  • поможет понять, как создаются изображения на чистом CSS;
  • если вы фронтенд-разработчик, то увеличит интерес к векторной графике;
  • если вы векторный иллюстратор, то увеличит интерес к фронтенд-разработке;
  • снабдит базовым шаблоном для создания изображений на чистом CSS.

Компоненты изображений на чистом CSS

Для начала разберёмся, что такое «чистый CSS».

Создание изображений на «чистом CSS» подразумевает добавление CSS-стилей нескольким HTML-тегам div.

К примеру, мы можем создать квадрат всего лишь одним div и применённым к нему стилем:

			body{
  background: #1D1F20;
}
.square{
  width: 100px;
  height: 100px;
  background: #A58CB6;
}
		

Мы будем создавать фигуры, стилизуя блоки, чтобы сформировать из них финальную картинку.

Каждый проект на чистом CSS будет состоять из следующих компонентов:

  • тег div для каждой фигуры;
  • определенный CSS-класс, присвоенный каждому div;
  • невидимый блок, который будет служить в качестве холста.

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

See the Pen Koala | Animals #1 by Mike Mangialardi (@mikemang) on CodePen.

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

Структура фигур

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

А пока просто имейте в виду, что нам предстоит иметь дело с невидимым прямоугольным полем, которое я выделил ниже:

Во-вторых, у нас есть круг в центре веб-страницы, на основе которого мы будем создавать голову.

Далее мы создадим уши, которые располагаются по бокам головы. Каждое ухо состоит из двух разноцветных кругов, которые накладываются друг на друга, один круг немного меньше другого. Мы будем проводить различие между div уха и div «внутреннего уха».

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

Далее мы создадим нос в виде коричневого прямоугольника с закруглёнными углами, и расположим его под глазами.

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

Еще одна важная вещь, о которой стоит упомянуть — это то, что для создания изображения мы также будем использовать разные слои. Уши будут позади головы, нос — перед глазами и т.д. Это станет понятнее, когда мы перейдем к работе с CSS.

HTML

Примечание: чтобы добавить нашей коале волосы, мы будем использовать метод clip-path. Он поддерживается в Chrome, Safari и Opera. Если вы пользуетесь Firefox, советую сменить его на другой браузер на время изучения этого руководства.

Как правило, я добавляю один div, который будет фигурой, затем я стилизую её, а после приступаю к следующему div.

Однако, поскольку это инструкция, давайте сначала взглянем на HTML-код и разберем его:

			<body>
<!-- Начало изображения -->
<!-- Невидимое поле -->
<div class="box">

<!-- Круглая голова -->
<div class="head">

<!-- Круглая копия головы -->
<div class="head-copy"></div>

<!-- Левое ухо ~ светло-серое -->
<div class="ear-left">

<!-- Внутреннее ухо ~ тёмно-серое -->
<div class="inner-ear"></div>
</div>

<!-- Правое ухо ~ светло-серое -->
<div class="ear-right">
<!-- Внутреннее ухо ~ Тёмно-серое -->
<div class="inner-ear"></div>
</div>

<!-- Левый глаз ~ белый -->
<div class="eye-left">
<!-- Зрачок ~ чёрный -->
<div class="pupil">
</div>
</div>

<!-- Правый глаз ~ белый -->
<div class="eye-right">
<!-- Зрачок ~ чёрный -->
<div class="pupil">
</div>
</div>

<!-- Нос ~ коричневый -->
<div class="nose">
</div>

<!-- Волосы ~ светло-серые -->
<div class="hair-left"></div>
<div class="hair-right"></div>

<!-- Конец головы -->
</div>
<!-- Конец невидимого поля -->
</div>
</body>
		

Важно заметить, что некоторые div вложены в другие. Давайте посмотрим на div правого уха нашей коалы:

			<!-- Правое ухо ~ светло-серое -->
<div class="ear-right">
<!-- Внутреннее ухо ~ тёмно-серое -->
<div class="inner-ear"></div>
</div>
		

«Ear-right» (правое ухо) является родительским div, а «inner-ear» (внутреннее ухо) — дочерним.

Это различие важно, потому что фигурам будут заданы фиксированные положение, ширина и высота, выраженные в процентах.

Например, представим, что у нас есть div, вложенный в body с height: 100% и width: 100%:

Классу some-div назначается фиксированная позиция, которая на 10% ниже верхней части родительского блока. Так как some-div встроен в body, который имеет 100% ширины и 100% высоты, div будет расположен на 10% ниже верхней части этого блока.

Теперь вложим другой div в some-div и зададим ему такой же стиль:

Как вы можете видеть, мы получим совершенно другое расположение.

В этом примере another-div (синий квадрат) на 10% ниже, чем some-div (красный квадрат).

Теперь переместим another-div из some-div в body и увеличим отступ до 30%:

another-div теперь отступает на 30% от верха body, а не some-div.

Имея это в виду, перейдем к стилям CSS.

CSS стили

body

Для начала зададим body фоновый цвет. Пусть это будет оттенок синего, как у Твиттера:

			body{
  background: #25A9FC;
}
		

box

Теперь добавим стили невидимому блоку. Он будет отцентрирован по горизонтали (чтобы следить за изменением положения поля, добавьте ему фон или рамку):

			.box{
  position: relative;
  margin: auto;
  display: block;

  // опциональные фон и рамка

  background: white;
  border: solid 4px red;

  // пишите код здесь
}
		

position: relative означает, что элемент позиционируется относительно своего нормального положения, которое находится в верхнем левом углу, так как это первый div в body.

Когда свойство position установлено в relative, используйте display: block; и margin: auto;, чтобы автоматически отцентрировать поле по горизонтали.

Затем мы можем добавить следующую часть кода, чтобы поместить поле на 8% ниже, а также установить height и width с размерами, как на изображении выше, и, наконец, присвоить необходимое значение фона:

			.box{
  position: relative;
  margin: auto;
  display: block;
  margin-top: 8%;
  width: 600px;
  height: 420px;
  background: none;
}
		

Отметим, что мы используем свойство margin-top: 8%, чтобы опустить поле на 8%. Поскольку мы специально настраиваем top, это не отразится на наших предыдущих отступах, заданных через margin:auto.

Теперь, когда поле настроено, все наши остальные div будут вложены в него. Опять же, это важно, потому что когда мы будем назначать абсолютные положения в процентах, это расположит div на столько же процентов от поля, но не от body. Этот же принцип будет работать и с нашими высотой и шириной.

Голова

Посмотрим на код для создания головы, а затем разберем его шаг за шагом:

			.head{
  position: absolute;
  top: 16.5%;
  left: 25%;
  width: 50%;
  height: 67%;
  background: #A6BECF;
  border-radius: 50%;
}
		

Процентные показатели для top и left означают, что div будет в 15% от верхнего края поля и в 25% — от левого. Ширина div — 50% от ширины поля, а высота — 67% от высоты поля. После этого мы устанавливаем светло-серый цвет фона.

Далее мы используем border-radius: 50%. Если вы пропустите это свойство, голова всегда будет в форме прямоугольника (или квадрата). border-radius является тем свойством, которое меняет фигуру. Если вы знакомы с Illustrator, то можете сравнить добавление свойства border-radius с тем, как в нём нужно потянуть за края квадрата, чтобы закруглить его. Чтобы округлить форму до круга, мы всегда используем показатель, равный 50%.

border-radius можно использовать не только для создания круга, но и для того, чтобы закруглить любую фигуру, например, прямоугольник для носа нашей коалы.

Прежде чем мы пойдем дальше, я объясню, откуда я взял процентные показатели верхней и левой границ, ширины и высоты. Мы задали полю ширину в 600 пикселей, так что 50% дают нам 300 пикселей. Учитывая, что поле было высотой всего в 400 пикселей, процентный показатель для головы должен быть выше.

Скорее всего вы ждете, что я дам вам точную формулу для вычисления высоты. Честно говоря, обычно я нахожу нужное значение методом тыка.

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

Теперь, имея проценты позиций, вычислить абсолютный центр гораздо проще. Вот формула:

			left = (100 - width) / 2
top = (100 - height) / 2
// наш случай
(100 - 67)/2 = top: 16.5%;
(100-50)/2 = left: 25%;
		

Теперь этот фрагмент кода работает для div нашей головы, потому что мы хотим разместить её по центру. Однако мы, к примеру, не хотим помещать в самый центр уши. Мы скоро подойдем к этому моменту, и я также объясню, когда использовать bottom и right вместо top и left.

Последнее, о чём стоит сказать в этом разделе — каждый последующий div будет вложен в div головы, так как каждая фигура, которая будет добавлена, будет расположена поверх неё.

Вот что мы должны получить на данном этапе:

Копия головы

			.head-copy{
  width: 100%;
  height: 100%;
  position: absolute;
  background: #A6BECF;
  border-radius: 50%;
  z-index: 2;
}
		

Div копии головы делается исключительно для того, чтобы уши могли появиться за головой. Для этого используется свойство z-index. Обратите внимание на последнюю строку предыдущего фрагмента кода:

			z-index: 2;
		

z-index используется для обозначения уровня расположения div относительно других по оси, направленной перпендикулярно экрану (то есть на вас или от вас). С помощью этого свойства задаются слои.

В нашем финальном изображении глаза будут над головой, нос — над глазами и т.д. Всё это будет контролироваться с помощью z-index. Чем больше значение z-index, тем выше расположен div.

Так что если у вас два div, z-index: 1 будет вашим нижним слоем, а z-index: 2 — верхним. Когда мы добавляем копию головы, мы даём ей значение z-index: 2, значит, уши нашей коалы будут располагаться за головой.

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

Мы не должны увидеть каких-либо изменений . Изображение по-прежнему выглядит следующим образом:

Уши

Как говорилось ранее, у нас будет по одному уху, состоящему из кругов, для каждой стороны. Два светло-серых круга побольше и два темно-серых круга поменьше поверх каждого уха (назовём их внутренними ушами — inner-ear).

			.ear-left{
  position: absolute;
  width: 60%;
  height: 65%;
  left: -20%;
  top: 5%;
  background: #A6BECF;
  border-radius: 50%;
  z-index: 1;
}
.ear-right{
  position: absolute;
  width: 60%;
  height: 65%;
  right: -20%;
  top: 5%;
  background: #A6BECF;
  border-radius: 50%;
  z-index: 1;
}
.inner-ear{
  position: absolute;
  border-radius: 50%;
  width: 80%;
  height: 80%;
  top: 10%;
  left: 10%;
  background: #819CAF;
}
		

Для каждого класса мы используем border-radius:50%, так как нам нужны круги, а затем добавляем цвет, используя background.
Как вы видите, мы написали два разных стиля для ушей, но только один для внутреннего уха. Это станет очевидным, когда мы разберемся с позиционированием.

Родительским div для правого и левого уха является голова. Таким образом, процентные показатели будут рассчитываться относительно головы, так же как высота и ширина. Рассчитываем высоту и ширину, основываясь на том, что мы хотим большие уши, которые, однако, должны быть меньше головы. Таким образом, мы получаем width:60% и height:65%.

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

			left = (100 - width) / 2
top = (100 - height) / 2
// наш случай
(100 - 80)/2 = top: 10%;
(100-80)/2 = left: 10%;
		

Так как left и right рассчитываются относительно ушей, мы можем использовать один и тот же стиль для левого и правого уха, поэтому у нас всего один div внутреннего уха. Мы вынуждены использовать два раздельных div для ушей, потому что они будут иметь различные показатели left и right, т.к. они позиционируются относительно головы.

Мы хотим, чтобы уши торчали слева и справа от головы. Мы используем отрицательные значения left: -20% и right: -20% для сдвига в указанном направлении.

Вот что получилось в итоге:

			//левое ухо
  width: 60%;
  height: 65%;
  left: -20%;
  top: 5%;
//правое ухо
  width: 60%;
  height: 65%;
  right: -20%;
  top: 5%;
		

Напоследок мы добавляем z-index: 1; так что наши уши отправляются под голову. Вот что должно у нас получиться:

Глаза

			.eye-left{
  position: absolute;
  background: white;
  width: 30%;
  height: 33%;
  top: 25%;
  left: 21%;
  border-radius: 50%;
  z-index: 3;
}
.eye-right{
  position: absolute;
  background: white;
  width: 30%;
  height: 33%;
  top: 25%;
  right: 21%;
  border-radius: 50%;
  z-index: 2;
}
.pupil{
  position: absolute;
  width: 28%;
  height: 30%;
  top: 35%;
  left: 36%;
  border-radius: 50%;
  background: #27354A;
}
		

Как вы видите, глаза нашей коалы похожи на её уши. У нас есть два больших белых круга (левый и правый глаз) и один зрачок.

Для них мы используем border-radius:50%, так как они являются кругами, а также используем background,  чтобы задать соответствующий цвет.

У нас есть зрачок, который помещается в каждый глаз. Мы угадываем height и width зрачка, размещаем его по центру и получаем такой результат:

			width: 28%;
height: 30%;
top: 35%;
left: 36%;
		

Для определения отступов левого глаза вы также можете использовать метод проб и ошибок или вышеприведённую формулу. Между тем, показатели height и width мы просто угадываем, пока не найдем оптимальное значение.

			//левый глаз  
  width: 30%;
  height: 33%;
  top: 25%;
  left: 21%;
  
  //правый глаз
  width: 30%;
  height: 33%;
  top: 25%;
  right: 21%;
		

Что касается z-index, следующие значения позволят поместить нос прямо над глазами:

			//левый глаз 
 z-index: 3;
 //правый глаз
 z-index: 2;
		

В итоге у нас должна получиться вот такая картинка:

Нос

			.nose{
  position: absolute;
  background: #BE845F;
  width: 25%;
  height: 42.5%;
  left: 37%;
  top: 45%;
  border-radius: 50px;
  z-index: 4;
}
		

Теперь займемся носом. Все значения мы подбираем аналогично, вот оптимальные:

			width: 25%;
  height: 42.5%;
  left: 37%;
  top: 45%;
		

Мы задаем коричневый цвет для фона, используя  background, и глубину с помощью z-index:4, чтобы нос оказался над глазами.

Мы также используем border-radius: 50px, с помощью которого закругляем углы прямоугольника так, как нам нужно. Когда фигуру нужно закруглить совсем чуть-чуть, проще указывать количество пикселей, а не процентов.

Теперь у нас получается вот такое изображение:

Волосы

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

			.hair-left{
  position: absolute;
  top: -8%;
  left: 30%;
  width: 20%;
  height: 20%;
  background:  #A6BECF;
  -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
.hair-right{
  position: absolute;
  top: -4%;
  left: 48%;
  width: 20%;
  height: 20%;
  background:  #A6BECF;
  -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
		

Как видите, здесь мы не используем border-radius, но у нас есть вот такой код с clip-path:

			-webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
		

Для любой фигуры, кроме квадрата, треугольника и круга, проще использовать метод clip-path.

Это может казаться немного непонятным, но, к счастью, есть прекрасный инструмент Clippy, который выдаёт clip-path для различных фигур. Справа вы увидите множество различных фигур:

На изображении выше выбран треугольник, так что вы можете скопировать clip-path и вставить его в CSS-класс для волос.

Мы снова задаем цвет с помощью background и устанавливаем width и height в 20% для обоих пучков. Мы задаем левому пучку значение left: 30%, а правому — left: 48%. Это хороший пример для обсуждения, что использовать: right или left. Предположим, что мы хотим передвинуть правый пучок на 5% вправо. Мы можем добавить 5% к 48%, чтобы получить значение left:53%. Однако правилом хорошего тона считается переход с left на right и наоборот при значении выше 50%. Поэтому left: 53% будет эквивалентно right:47%.

Верхние сдвиги будут отрицательными, поскольку мы хотим, чтобы оба пучка волос торчали над головой. Левый пучок будет торчать чуть сильнее, так что мы задаем ему height: 8%, а правый пучок — чуть меньше, с показателем height: 4%.

Наша картинка коалы готова!

В итоге CSS-код должен выглядеть так:

			body{
  background: #25A9FC;
}

.box{
  position: relative;
  margin: auto;
  display: block;
  margin-top: 8%;
  width: 600px;
  height: 420px;
  background: none;
}

.head{
  position: absolute;
  top:16.5%;
  left: 25%;
  width: 50%;
  height: 67%;
  background: #A6BECF;
  border-radius: 50%;
}

.head-copy{
  width: 100%;
  height: 100%;
  position: absolute;
  background: #A6BECF;
  border-radius: 50%;
  z-index: 2;
}

.ear-left{
  position: absolute;
  width: 60%;
  height: 65%;
  left: -20%;
  top: 5%;
  background: #A6BECF;
  border-radius: 50%;
  z-index: 1;
}

.ear-right{
  position: absolute;
  width: 60%;
  height: 65%;
  right: -20%;
  top: 5%;
  background: #A6BECF;
  border-radius: 50%;
  z-index: 1;
}

.inner-ear{
  position: absolute;
  border-radius: 50%;
  width: 80%;
  height: 80%;
  top: 10%;
  left: 10%;
  background: #819CAF;
}

.eye-left{
  position: absolute;
  background: white;
  width: 30%;
  height: 33%;
  top: 25%;
  left: 21%;
  border-radius: 50%;
  z-index: 3;
}

.eye-right{
  position: absolute;
  background: white;
  width: 30%;
  height: 33%;
  top: 25%;
  right: 21%;
  border-radius: 50%;
  z-index: 3;
}

.pupil{
  position: absolute;
  width: 28%;
  height: 30%;
  top: 35%;
  left: 36%;
  border-radius: 50%;
  background: #27354A;
}

.nose{
  position: absolute;
  background: #BE845F;
  width: 25%;
  height: 42.5%;
  left: 37%;
  top: 45%;
  border-radius: 50px;
  z-index: 4;
}

.hair-left{
  position: absolute;
  top: -8%;
  left: 30%;
  width: 20%;
  height: 20%;
  background:  #A6BECF;
  -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

.hair-right{
  position: absolute;
  top: -4%;
  left: 48%;
  width: 20%;
  height: 20%;
  background:  #A6BECF;
  -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
		

Дальнейшая практика

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

Также я предлагаю вам два бесплатных способа прокачать свои навыки по этой теме:

  1. Видеокурс «Pure CSS Images».
  2. Челлендж «Daily CSS Images».
Следите за новыми постами
Следите за новыми постами по любимым темам
27К открытий27К показов