Режимы наложения + гриды = 🖤

Виталий Зюзин
4 min readApr 10, 2018

--

В этой статье я продолжил экспериментировать с режимами наложения (ещё один эксперимент в прошлой статье) и решил сделать что-то более-менее «раскладочное» с помощью гридов.

На эту мысль меня навела реклама магазина в метро с тонированными областями изображения.

Вот, что получилось:

Давайте разбираться 🦄.

Лейаут собран на гридах. В очередной раз кайфанул от удобства грид-лейаута. И не только от удобства процесса сборки интерфейса, но и от продуманности гридов в плане «резины» и взаимодействия их с другими возможностями CSS.

Итак, начнём с разметки:

<article class="brand">
<img class="brand__img" src="img/horse.jpg" alt="">
<section class="brand__message">
<h1 class="brand__heading">heading</h1>
<p class="brand__text">text</p>
</section>
</article>

Блок .brand отображается как грид. У грида 20 «резиновых» рядов и столбцов + 1 боковой столбец фиксированной ширины 300px с текстом.

.brand {
display: grid;
grid-template-columns: repeat(20, 1fr) 300px;
grid-template-rows: repeat(20, 1fr);
}

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

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

/* Картинка:
идёт по столбцам — от первого столбца до последнего;
идёт по рядам — от первого ряда до последнего */
.brand__img {
grid-column: 1 / -1;
grid-row: 1 / -1;
}
/* Колонка с текстом:
идёт по столбцам — от предпоследнего столбца до последнего;
идёт по рядам — от первого ряда до последнего */
.brand__message {
grid-column: -2 / -1;
grid-row: 1 / -1;
}

Отрицательные значения индексов означают обратный порядок отсчёта: -1 — последний ряд или столбец, -2 — предпоследний и так далее. Это удобно, так как при задании «координат» грид-элемента не нужно хардкодить общее число линий в гриде.

Есть ещё одна тонкость. Чтобы оставить возможность нашему гриду быть гибким, а не фиксированным, нужно подобрать картинку «с запасом» по размеру. Кроме того, нужно заставить картинку img вести себя так, как будто это фоновое изображение в режиме отображения background-size: cover. К счастью, это легко решается свойством object-fit:

.brand__img {
object-fit: cover;
object-position: center left;
width: 100%;
height: 100%;
}

Получился отличный отзывчивый лейаут:

Остаётся непонятным, зачем нам понадобились 20 рядов и столбцов, и как всё таки с имеющейся разметкой покрасить коня?

И тут на помощью приходят псевдоэлементы. Чем .brand::before и .brand::after не элементы грида? Вполне себе полноценные участники раскладки, если задать им любое значение свойства content. Интересно, что хотя псевдоэлементы и не спозиционированы абсолютно или относительно, к ним применяется свойство z-index, то есть можно указать очередность «слоёв» грид-элементов.

.brand::before,
.brand::after {
content: "";
z-index: 1;
}
.brand::before {
grid-column: 1 / -2;
grid-row: 1 / 11;
background-color: honeydew;
}
.brand::after {
grid-column: 1 / -2;
grid-row: -1 / 11;
background-color: orchid;
}

В общем, верхний и нижний «слои краски» будут делить ряды грида пополам, а по столбцам будут занимать всё пространство до боковой колонки:

Остаётся добавить немного магии режимов наложения, и конь будет покрашен:

.brand::before,
.brand::after {
mix-blend-mode: hue;
}

Режим наложения hue берёт оттенок цвета верхнего слоя (в нашем случае это сплошные цвета honeydew и orchid), а насыщенность и светимость от нижнего, то есть по-простому: цветные области будут тонированы, а чёрно-белые останутся такими же. В прошлый раз получилось селективное обесцвечивание, а сейчас вышло наоборот селективное тонирование.

Кстати, я обожаю именованные цвета в CSS! Вы только подумайте, как прекрасно звучит — honeydew🍀.

В общем, я попробовал ещё другие сочетания режимов наложения и раскладки слоёв, выходит прикольно, можно попробовать где-то применить:

--

--