Lytbox Academy Logo
Community1:1 CoachingBlogContact
Join the AcademySign In
Elementor Tuts

Reveal a Sticky Header on Scroll with Elementor (No Duplicate Headers)

jeffrey at Lytbox
Table of Contents

Learn a simple and fun effect where with header slides down when scrolling your webpage…

I’m back with a revamped and remastered Advanced Elementor headers tutorials!

This is the first Elementor header effect in a series of 3. Each of the 3 tutorials can work as a stand alone effect, or they can be combined to create a truly awesome and super advanced header that gives your website a special experience.

Header Reveal On Scroll

The way this works, when you scroll, the header goes up off page like normal. But when we get to an assigned location on the page scroll, your header will slide back down ‘revealing; itself.

Step 1: Create Your Header

Any header will do. By the way, there’s a video tutorial below showing each of these steps. We’ll begin with a simple basic header that consists of a logo, menu, and call to action button. But feel free to make your header your way.

Step 2: Add Class to Header Container

In the main outer container that wraps your entire header, go to Advance > CSS Classes and add ‘lytbox-header’. Here’s a quick copy and paste to make it easy.

lytbox-header

Step 3: Add a Code Management Plugin

I know you can use Elementor’s editor to add in code, but that gets messy. When building something like our advanced headers, it’s best to use a code management plugin to keep it organized and easier to edit.

My go-to code plugins are FluentSnippets for a free and simple option and WP Codebox for advanced sites. In the video I use FluentSnippets. It’s free, lightweight, and with no ‘pro’ limitations since there is no pro version.

Step 4: Add the JS Snippet

Create a new snippet in your code plugin, name it Header Scroll Effect JS (or whatever else you want to call it), then paste in this snippet:

(() => {
  // ===== EDIT THESE =====
  const STICKY_AFTER_PX = 1000; // when sticky behavior starts
  const ANIM_MS = 180;         // animation speed (matches CSS var)
  const OVERLAY_MODE = true;   // TRUE if header overlays hero (absolute/negative margin)
  // ======================

  const header = document.querySelector('.lytbox-header');
  if (!header) return;

  document.documentElement.style.setProperty('--lytbox-anim-ms', `${ANIM_MS}ms`);

  // Spacer prevents page jump when header becomes fixed (disabled in overlay mode)
  const spacer = document.createElement('div');
  spacer.className = 'lytbox-header-spacer';
  spacer.style.height = '0px';
  spacer.style.pointerEvents = 'none';
  header.insertAdjacentElement('afterend', spacer);

  let isSticky = false;

  const setSpacer = (px) => {
    spacer.style.height = OVERLAY_MODE ? '0px' : `${px}px`;
  };

  const makeSticky = () => {
    if (isSticky) return;
    isSticky = true;

    if (!OVERLAY_MODE) setSpacer(header.offsetHeight);

    // Step 1: apply sticky state off-screen WITHOUT transition
    header.classList.add('lytbox-is-sticky', 'lytbox-no-trans');
    header.classList.remove('lytbox-show');

    // Force style flush (prevents first-time pop-in)
    void header.offsetHeight;

    // Step 2: next frame, enable transition + slide in
    requestAnimationFrame(() => {
      header.classList.remove('lytbox-no-trans');
      header.classList.add('lytbox-show');
    });
  };

  const removeSticky = () => {
    if (!isSticky) return;
    isSticky = false;

    // slide up (hide)
    header.classList.remove('lytbox-show');

    window.setTimeout(() => {
      // return to normal flow
      header.classList.remove('lytbox-is-sticky');

      // kill spacer so no white gap at the top
      setSpacer(0);
    }, ANIM_MS);
  };

  const onScroll = () => {
    if (window.scrollY >= STICKY_AFTER_PX) makeSticky();
    else removeSticky();
  };

  window.addEventListener('scroll', onScroll, { passive: true });
  window.addEventListener('resize', () => {
    if (isSticky && !OVERLAY_MODE) setSpacer(header.offsetHeight);
  });

  onScroll();
})();

To edit the JS, there are 3 options at the top under // ===== EDIT THESE =====.

The 1st option ‘const STICKY_AFTER_PX = 1000;‘, the 1000 default value is the number of pixels the page needs to scroll to ‘reveal’ the header. Change the value to change the location of the reveal effect.

The 2nd option ‘const ANIM_MS = 180;‘ is your animation speed. By default it’s at 180ms. Change the ‘180’ to make the animation faster or slower.

The 3rd option ‘const OVERLAY_MODE = true;‘ is for overlay header. That’s when your header is using a negative margin or position absolute to overlap on top of the banner. If you’re not using an overlay header and instead using an old school nav bar, change the ‘true’ to ‘false’.

Step 5: Add the CSS Snippet

Create another snippet for CSS and paste in the code below:

:root {
  /* OPTIONAL: Sticky background controls */
  --lytbox-sticky-bg: rgba(18, 22, 30, 0.75);
  --lytbox-sticky-blur: 10px;
  --lytbox-sticky-shadow: 0 10px 30px rgba(18, 22, 30, 0.05);
}

.lytbox-no-trans {
  transition: none !important;
}

/* Sticky behavior */
.lytbox-header.lytbox-is-sticky {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 9999;
  transform: translateY(-110%);
  transition: transform var(--lytbox-anim-ms) ease;
  will-change: transform;
}

.lytbox-header.lytbox-is-sticky.lytbox-show {
  transform: translateY(0);
}

/* OPTIONAL: add background ONLY when sticky
   To disable: comment these lines. */

.lytbox-header.lytbox-is-sticky {
  background: var(--lytbox-sticky-bg);
  backdrop-filter: blur(var(--lytbox-sticky-blur));
  box-shadow: var(--lytbox-sticky-shadow);
}

The only values to edit are the variables at the top under /* OPTIONAL: Sticky background controls */.

There are options to change the header background, the blur (makes a cool glass effect), and the box-shadow in that order.

If you are not using a background on your revealing header, then feel free to either delete or comment out the bottom part of the snippet under ‘/* OPTIONAL: add background ONLY when sticky To disable: comment these lines. */ (I suggest commenting it out to keep for later.)

Watch the Video Tutorial

Something not working? Does it feel a bit advanced. No worries! I got you covered in an easy to follow video tutorial below.

YouTube video

Join the Lytbox Newsletter

Small Subscription Form

Join the Lytbox Crew & Get Web Design Goodies.

By subscribing to the Lytbox newsletter you'll get web design updates, insights, and fun web design stuff!

Newsletter Popup Form

By subscribing, you agree to our Privacy Policy and consent to receive updates from Lytbox Academy.