JSFiddle - React, Tailwind, and code Playground

by BurpmanJunior

HTML

<section class="inner">
  <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Nam eget dui. Fusce convallis metus id felis luctus adipiscing. Pellentesque libero tortor, tincidunt et, tincidunt eget, semper nec, quam. In ac felis quis tortor malesuada pretium.</p>
  <p>Proin viverra, ligula sit amet ultrices semper, ligula arcu tristique sapien, a accumsan nisi mauris ac eros. Praesent nonummy mi in odio. Vestibulum eu odio. Phasellus consectetuer vestibulum elit. Quisque malesuada placerat nisl.</p>
</section>

<nav id="navigation">
  <ul class="inner">
    <li><a href="#!">Sed consequat</a></li>
    <li><a href="#!">Vestibulum ipsum</a></li>
    <li><a href="#!">Donec</a></li>
    <li><a href="#!">Integer tincidunt</a></li>
    <li><a href="#!">Nullam sagittis</a></li>
  </ul>
</nav>
<span id="navigation-spacer"></span>

<section class="inner">
  <p>Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Sed magna purus, fermentum eu, tincidunt eu, varius ut, felis. In hac habitasse platea dictumst. Sed aliquam ultrices mauris. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla.</p>
  <p>Praesent metus tellus, elementum eu, semper a, adipiscing nec, purus. Aenean commodo ligula eget dolor. Nulla sit amet est. Vivamus elementum semper nisi.</p>
  <p>Sed in libero ut nibh placerat accumsan. Aenean massa. Fusce commodo aliquam arcu. Vivamus elementum semper nisi. Curabitur suscipit suscipit tellus.</p>
  <p>Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Curabitur turpis. Quisque malesuada placerat nisl. Nunc sed turpis. Pellentesque dapibus hendrerit tortor.</p>
  <p>Vestibulum fringilla pede sit amet augue. Nulla porta dolor. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Praesent egestas neque eu enim. Cras sagittis.</p>
  <p>Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor. Sed magna purus,...

CSS

/** Core styles */
body{
  font-family: monospace;
  font-size: 12px;
  background-color: #fff;
  color: #666;
  line-height: 1.4;
}

*,
*:before,
*:after{
  box-sizing: border-box;
}

a{
  color: #8354a5;
}
a:hover,
a:focus{
  color: #bd7df2;
}

/** Margin resets */
* + *,
p + p{
  margin-top: 1em;
  margin-bottom: 0;
}

li{
  margin-top: 0;
}

/** Containers */
.inner{
  max-width: 600px;
  padding: 0 1em;
  margin: 1em auto;
}

/** Navigation */
#navigation{
  background-color: #fff;
  border-top: 1px solid #eee;
  border-bottom: 1px solid #eee;
  margin: 0;
  padding: 1em 0;
  text-align: center;
}

#navigation .inner{
  margin: 0 auto;
}

#navigation a{
  font-weight: bold;
}

#navigation li{
  display: inline-block;
  margin: 0 0.5em;
}

/** Fixed navigation */
#navigation-spacer{
  display: none;
  padding: 0;
  margin: 0;
}

#navigation.fixed{
  position: fixed;
  top: 0;
  right: 0;
  left: 0;
  border-top-color: #fff;
}

#navigation.fixed + #navigation-spacer{
  /* Display spacer when fixed */
  display: block;
}

JavaScript

/**
 * Sticky navigation
 * @param string nav    Navigation element ID
 * @param string spacer Spacer element ID
 */
function stickyNav(nav, spacer){

	// Locate elements
  var nav_element = document.getElementById(nav),
      spacer_element = document.getElementById(spacer);

	if(!nav_element || !spacer_element){
  
  	// Can't find them
    return false;
    
  }
  
  /**
   * Sets the spacer size so elements below nav don't jump up when fixed
   */
  var setSpacer = function(){
  
  	spacer_element.style.height = nav_element.offsetHeight + 'px';
  
  }
  
  /**
   * Reset spacer to zero for when nav isn't fixed
   */
  var resetSpacer = function(){
  
  	spacer_element.style.height = '';
    
  }
  
  /**
   * Sticky state
   */
  var is_sticky = false;
  
  /**
   * Updates spacer based on state
   */
  var updateSpacer = function(){
  
  	if(is_sticky){
    	
      setSpacer();
      
    }else{
    	
      resetSpacer();
      
    }
  
  }
  
  /**
   * Sets required state
   */
  var setStateRequirement = function(){
  
  	// Check if isn't sticky and needs to be or is currently sticky and still needs to be
  	if(
    	(!is_sticky && nav_element.getBoundingClientRect().top <= 0) ||
    	(is_sticky && spacer_element.getBoundingClientRect().top <= 0)
    ){
    
    	// Needs to be sticky so add fixed class if not already set and set spacer size
    	if(!nav_element.classList.contains('fixed')){
      	nav_element.classList.add('fixed');
      }
      is_sticky = true;
      
    }else{
    
    	// Reset all
      nav_element.classList.remove('fixed');
      is_sticky = false;
      
    }
    
    // Update spacer
    updateSpacer();
    
  }
  
  // Bind event listeners
  window.addEventListener('scroll', setStateRequirement);
  window.addEventListener('resize', setStateRequirement);
    
}


// Run main function with IDs for nav and spacer elements
stickyNav('navigation', 'navigation-spacer');