Не работает position: sticky при включенном overflow-x: hidden, но необходимо сохранить оба свойства
В моём проекте применены такие проблемные стили:
html, body {
overflow-x: hidden;
}
header {
position: sticky;
top: 0px;
}
Если убрать overflow-x: hidden
, позиционирование header работает замечательно, но мне важно оставить оба стиля. Есть ли варианты решения этой проблемы?
Ответы (2 шт):
Нашёл костыль. Задал max-width у контейнера с переполнением. Сталкивался с проблемой того, что единицы viewport не учитывают ширину скроллбара, поэтому пришлось дополнительно использовать JS.
Решение:
JS
const scrollbarWidth =
window.innerWidth - document.documentElement.clientWidth;
if (scrollbarWidth > 0) {
document.documentElement.style.setProperty(
"--scrollbarWidth",
scrollbarWidth + "px"
);
CSS
:root {
--adjusted-vw: calc(100vw - var(--scrollbarWidth));
}
.overflowed-container {
max-width: var(--adjusted-vw);
}
Вся сложность проблемы в том, что необходимо было ограничить контейнер с Lottie-анимацией, который рендерит модуль, задавая собственные стили. Переписывать модуль под себя не очень хотелось, обошёл через это.
position:sticky
не работает, если у любого из контейнеров установлено свойство overflow
.
Однако, элементы html
и body
несколько отличаются. Если overflow-x: hidden
будет установлено только у одного из них - sticky
продолжит работать, при условии, что больше ни у одного из предков не будет выставлен overflow
.
document.querySelectorAll('[type="checkbox"]').forEach(c => {
c.addEventListener('change', e => {
document.querySelector(c.dataset.selector).style.overflowX = !c.checked ? '' : 'hidden';
})
})
header {
position: sticky;
top: 0px;
background: red;
}
<div>
<header>Header
<label><input type="checkbox" data-selector="body"> hidden on body</label>
<label><input type="checkbox" data-selector="html"> hidden on html</label>
<label><input type="checkbox" data-selector="div"> hidden on div container</label>
</header>
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</div>