Режимы наложения + гриды = 🖤
В этой статье я продолжил экспериментировать с режимами наложения (ещё один эксперимент в прошлой статье) и решил сделать что-то более-менее «раскладочное» с помощью гридов.
На эту мысль меня навела реклама магазина в метро с тонированными областями изображения.
Вот, что получилось:
Давайте разбираться 🦄.
Лейаут собран на гридах. В очередной раз кайфанул от удобства грид-лейаута. И не только от удобства процесса сборки интерфейса, но и от продуманности гридов в плане «резины» и взаимодействия их с другими возможностями 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
🍀.
В общем, я попробовал ещё другие сочетания режимов наложения и раскладки слоёв, выходит прикольно, можно попробовать где-то применить: