Как сделать так, чтобы положение привязывалось к элементам сетки CSS
Вы когда-нибудь сталкивались со случаем, когда position: sticky
не работает должным образом с дочерним элементом грид-контейнера? Несколько дней назад я помогал другу решить именно эту проблему и хотел, наконец, написать об этом.
Введение
Эта проблема на самом деле не является чем-то ошибочным или неправильным. Фактически, это эффект поведения CSS по умолчанию. Почему и как? Давайте посмотрим на следующий пример.
<div class="wrapper">
<aside></aside>
<main></main>
</div>
.wrapper {
display: grid;
grid-template-columns: 250px minmax(10px, 1fr);
grid-gap: 1rem;
}
У нас есть сетка, в которой сторона занимает 250px
по ширине, а остальное доступное пространство предназначено для основного раздела. Просто, верно?
Теперь мы хотим добавить position: sticky
к элементу aside, чтобы он фиксировался при прокрутке.
aside {
position: sticky;
top: 0;
}
Упс. Это не работает? Почему это? Давайте узнаем.
Поведение align-items по умолчанию
Добавление фона к боковому элементу покажет, что его высота равна основному разделу.
Это поведение свойства align-items
по умолчанию. По умолчанию растягивается. В результате столбец будет растягиваться по высоте, чтобы соответствовать самому большому столбцу в сетке.
Позвольте мне показать вам еще один пример, который поможет лучше проиллюстрировать проблему. У нас есть простой грид-контейнер.
.cards__list {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1rem;
}
По умолчанию карты растягиваются, чтобы соответствовать самой большой карте (первой справа). Чтобы переопределить это поведение, нам нужно изменить значение align-items
на start
.
.cards__list {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1rem;
align-items: start;
}
Вернемся к исходному примеру. Чтобы еще больше показать проблему, я добавил фон в раздел aside
. Попробуйте переключить флажок в следующей демонстрации и обратите внимание, как изменяется высота боковой панели.
Чтобы сделать боковую панель липкой, нам нужно переопределить поведение растяжения по умолчанию и сделать боковую высоту равной содержимому. Мы можем либо использовать align-self
для элемента aside
:
aside {
align-self: start;
}
Или использовать align-items
для родителя, что повлияет на все дочерние элементы.
.wrapper {
display: grid;
grid-template-columns: 250px minmax(10px, 1fr);
grid-gap: 1rem;
align-items: start;
}
Выбор между ними зависит от вашего варианта использования. У вас может быть более двух столбцов, и вы хотите выровнять только один из них.
Другой пример
Очень похожий пример, который может использовать такое же поведение сетки CSS по умолчанию, — это страница со списком команд.
При прокрутке мы хотим, чтобы «Дизайн» оставался фиксированным, чтобы мы могли быть уверены, что текущий список команд относится к «Дизайну». Без использования align-self: start
в заголовке это не будет работать должным образом.
.section {
display: grid;
grid-template-columns: 100px 1fr;
grid-gap: 2rem;
}
.section__headline {
position: sticky;
top: 1rem;
align-self: start;
}
🍬 Заключение
Это пример функции CSS, от которой мы, разработчики, можем получить пользу в некоторых случаях и переопределить ее другим значением (точно так же, как в этой статье).
Я надеюсь, вы узнали что-то новое!