Рисуем абстрактные картины на чистом CSS
easy

Рисуем абстрактные картины на чистом CSS

Импрессионизм, авангардизм и искусство

Сегодня займёмся искусством сразу в двух направлениях: нарисуем 9 разных картин и посмотрим, как это легко сделать с помощью современного CSS. Работы на 10–15 минут, а в конце получится такая красота:

Рисуем абстрактные картины на чистом CSS

Логика проекта

Всё, что нам сегодня будет нужно, — это HTML и CSS. Скрипты не понадобятся, потому что современные стили уже умеют работать с переменными и создавать новые картинки на основе других элементов на странице.

Работу построим так:

  1. Создадим HTML-страницу, где разместим блоки, в которых и появятся наши картинки.
  2. Зададим стили для всей страницы и общие для блоков.
  3. Нарисуем первую картинку.
  4. На основе первой создадим остальные 8 — и каждая будет выглядеть иначе.

Подводных камней тут нет, поэтому сразу приступим.

Создаём HTML-страницу

Открываем редактор кода, создаём новый файл и сохраняем его сразу как index.html. Всё, что нам нужно от страницы, — добавить блоки, в которых и будут создаваться картинки. Также добавим общий блок, внутри которого будут появляться наши картинки — так мы сможем настроить сразу их размер, отступы и расположение (но это уже сделаем в стилях, которые подключим сразу):

<!DOCTYPE html>
<html lang="ru" >
<head>
  <meta charset="UTF-8">
  <title>Создаём абстрактный фон</title>
  <!-- Подключаем стили -->
  <link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Общий блок с картинками -->
<div class="wrapper">
	<!-- Отдельные блоки для каждой картинки -->
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
</div>
</body>
</html>

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

Настраиваем стили

Теперь создаём новый файл style.css и начинаем наполнять уже его. 

Первое, что делаем — ограничиваем визуальное отображение каждого блока по границам. Это нам нужно для того, чтобы если что-то не помещается в блок, это обрезалось как раз по границам блока:

/* Ограничиваем размер содержимого блока их границами */
* {
	box-sizing: border-box;
}

Следующий шаг — общие настройки для всей страницы. Тут мы используем переменные для размера рамок и цвета фона, чтобы было проще работать. Все элементы на странице располагаем по сетке, а контент — по центру. Ну и фон сразу сделаем тёмно-зелёным, чтобы было контрастнее:

/* Общие настройки для всей страницы */
body {
	/* Переменные для размера рамок и цвета фона в картинках */
	--s: max(1rem, 2vw);
	--bg: deeppink;
	/* Настраиваем отступы */
	margin: 0;
	padding: var(--s);
	/* Размещаем элементы по сетке */
	display: grid;
	/* Пусть контент занимает всю высоту экрана */
	min-height: 100vh;
	/* Располагаем элементы по центру */
	place-items: center;
	/* Цвет фона для страницы */
	background: teal;
}

Визуально у нас поменялся только фон, но эти стили нам помогут правильно разместить элементы на странице, когда они появятся. Обновляем браузер и видим новый фон:

Рисуем абстрактные картины на чистом CSS

Настраиваем модуль с блоками

У нас есть общий блок с классом .wrapper, где располагаются 9 блоков с будущими картинками. Пропишем стили, которые будут влиять сразу на все блоки внутри — их размер, расстояние между ними и их расстановку:

/* Настройки общего блока с картинками */
.wrapper {
	/* Настраиваем ширину блока */
	width: 100%;
	max-width: 70rem;
	/* Размещаем элементы по сетке */
	display: grid;
	/* Устанавливаем расстояние между картинками */
	gap: var(--s);
	/* Заполняем общий блок мелкими картинками с автоподбором расстояния */
	grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
}

Теперь настроим стили уже для этих отдельных маленьких блоков — сделаем их квадратными, добавим рамку и фон:

/* Настройки отдельной картинки внутри общего блока */
.wrapper div {
	/* Делаем их квадратными */
	aspect-ratio: 1;
	/* Настраиваем рамки вокруг картинок */
	border: calc(var(--s) * 0.2) solid;
	/* Задаём фон для мелких картинок */
	background-color: var(--bg);
}

Если обновить страницу в браузере, то увидим, что у нас появилось что-то новое — те самые 9 основ для картинок, которые нам предстоит создать (и сделать разными):

Рисуем абстрактные картины на чистом CSS

Рисуем первую картинку

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

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

Рисуем первую картинку:

/* Смещение зелёной полосы */
--c1-pos: 30%;
/* Все элементы на картинке используются как части изображения */
background-image: 
	/* Создаём чёрные линии */
	linear-gradient(
		/* Направление линий */
		var(--black-dir, to bottom), 
		/* Формируем 4 линии, каждая со своими параметрами прозрачности */
		transparent 10%, black 0, black 15%, transparent 0, 
		transparent 18%, black 0, black 22%, transparent 0, 
		transparent 25.25%, black 0, black 29%, transparent 0, 
		transparent 33%, black 0, black 35.5%, transparent 0),
	/* Создаём зелёную полосу */
	linear-gradient(
		/* Направление полосы */
		var(--c1-angle, 105deg), 
		/* Параметры зелёной полосы */
		transparent var(--c1-pos), lime 0, lime calc(var(--c1-pos) + var(--c1-w, 10%)), transparent 0),
	/* Создаём белый круг */
	radial-gradient(
		/* Положение круга */
		circle at var(--circle-pos, 75% 75%), 
		/* Размер круга */
		white var(--circle-size, 30%), 
		/* Прозрачность */
		transparent 0);

Вот что у нас получилось:

Рисуем абстрактные картины на чистом CSS

Смотрите, что здесь произошло и почему именно так.

  1. Мы нарисовали первую картинку: расположили чёрные линии, зелёную полосу и круг так, как нам нужно (ну, или как захотели, без разницы).
  2. Всё это мы прописали в стиле для конкретного блока.
  3. Так как все 9 блоков внутри общего — одинаковые, то мы и получили 9 одинаковых картинок.

Теперь сделаем так, чтобы все картинки были разными.

Делаем так, чтобы картинки отличались

Так как наша задача в том, чтобы картинки отличались друг от друга, мы используем псевдокласс :nth-child(), где в скобках указывается какое-то число. Этот псевдокласс смотрит на число в скобках и находит такой же по счёту элемент среди всех элементов того же класса. 

Первая картинка у нас готова, значит будем работать со вторым элементом — :nth-child(2). Так как мы при создании первой картинки использовали переменные, нам достаточно в этом псевдоклассе поменять значения этих переменных, чтобы получить новый результат:

/* Указываем параметры картинки во втором блоке	*/
&:nth-child(2) {
	/* Поворачиваем чёрные линии */
	--black-dir: 35deg;
	/* Поворачиваем зелёную линию */
	--c1-angle: 175deg;
	/* Настраиваем ширину зелёной линии */
	--c1-w: 55%;
	/* Указываем центр круга */
	--circle-pos: 60% 12%;
	/* Настраиваем размер круга */
	--circle-size: 9%;
}

Рисуем абстрактные картины на чистом CSS

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

Теперь зная, как это работает, поменяем переменные во всех остальных картинках:

&:nth-child(3) {
	--black-dir: 250deg;
	--c1-angle: 360deg;
	--c1-w: 15%;
	--circle-pos: 5% 50%;
	--circle-size: 40%;
}

&:nth-child(4) {
	--black-dir: 280deg;
	--c1-angle: 20deg;
	--c1-w: 5%;
	--circle-pos: 25% 25%;
	--circle-size: 18%;
}

&:nth-child(5) {
	--black-dir: 0;
	--c1-angle: 135deg;
	--c1-w: 60%;
	--circle-pos: 35% 35%;
	--circle-size: 30%;
}

&:nth-child(6) {
	--black-dir: 50deg;
	--c1-angle: 265deg;
	--c1-w: 10%;
	--circle-pos: 40% 45%;
	--circle-size: 10%;
}

&:nth-child(7) {
	--black-dir: 140deg;
	--c1-angle: 90deg;
	--c1-w: 20%;
	--circle-pos: 50% 65%;
	--circle-size: 24%;
}

&:nth-child(8) {
	--black-dir: 190deg;
	--c1-angle: 10deg;
	--c1-w: 8%;
	--circle-pos: 50% 120%;
	--circle-size: 50%;
}

&:nth-child(9) {
	--black-dir: 100deg;
	--c1-angle: -40deg;
	--c1-w: 25%;
	--circle-pos: 40% 20%;
	--circle-size: 12%;
}

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

Рисуем абстрактные картины на чистом CSS

<!DOCTYPE html>
<html lang="ru" >
<head>
  <meta charset="UTF-8">
  <title>Создаём абстрактный фон</title>
  <!-- Подключаем стили -->
  <link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Общий блок с картинками -->
<div class="wrapper">
	<!-- Отдельные блоки для каждой картинки -->
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
	<div></div>
</div>
</body>
</html>

/* Ограничиваем размер содержимого блока их границами */
* {
	box-sizing: border-box;
}

/* Общие настройки для всей страницы */
body {
	/* Переменные для размера рамок и цвета фона в картинках */
	--s: max(1rem, 2vw);
	--bg: deeppink;
	/* Настраиваем отступы */
	margin: 0;
	padding: var(--s);
	/* Размещаем элементы по сетке */
	display: grid;
	/* Пусть контент занимает всю высоту экрана */
	min-height: 100vh;
	/* Располагаем элементы по центру */
	place-items: center;
	/* Цвет фона для страницы */
	background: teal;
}

/* Настройки общего блока с картинками */
.wrapper {
	/* Настраиваем ширину блока */
	width: 100%;
	max-width: 70rem;
	/* Размещаем элементы по сетке */
	display: grid;
	/* Устанавливаем расстояние между картинками */
	gap: var(--s);
	/* Заполняем общий блок мелкими картинками с автоподбором расстояния */
	grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
}

/* Настройки отдельной картинки внутри общего блока */
.wrapper div {
	/* Делаем их квадратными */
	aspect-ratio: 1;
	/* Настраиваем рамки вокруг картинок */
	border: calc(var(--s) * 0.2) solid;
	/* Задаём фон для мелких картинок */
	background-color: var(--bg);

/* Создаём и настраиваем первую картинку */
	--c1-pos: 30%;
	/* Все элементы на картинке используются как части изображения */
	background-image: 
		/* Создаём чёрные линии */
		linear-gradient(
			/* Направление линий */
			var(--black-dir, to bottom), 
			/* Формируем 4 линии, каждая со своими параметрами прозрачности */
			transparent 10%, black 0, black 15%, transparent 0, 
			transparent 18%, black 0, black 22%, transparent 0, 
			transparent 25.25%, black 0, black 29%, transparent 0, 
			transparent 33%, black 0, black 35.5%, transparent 0),
		/* Создаём зелёную полосу */
		linear-gradient(
			/* Направление полосы */
			var(--c1-angle, 105deg), 
			/* Параметры зелёной полосы */
			transparent var(--c1-pos), lime 0, lime calc(var(--c1-pos) + var(--c1-w, 10%)), transparent 0),
		/* Создаём белый круг */
		radial-gradient(
			/* Положение круга */
			circle at var(--circle-pos, 75% 75%), 
			/* Размер круга */
			white var(--circle-size, 30%), 
			/* Прозрачность */
			transparent 0);
	
	/* Указываем параметры картинки во втором блоке	*/
	&:nth-child(2) {
		/* Поворачиваем чёрные линии */
		--black-dir: 35deg;
		/* Поворачиваем зелёную линию */
		--c1-angle: 175deg;
		/* Настраиваем ширину зелёной линии */
		--c1-w: 55%;
		/* Указываем центр круга */
		--circle-pos: 60% 12%;
		/* Настраиваем размер круга */
		--circle-size: 9%;
	}
	
	&:nth-child(3) {
		--black-dir: 250deg;
		--c1-angle: 360deg;
		--c1-w: 15%;
		--circle-pos: 5% 50%;
		--circle-size: 40%;
	}
	
	&:nth-child(4) {
		--black-dir: 280deg;
		--c1-angle: 20deg;
		--c1-w: 5%;
		--circle-pos: 25% 25%;
		--circle-size: 18%;
	}
	
	&:nth-child(5) {
		--black-dir: 0;
		--c1-angle: 135deg;
		--c1-w: 60%;
		--circle-pos: 35% 35%;
		--circle-size: 30%;
	}
	
	&:nth-child(6) {
		--black-dir: 50deg;
		--c1-angle: 265deg;
		--c1-w: 10%;
		--circle-pos: 40% 45%;
		--circle-size: 10%;
	}
	
	&:nth-child(7) {
		--black-dir: 140deg;
		--c1-angle: 90deg;
		--c1-w: 20%;
		--circle-pos: 50% 65%;
		--circle-size: 24%;
	}
	
	&:nth-child(8) {
		--black-dir: 190deg;
		--c1-angle: 10deg;
		--c1-w: 8%;
		--circle-pos: 50% 120%;
		--circle-size: 50%;
	}
	
	&:nth-child(9) {
		--black-dir: 100deg;
		--c1-angle: -40deg;
		--c1-w: 25%;
		--circle-pos: 40% 20%;
		--circle-size: 12%;
	}
}

Обложка:

Алексей Сухов

Корректор:

Елена Грицун

Вёрстка:

Мария Климентьева

Соцсети:

Юлия Зубарева

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Вам может быть интересно
easy