Не работает position: sticky при включенном overflow-x: hidden, но необходимо сохранить оба свойства

В моём проекте применены такие проблемные стили:

html, body {
  overflow-x: hidden;
}

header { 
  position: sticky; 
  top: 0px;
}

Если убрать overflow-x: hidden, позиционирование header работает замечательно, но мне важно оставить оба стиля. Есть ли варианты решения этой проблемы?


Ответы (2 шт):

Автор решения: user646144

Нашёл костыль. Задал 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-анимацией, который рендерит модуль, задавая собственные стили. Переписывать модуль под себя не очень хотелось, обошёл через это.

→ Ссылка
Автор решения: Grundy

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>

→ Ссылка