0

I have a fixed div element and I want to hide it after scrolling for a width smaller than 767px. With media queries, I can do this when the width is smaller than 767px but I want to trigger the display: hidden after scrolling. How can I do it?

body {
  background: #000;
}

#magic {
  position: fixed;
  z-index: 999999;
  top: 50px;
  margin-bottom: 20px;
  margin-right: 50px;
  display: flex;
}

#music {
  position: fixed;
  z-index: 999999;
  top: 50px;
  margin-bottom: 20px;
  margin-right: 300px;
  display: flex;
}

.play {
  display: flex;
  min-width: 5px;
  height: 31px;
  width: 11px;
  text-align: left;
  padding: 0px 10px;
  background: #fff;
  /* player background */
  border-left: 3px solid #16090F;
  /* player border */
  color: #B5A7BA;
  opacity: 1;
  -webkit-transition: all .4s ease;
  -moz-transition: all .4s ease;
  -o-transition: all .4s ease;
  transition-delay: .4s;
  -webkit-transition-delay: .4s;
  border-radius: 100%;

}

@media (max-width: 767px) {

  #music {
    top: -550px;
    margin-bottom: 20px;
    margin-right: 350px;
    display: flex;
  }

  #magic {
    margin-right: 30px;
  }
}
<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">

</head>

  <body>
    <div id="magic">
      <a href="#" style="text-decoration: none; color: #fff; font-size: 10px;">
      <i class="fa fa-snowflake-o fa-2x" style="color:#eee" aria-hidden="true"></i> Magic</a>
    </div>
    <div id="music">
      <div class="roundthing">
      </div>
      <div class="play"></div>
    </div>
  </body>

</html>

I wrote the part of the code related to those fixed elements but feel free to use anything.

Thanks in advance!

lighting
  • 400
  • 2
  • 13
  • If the media width gets larger again (e.g. the user changes from portrait to landscape mode or resizes their browser do you want the fixed div to reappear - it sounds as though you do from your description in which case just listening for the scroll event and hiding the element once and for all isn't enough. – A Haworth Jul 26 '21 at 16:48

4 Answers4

3

You can listen to a scroll event and run the check below

if (window.matchMedia('screen and (max-width: 767px)').matches) {
    // hide the element here
}

Take a look at How to hide a div wih jQuery dependant on screen size

Noslac
  • 446
  • 4
  • 5
  • Does the element need to come back if, for example, the user switches to landscape mode or adjusts their window size? – A Haworth Jul 26 '21 at 18:52
0

There are two options.

  1. Listen to scroll event and then check the screen size
  2. Listen to resize event, check the screen size and then listen to scroll event.

It is better to use the second option as resize triggers less frequently than scroll.

let element = document.querySelector('#magic')

window.addEventListener('resize', check)
check()
function check() {
  if (window.matchMedia('screen and (max-width: 767px)').matches)
    document.addEventListener('scroll', hide)
}

function hide() {
  element.style.display = 'none'
}
body {
  height: 1000px;
  background: #000;
}

#magic {
  position: fixed;
  z-index: 999999;
  top: 50px;
  margin-bottom: 20px;
  margin-right: 50px;
  display: flex;
}

#music {
  position: fixed;
  z-index: 999999;
  top: 50px;
  margin-bottom: 20px;
  margin-right: 300px;
  display: flex;
}

.play {
  display: flex;
  min-width: 5px;
  height: 31px;
  width: 11px;
  text-align: left;
  padding: 0px 10px;
  background: #fff;
  /* player background */
  border-left: 3px solid #16090F;
  /* player border */
  color: #B5A7BA;
  opacity: 1;
  -webkit-transition: all .4s ease;
  -moz-transition: all .4s ease;
  -o-transition: all .4s ease;
  transition-delay: .4s;
  -webkit-transition-delay: .4s;
  border-radius: 100%;

}

@media (max-width: 767px) {

  #music {
    top: -550px;
    margin-bottom: 20px;
    margin-right: 350px;
    display: flex;
  }

  #magic {
    margin-right: 30px;
  }
}
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
</head>

<body>
  <div id="magic">
    <a href="#" style="text-decoration: none; color: #fff; font-size: 10px;">
    <i class="fa fa-snowflake-o fa-2x" style="color:#eee" aria-hidden="true"></i> Magic</a>
  </div>
  <div id="music">
    <div class="roundthing">
    </div>
    <div class="play"></div>
  </div>
</body>
0

You can use innerWidth and write a statement that if the width of the client is lower equal to 768, after scrolling, hide the element. else(width more equal to 769): show element.

I also used IIFE Function. That helps us after loading the page, it runs immediately and you won't need any other action or call to run the function.

(function () {
  const section = document.querySelector('section');
  
  window.addEventListener('scroll', () => {
    window.innerWidth <= 768 ? section.style.opacity = 0 : section.style.opacity = 1;
    }
  )
})();
body {
  height: 200vh
}

section {
  width: 300px;
  height: 200px;
  background-color: orange;
}
<section></section>
Amini
  • 1,620
  • 1
  • 8
  • 26
0

It can be quite overheady listening for the scroll event, especially as in this case we are only interested when the user has moved down from (or back up to) the top.

This snippet uses a different method. It places a tiny div at the top of the page and sets an intersection observer on it. When it is in the viewport we know that we want to show magic whatever the width of the viewport so we set the visibility of magic to visible.

However, when it goes out of the viewport that means the user has scrolled and we set the visibility of magic to var(--visibility). --visibility is set to visible for larger viewport widths, and through a media query is set to hidden for widths under 768 - so magic will disappear. It will reappear if the user scrolls to the top or the viewport is widened (e.g. by the user altering the window size or maybe going to landscape mode on some devices).

This way we avoid the overhead of having to look at all scroll events and there is no need to look for the resize event either.

<html>

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet">
  <style>
    body {
      background: #000;
      height: 300vh;
      /* just so we can scroll for the testing */
    }
    
    #sensor {
      /* when this goes out of view we are deemed to have scrolled */
      position: absolute;
      top: 0;
      left: 0;
      width: 1px;
      height: 20px;
    }
    
    #magic {
      position: fixed;
      z-index: 999999;
      top: 50px;
      margin-bottom: 20px;
      margin-right: 50px;
      display: flex;
      visibility: visible;
      /* this will get changed to var(--visibility) after a scroll on any width of device */
      --visibility: visible;
      /* this will get changed by CSS stylesheet media query on a narrow device */
    }
    
    #music {
      position: fixed;
      z-index: 999999;
      top: 50px;
      margin-bottom: 20px;
      margin-right: 300px;
      display: flex;
    }
    
    .play {
      display: flex;
      min-width: 5px;
      height: 31px;
      width: 11px;
      text-align: left;
      padding: 0px 10px;
      background: #fff;
      /* player background */
      border-left: 3px solid #16090F;
      /* player border */
      color: #B5A7BA;
      opacity: 1;
      -webkit-transition: all .4s ease;
      -moz-transition: all .4s ease;
      -o-transition: all .4s ease;
      transition-delay: .4s;
      -webkit-transition-delay: .4s;
      border-radius: 100%;
    }
    
    @media (max-width: 767px) {
      #music {
        top: -550px;
        margin-bottom: 20px;
        margin-right: 350px;
        display: flex;
      }
      #magic {
        margin-right: 30px;
        --visibility: hidden;
      }
    }
  </style>
</head>

<body>
  <div id="sensor"></div>
  <div id="magic">
    <a href="#" style="text-decoration: none; color: #fff; font-size: 10px;">
      <i class="fa fa-snowflake-o fa-2x" style="color:#eee" aria-hidden="true"></i> Magic</a>
  </div>
  <div id="music">
    <div class="roundthing">
    </div>
    <div class="play"></div>
  </div>
  <script>
    let callback = (entries, observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          // we are at the top of the page so haven't scrolled (or have scrolled right back up)
          magic.style.visibility = 'visible'; //make magic element visible
        } else {
          magic.style.visibility = 'var(--visibility)';
        }
      });
    };
    const sensor = document.querySelector('#sensor');
    const observer = new IntersectionObserver(callback);
    const magic = document.querySelector('#magic');
    observer.observe(sensor);
  </script>
</body>


</html>
A Haworth
  • 30,908
  • 4
  • 11
  • 14