Главная » Статьи » Динамические размеры липкой боковой панели с HTML и CSS

Динамические размеры липкой боковой панели с HTML и CSS

Динамические размеры липкой боковой панели с HTML и CSS

От автора: создание содержимого страницы, которое «прилипает» к области просмотра при прокрутке, что-то вроде меню перехода к привязке или заголовков разделов, никогда не было таким простым. Добавьте position: sticky в набор правил CSS, установите смещение направления (например top: 0), и вы готовы произвести впечатление на своих товарищей по команде с минимальными усилиями.

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

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

Как я уже упоминал ранее, стиль макета реализовать было так же просто. Но была одна загвоздка: высота компонента зависела от его содержимого. Я мог бы задать max-height и установить overflow-y: auto, чтобы содержимое компонента было прокручиваемым. Это хорошо работало на экране моего ноутбука, но в меньшем окне просмотра с меньшим вертикальным пространством высота боковой панели превышала бы размер окна просмотра.

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

Разбор решений

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

Затем я вспомнил, что высота фиксированного компонента является динамической. Какое магическое значение я мог бы использовать для своего медиа-запроса, который мог бы обработать такую вещь? Возможно, вместо этого я мог бы написать функцию JavaScript, чтобы проверить, выходит ли компонент за границы области просмотра при загрузке страницы? Тогда я мог бы обновить высоту компонента… Это была возможность.

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

Настройка раздела страницы

Я начал с отображения основного элемента flex. Для боковой панели было установлено значение фиксированной ширины flex-basis. Затем элемент article заполнил оставшееся доступное пространство горизонтального окна просмотра.

Если вам интересно, как я сумел сложить два контейнера для меньших окон просмотра без медиа-запроса, ознакомьтесь с трюком Flexbox Holy Albatross. Я добавил на боковую панель align-self: start, чтобы ее высота не растягивалась вместе с основной статьей (значение stretch по умолчанию). Это дало свойствам позиционирования возможность использовать свою магию:

.sidebar { --offset: var(--space); /* ... */ position: sticky; top: var(--offset);
}

Проверь это! Благодаря этим двум свойствам CSS элемент боковой панели прикрепляется к верхней части области просмотра со смещением. Обратите внимание, что для значения top установлено пользователдьское свойство CSS с. Теперь переменную —offset можно повторно использовать в любом дочернем элементе на боковой панели. Это пригодится позже при установке максимальной высоты закрепленного компонента боковой панели.

Вы можете найти список объявлений глобальных переменных CSS в демонстрации CodePen, включая переменную —space, используемую для значения смещения в наборе правил :root.

Фиксированная боковая панель

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

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

.component { display: grid; grid-template-rows: auto 1fr auto;
}


.component .content { max-height: 500px; overflow-y: auto;
}

Этот компонент использует CSS Grid и идею стека блинов из 1-Line Layouts для настройки строк этого шаблона. И header, и footer (auto) подстраиваются под высоту своих дочерних элементов, в то время как содержимое (1fr или одна дробная единица ) заполняет остальную часть доступного вертикального пространства.

А на содержимом max-height ограничивает рост компонента на экранах большего размера. В этом нет необходимости, если требуется, чтобы компонент растягивался до высоты области просмотра.

overflow-y: auto позволяет при необходимости прокручивать контент.

Когда компонент используется в боковой панели, необходим элемент max-height, чтобы он не превышал высоту области просмотра. Ранее область действия —offset в классе .sidebar удваивается, чтобы создать запас на нижней части элемента, который соответствует верхнему смещению фиксированной боковой панели:

.sidebar .component { max-height: calc(100vh - var(--offset) * 2);
}

На этом сборка этого фиксированного компонента боковой панели завершена! После применения некоторых декоративных стилей этот прототип был готов к тестированию и рассмотрению. Попробуйте! Откройте демонстрацию в CodePen и щелкните элементы сетки, чтобы добавить их на боковую панель. Измените размер окна браузера, чтобы увидеть, как компонент изменяется, оставаясь в поле зрения при прокрутке основного раздела содержимого.

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

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

Автор: Ryan Mulligan

Источник: css-tricks.com

Редакция: Команда webformyself.