Home > Enterprise >  Transparent Header Thinks Page is Not Scrolled when Body Position is Set to Fixed
Transparent Header Thinks Page is Not Scrolled when Body Position is Set to Fixed

Time:11-20

I created a modal and I had to do some extra work because ios is a pain with modals and setting overflow: hidden is not enough. The workaround on ios is to set the body to position: fixed when the modal is open and you can also set the top property to however far the page is scrolled like I did in the below example.

The thing that is tripping me up here is that the header should stay as it is wherever the user is on the page. When the body is set to fixed the header thinks that the page is not scrolled and always becomes transparent.

How can we fix the header logic so that when the modal is open, the header class does not change?

let scrollY

    window.addEventListener('scroll', e => {
      if (window.scrollY > 100) {
        document.querySelector('.header').classList.remove('header--is-transparent')
      } else {
        document.querySelector('.header').classList.add('header--is-transparent')
      }
    })


    const btn = document.querySelector('.btn')
    btn.addEventListener('click', openModal)

    function openModal() {
      scrollY = window.scrollY

      document.body.style.position = 'fixed'
      document.body.style.overflow = 'hidden'
      document.body.style.width = '100%'
      document.body.style.top = `-${scrollY}px`

      document.querySelector('.main').insertAdjacentHTML('beforeend', `
        <div >  
          <div ></div>
          <div >
            <h3>Modal content</h3>
            <button >X</button>
          </div>  
        </div>
      `)
    }

    function closeModal() {
      document.body.style.position = ''
      document.body.style.overflow = ''
      document.body.style.width = ''

      document.querySelector('.modal').remove()
    }

    document.addEventListener('click', e => {
      if (e.target.closest('.closeBtn')) {
        closeModal()
      }
    })
.main {
      height: 2000px;
      width: 100%;
    }

    .header {
      position: fixed;
      top: 0;
      width: 100%;
      height: 50px;
      background-color: rgba(255, 255, 255);
      opacity: 1;
    }

    .header.header--is-transparent {
      opacity: 0.5;
    }

    li {
      height: 300px;
      list-style: none;
    }

    .li1 {
      background: red;
    }

    .li2 {
      background: blue;
    }

    .li3 {
      background: green;
    }

    .btn {
      color: #fff;
      background: #000;
      height: 60px;
      width: 100px;
      position: fixed;
      bottom: 20px;
      left: 20px;
    }

    .modal {
      position: fixed;
      top: 0;
      right: 0;
      height: 100%;
      width: 100%;
      z-index: 999;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .modal-wrapper {
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .modal-content {
      height: 200px;
      width: 200px;
      background: #fff;
      position: absolute;
    }

    .modal-backdrop {
      height: 100%;
      width: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      position: fixed;
      top: 0;
      left: 0;
    }
<div >
    <div >HEADER</div>
    <li ></li>
    <li ></li>
    <li ></li>
    <button >open modal</button>
  </div>

CodePudding user response:

Just check if the body position is fixed when adding the transparent class, I would suggest to check out https://developer.mozilla.org/en-US/docs/Web/CSS/:modal the :modal property and how to set up your dialog so you can use it

let scrollY

    window.addEventListener('scroll', e => {
      if (window.scrollY > 100 ||  document.body.style.position == "fixed") {
        document.querySelector('.header').classList.remove('header--is-transparent')
      } else {
        document.querySelector('.header').classList.add('header--is-transparent')
      }
    })


    const btn = document.querySelector('.btn')
    btn.addEventListener('click', openModal)

    function openModal() {
      scrollY = window.scrollY

      document.body.style.position = 'fixed'
      document.body.style.overflow = 'hidden'
      document.body.style.width = '100%'
      document.body.style.top = `-${scrollY}px`

      document.querySelector('.main').insertAdjacentHTML('beforeend', `
        <div >  
          <div ></div>
          <div >
            <h3>Modal content</h3>
            <button >X</button>
          </div>  
        </div>
      `)
    }

    function closeModal() {
      document.body.style.position = ''
      document.body.style.overflow = ''
      document.body.style.width = ''

      document.querySelector('.modal').remove()
    }

    document.addEventListener('click', e => {
      if (e.target.closest('.closeBtn')) {
        closeModal()
      }
    })
.main {
      height: 2000px;
      width: 100%;
    }

    .header {
      position: fixed;
      top: 0;
      width: 100%;
      height: 50px;
      background-color: rgba(255, 255, 255);
      opacity: 1;
    }

    .header.header--is-transparent {
      opacity: 0.5;
    }

    li {
      height: 300px;
      list-style: none;
    }

    .li1 {
      background: red;
    }

    .li2 {
      background: blue;
    }

    .li3 {
      background: green;
    }

    .btn {
      color: #fff;
      background: #000;
      height: 60px;
      width: 100px;
      position: fixed;
      bottom: 20px;
      left: 20px;
    }

    .modal {
      position: fixed;
      top: 0;
      right: 0;
      height: 100%;
      width: 100%;
      z-index: 999;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .modal-wrapper {
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .modal-content {
      height: 200px;
      width: 200px;
      background: #fff;
      position: absolute;
    }

    .modal-backdrop {
      height: 100%;
      width: 100%;
      background-color: rgba(0, 0, 0, 0.5);
      position: fixed;
      top: 0;
      left: 0;
    }
<div >
    <div >HEADER</div>
    <li ></li>
    <li ></li>
    <li ></li>
    <button >open modal</button>
  </div>

  • Related