Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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 class="modal">  
          <div class="modal-backdrop"></div>
          <div class="modal-content">
            <h3>Modal content</h3>
            <button class="closeBtn">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 class="main">
    <div class="header header--is-transparent">HEADER</div>
    <li class="li1"></li>
    <li class="li2"></li>
    <li class="li3"></li>
    <button class="btn">open modal</button>
  </div>

>Solution :

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 class="modal">  
          <div class="modal-backdrop"></div>
          <div class="modal-content">
            <h3>Modal content</h3>
            <button class="closeBtn">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 class="main">
    <div class="header header--is-transparent">HEADER</div>
    <li class="li1"></li>
    <li class="li2"></li>
    <li class="li3"></li>
    <button class="btn">open modal</button>
  </div>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading