Click here to Skip to main content
14,733,443 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I have a page with a fixed top bar and a section menu that fixes to the bottom of the viewport on small devices and at the top, below the top bar, on devices with viewports wider than 1080px.

There's also an element at a certain point down the page that when the user scrolls past it, it fixes to the top of the viewport.

I've managed to get all of this to work but the issue is that I cannot seem to adjust the distance at which the element fixes from the top of the viewport. In other words it needs to be fixed at top: 75px on screens less than 1080px and top: 140px on screens larger than 1080px.

This is to cater to the fact that the section menu is either fixed at the bottom of the viewport on mobile and below the top bar on desktop.

I've created a minimal demo in CodePen to demonstrate this where I have placed the required javascript for the main functions within a match media query, in an attempt to make this top adjustment.

However, as you will see, it simply applies the highest setting (140px) which results in a gap between the top bar and the fixed element on smaller screens.

Here's the CodePen:

https://codepen.io/creativezest/pen/wvzvJdp

I've included the code for what I have already tried below.

I would greatly appreciate any help at all.

Many thanks.

Kind regards, Marc

What I have tried:

HTML

<pre lang="HTML"><pre><!DOCTYPE html>
<html lang="en">
<head>

<!-- STYLESHEET LINKS -->
<link rel="stylesheet" type="text/css" href="main.css" />

<!-- FONT LINKS -->
<link rel="stylesheet" type="text/css" href="../MyFontsWebfontsKit.css">

  <!-- JQUERY LINK -->
  <script src="jquery.js"></script>

</head>

<body>

<!-- Top Bar Element -->

<div class="topBar">
    <p>Top Bar</p>
</div>

<div class="sectionMenu">
    <p>Section Menu</p>
</div>

<!-- Section 1 -->

<div class="section hero">
    <h1>Hero</h1>
</div>

<!-- Section 2 -->

<div class="section one">
    <h2>Section 1</h2>
</div>

<!-- Section 1 -->

<div class="section two">
    <h2>Section 2</h2>
</div>

 <!-- This div is used to indicate the original position of the scrollable fixed div. -->

 <div class="scroller_anchor"></div>

 <!-- This element should fix directly below the topbar on screens less than 1080px wide and below the section menu on screens above 1080px -->

<div class="fixed-element">
    <h3>Element becomes fixed</h3>
</div>

<!-- Section 2 -->

<div class="section two">
    <h2>Section 2</h2>
</div>

<!-- Section 3 -->

<div class="section three">
    <h2>Section 3</h2>
</div>

<!-- Section 4 -->

<div class="section four">
    <h2>Section 4</h2>
</div>

<!-- Section 5 -->

<div class="section five">
    <h2>Section 5</h2>
</div>

<!-- SCRIPT LINK -->
<script src="scripts.js"></script>

<!-- TYPETURA -->
<script src="typetura.js"></script>

</body>
</html>




CSS


<pre>* {
    box-sizing: border-box;  
 }
 
 html, body {
    max-width: 100%;
    margin: 0;
    padding: 0;
  }

  body {
     width: 100%;
     height: 100%;
     font-family: HelveticaLTWXX-Roman, arial, sans-serif;
     font-style: normal;
     font-size: 16px;
     color: white;
     background-color: white;
     margin: 0;
     padding: 0;
     scroll-behavior: smooth;
     transition: all .5s;
  }

  /******************************************* HEADINGS *****************************************/

  h1, h2, h3 {
      margin: 0;
      padding: 0;
      font-family: HelveticaNowDisplay-XBd, arial, sans-serif;
      font-weight: 600;
  }

  h1 {
    --tt-key: h1;
    --tt-max: 2560;
    font-size: 4rem;
    width: 85%;
    margin: 0 auto;
    text-align: center;
  }

  @keyframes h1 {
    0%, 12.5% {
        font-size: 4rem;
    }

    100% {
        font-size: 12rem;
    }
}

  h2 {
    --tt-key: h2;
    --tt-max: 2560;
    font-size: 2rem;
  }

  @keyframes h2 {
    0%, 12.5% {
        font-size: 2rem;
    }

    100% {
        font-size: 10rem;
    }
}

h3 {
    font-family: HelveticaLTWXX-Roman;
    font-weight: normal;
    font-size: 1.5rem;
}


/******************************************* TOP BAR *****************************************/

.topBar {
    display: grid;
    position: fixed;
    top: 0;
    z-index: 2;
    justify-content: center;
    align-content: center;
    width: 100%;
    height: 75px;
    background-color: #0c0c0c;
}

.topBar p {
    font-size: 1.5rem;
    margin: 0;
    padding: 0;
}


/******************************************* SECTION MENU *****************************************/

.sectionMenu {
    display: grid;
    position: fixed;
    bottom: 0px;
    z-index: 2;
    justify-content: center;
    align-content: center;
    width: 100%;
    height: 60px;
    background-color: #141414;
}

.sectionMenu p {
    font-size: 1.5rem;
    margin: 0;
    padding: 0;
}


/******************************************* CONTENT SECTIONS *****************************************/

.section {
    position: static;
    top: 0;
    display: grid;
    align-content: center;
    justify-content: center;
    width: 100%;
    padding: 20rem 0 20rem 0;
}

.hero {
    background-color: #035dbc;
}

.one {
    background-color: #a9a9a9;
}

.two {
    background-color: #bebebe;
}

.three {
    background-color: #d0d0d0;
}

.four {
    background-color: #dcdcdc;
}

.five {
    background-color: #f0f0f0;
}


/******************************************* SCROLL ANCHOR *****************************************/

.scroller_anchor{
    height:0px;
    margin:0;
    padding:0;
  }


/************************************ ELEMENT FIXES TO TOP ON SCROLL PAST ********************************/

.fixed-element {
    display: grid;
    width: 100%;
    height: 60px;
    align-content: center;
    justify-content: center;
    background-color: #0c0c0c;
    transition: all 0.5s ease-in-out;
}

/********************************************* BREAKPOINT *****************************************/

@media only screen and (min-width: 1080px) {

    .sectionMenu {
        top: 75px;
    }

    .hero {
        top: 135px;
    }

}



JavaScript

<pre><pre>// ADJUST THE TOP POSITION OF THE FIXED PERSONA THUMBNAILS BUTTON ROW BETWEEN SMALL AND LARGE DEVICES - (1080PX)  //


function myFunction(x) {

    if (x.matches) { // If media query matches
  
      $(window).scroll(function(e) {
  
  
        var scroller_anchor = $(".scroller_anchor").offset().top;
         
      
        if ($(this).scrollTop() >= scroller_anchor && $('.fixed-element').css('position') != 'fixed') 
        { 
          $('.fixed-element').css({
              'position': 'fixed',
              'top': '135px',
              'z-index': '2',
              'box-shadow': '0px 3px 3px rgba(0, 0, 0, 0.5)'
          });
           
            $('.scroller_anchor').css('height', '60px');
        } 
        
        else if ($(this).scrollTop() < scroller_anchor && $('.fixed-element').css('position') != 'relative') 
        {    
             
            $('.scroller_anchor').css('height', '0px');
      
            $('.fixed-element').css({
              'position': 'relative',
              'top': '0px',
              'box-shadow': 'none'
          });
        }
      });
  
    }
    
    else {
  
      $(window).scroll(function(e) {
  
  
        var scroller_anchor = $(".scroller_anchor").offset().top;
         
      
        if ($(this).scrollTop() >= scroller_anchor && $('.fixed-element').css('position') != 'fixed') 
        { 
          $('.fixed-element').css({
              'position': 'fixed',
              'top': '140px',
              'z-index': '2',
              'box-shadow': '0px 3px 3px rgba(0, 0, 0, 0.5)'
          });
           
            $('.scroller_anchor').css('height', '60px');
        } 
        
        else if ($(this).scrollTop() < scroller_anchor && $('.fixed-element').css('position') != 'relative') 
        {    
             
            $('.scroller_anchor').css('height', '0px');
      
            $('.fixed-element').css({
              'position': 'relative',
              'top': '0px',
              'box-shadow': 'none'
          });
        }
      });
    }
  }
  
  var x = window.matchMedia("(min-width: 1080px)")
  myFunction(x) // Call listener function at run time
  x.addListener(myFunction) // Attach listener function on state changes 
Posted
Updated 29-Nov-20 23:19pm

1 solution

No need for Javascript - just use sticky positioning:
position - CSS: Cascading Style Sheets | MDN[^]
Can I use... Support tables for HTML5, CSS3, etc[^]
https://codepen.io/RichardD2/pen/LYREwRo[^]
.fixed-element {
  ...
  position: sticky;
  top: 75px;
}

@media only screen and (min-width: 1080px) {
  ...
  .fixed-element{
    top: 135px;
  }
}
Browser support is pretty good, and there are polyfills available if you need to support older browsers.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900