Skip to Main Content

Create a Sticky Header in Elementor: A Comprehensive Guide

Elevate Your WordPress Site with a Dynamic Sticky Header Using Elementor

Master the art of creating a captivating sticky header without relying on third-party plugins. This comprehensive tutorial will guide you through crafting a transparent sticky header, adjusting its color on scroll, shrinking its size, and dynamically modifying the navigation menu, button, search icon, and site logo based on user interaction. Elevate your WordPress site's user experience and enhance its visual appeal with these practical techniques.

A sticky header is a crucial element for enhancing user navigation and providing a consistent brand experience on a website. Elementor, a popular WordPress page builder, offers a seamless way to create and customize sticky headers. This guide will walk you through the process of creating a sticky header in Elementor, covering various aspects such as transparent headers, shrinking headers, and logo swapping.

I have created a demo link where you can experience the sticky header in action.

Elementor Sticky header template on Gumroad
Elementor Sticky header Template

If you like to import this exact template on your projects, you can purchase it from my store at 10USD.

Basic requirements:

  1. Elementor Advanced license is required for full functionality.
    Elementor Theme Builder Banner ads
  2. Enable Flexbox Container in Elementor features.
    Activate Flexbox Container experiments
  3. You have to manually implement Media Queries for mobile responsiveness for yourself (quite easy) or If you buy the template, you don’t have to worry about it.
  4. Optional: Activate the Default to New Theme Builder Builder.
    Switch to New Theme Builder
  5. Consider using Autoprefixer for vendor browser prefixes.

Step 1: Create the Header Template

  1. Access Theme Builder: Navigate to Appearance > Theme Builder in your WordPress dashboard.To access Theme Builder, navigate to temeplates and click the theme builder
    After you click the Theme Builder, you will see the Templates parts, you have created.
    Picture showing all the templates from Elementor's Theme Builder
  2. Add New Header: Click the “Add New” button (+) and select “Header.”
    Click the Header plus icon to create a header template
    After you choose the header template, it will lead to the Elementor’s Block. From there, you can choose the prebuilt templates or Elementor’s block, create the template from scratch, or Buy it from my Gumroad store.
    Choose the header that has the sub menu
  3. Change the HTML tag as a Header for better semantics
    Change the HTML tag to header under general settings
    After changing HTML tag to header for better semantic
  4. Structure and Widgets: Choose “Row” as the structure and drag and drop the desired widgets, such as the Site Logo, WordPress Menu, and Search Icon, into the container and start configuring it to your requirement.– Select the structure
    Choose row as structure, so the content flows horizontally
    -Place all the widgets inside the container/ wrapper.
    Drag and drop all the widgets and stack them horizontally
    – Change the items direction to a row ( so it stacks all the items horizontally), Justify Content to space-between (to distribute items in line evenly), Align Items to the center to place all the items in the middle,  and Gaps to 20px. Set the Justify Content of the main container to Space Between so its the stretch the items to the end and Align items to center so the content in between will align to the center
    It will look something like this after you apply all the settings.
    This will look like after the settings is applied
  5. CSS Classes: Assign unique CSS classes to the container and widgets for better control and styling. If you do not know how to assign CSS classes, follow the Official Elementor Tutorials –  How To Use Selector In The Custom CSS Tab.

    I have added the parent__container and sticky-header-container as my CSS classes.

    parent_container as a global variable and sticky-header-container for styling header.
    Give 2 CSS classes to the container

Step 2: Create a Transparent sticky Header

  1. Background Color: By default, Elementor sets the background color to transparent, leaving the header transparent. ( In this demo, I use negative margins on top to push the header section) By default, Elementor set the background color to default which is transparent
    Sometimes a theme includes background color by default, if you have this issue you can use the  Chrome Dev tools’s inspect elements and you will find the CSS responsible and remove it in theme customizer settings or overwrite it with !important CSS rule which is not recommended.
  2. Sticky Settings: Under Motion Effects, set the Sticky option to “Top” and adjust the Effects Offset to your preference.Under motion effects, set the sticky to top (so it sticky to the top of the page) and set the effects offset to 100

Step 3: Change Sticky Header Color on Scroll

  1. Change Color & add Box Shadow: When the user scrolls down, change the background color of the sticky header from transparent to white and add a box shadow to the container for a more defined look.
If you’re applying a backdrop filter to the sticky header just make sure you remove the background color & Box-shadow CSS rule.
    
/*
* Define your own background color for default and sticky
* CSS Blend-mode rule is not included
*/

/*
* Elementor Sticky Header change color on Scroll
* Change the color from transparent to white
*/
.parent__container {
  --site-transition: 350ms linear;
  --bg-color__before: #00000000;
  --bg-color__after: #fff;
  --max__height: 140px;
  --min__height: 100px;
  --min-height: var(--max__height);
  
  background-color: var(--bg-color__before);
}

.sticky-header-container {
  transition: 
    background-color var(--site-transition),
    backgrop-filter var(--site-transition),
    box-shadow var(--site-transition);
}

.elementor-sticky--effects.sticky-header-container {
  --bg-color__before: var(--bg-color__after);
  box-shadow: hsl(0deg 0% 0% / 14%) 0 2px 40px;

  /* If you're using backdrop filter CSS properties, remove background color CSS properties and box-shadow CSS rule
        backdrop-filter: blur(10px);*/
  /*  just enabled one of them
           mix-blend-mode: difference;
           mix-blend-mode: normal;
           mix-blend-mode: multiply;
      */
}

    

Step 4: Shrink the Header properties

Shrink Sticky Header 

CSS Adjustments: Use CSS to shrink the height of the sticky header, logo, and navigation menu when the user scrolls down.

    
/*
* Elementor Sticky Header change color on Scroll &
* Shrink sticky Header
*/

.elementor-sticky--effects.sticky-header-container {
  --max__height: var(--min__height);
  --bg-color__before: var(--bg-color__after);

  box-shadow: hsl(0deg 0% 0% / 14%) 0 2px 40px;

  /*
   * backdrop-filter: blur(10px);
   * -webkit-box-shadow: hsl(0deg 0% 0% / 14%) 0 2px 40px;
* */
}

    

Apply CSS to reduce the width of the site logo when the sticky header shrinks.

    

/*
* Site Logo widget
* Using transform CSS property is much better than width properties to scale in terms of performance
*/
.site--logo{
    transform: scale(1);
    transform-origin: center;
    transition:
        transform var(--site-transition),
        transform-origin var(--site-transition);
}


.elementor-sticky--effects .site--logo{
      transform: scale(.9);
}

    

Change Button Color & Search Icon:

Modify the button & search color based on the user’s scroll position

    
/*Search icon*/
.search-icon svg.e-font-icon-svg,
.search-icon i.e-font-icon-svg{
    fill: #000!important;
    color: #000;
    transition: fill var(--site-transition);
}

/*Search icon when sticky*/
.elementor-sticky--effects .search-icon svg.e-font-icon-svg,
.elementor-sticky--effects .search-icon i.e-font-icon-svg{
    fill: #fff!important;
    color: #fff;
}

    
    
/*
*   Button
*/

.elementor-button{
    background: var(--_button, #000)
}


.sticky-btn .elementor-button{
    font-weight: 600;
    border-radius:0;
    border: none;
    transition: background-color var(--site-transition);
}


.elementor-sticky--effects .sticky-btn .elementor-button{
  --_button: #fff;
}

/*
*   Button Text
*/

.sticky-btn .elementor-button-text{
    color: #fff;
    transition: color var(--site-transition);
}


.elementor-sticky--effects .sticky-btn .elementor-button-text{
    color: #000;
}
    

Reduce the WordPress Menu’s font size style and change color: 

    
.elementor-nav-menu--main .elementor-item{
    color: var(--_nav__before, #000);
}

/* 
* Navigation elementor-nav-menu--main
*/

.site-nav .elementor-nav-menu--main .elementor-item{
/*
* define your color
*/
    --_nav__before: #000;
    --_fw: 600;

    font-weight: var(--_fw);
    font-size: clamp(1rem, 0.8182rem + 0.6061vw, 1.25rem);
    transition:
        color var(--site-transition),
        font-weight var(--site-transition),
        font-size var(--site-transition);
}
.site-nav  .elementor-nav-menu--main .elementor-item:hover{
    color: #000;
}


.elementor-sticky--effects .site-nav .elementor-nav-menu--main .elementor-item{
    font-size: clamp(1rem, 0.8636rem + 0.4545vw, 1.1875rem);
    --_nav__before: #fff;
    --_fw: 800;
}
    

Style the Hamburger menu when sticky

    
/* 
* For Hamburger menu
*/

/* Styling for the hamburger menu toggle button */
.site-nav .elementor-menu-toggle{
    background-color: #000;
    -webkit-transition: background-color var(--site-transition);
    -o-transition: background-color var(--site-transition);
    transition: background-color var(--site-transition);
    border-radius: 0;
}

/* 
* Hamburger Menu's svg
*/

/* Styling for the hamburger menu icon */
.site-nav .elementor-menu-toggle .e-font-icon-svg{
    fill: #000;
    color: #000;
    -webkit-transition: 
        fill var(--site-transition),
        color var(--site-transition);
    -o-transition: 
        fill var(--site-transition),
        color var(--site-transition);
    transition: 
        fill var(--site-transition),
        color var(--site-transition);
}

/* 
* This style change
*/

/* Styling changes for the hamburger menu in sticky mode */
.elementor-sticky--effects .site-nav .elementor-menu-toggle{
    background-color: #fff;
}

.elementor-sticky--effects  .site-nav .elementor-menu-toggle .e-font-icon-svg,
.elementor-sticky--effects .site-nav .elementor-menu-toggle .e-font-icon-svg{
    fill: #fff;
    color: #fff;
}

/* 
* Styling for the sub-arrow icon in the navigation menu 
*/
.elementor-nav-menu .sub-arrow .e-font-icon-svg{
    fill: var(--_nav__before);
    color: var(--_nav__before);
}

/* Styling changes for the sub-arrow icon in sticky mode */
.elementor-sticky--effects .elementor-nav-menu .sub-arrow .e-font-icon-svg,
.elementor-sticky--effects .elementor-nav-menu .sub-arrow .e-font-icon-svg{
    --_nav__before: #fff;
    fill: var(--_nav__before);
    color: var(--_nav__before);
}


    

Dynamic Logo on Scroll

Utilize CSS techniques to swap the logo with a different one when the sticky header appears.

Let me tell you one thing straight, there are lots of tutorials out there that teach you how to use CSS content property to swap the logo. But the problem I found is that it, the logo was unclickable when changed. So please don’t follow the tutorials that use content CSS property.
You will need to change the structure of the layout if you want to achieve a dynamic Logo on scroll.
  1. Add a new container widget Drag and Drop container widget next to logo and WordPress Menu widget
  2. Reposition the old Logo (interact with before and after)
Reposition your site logo into container
Before
Result after the logo is drag inside the new container
after
  1. Add a new image widget inside the container (created in 2)
    Stack site logo and image widget in a container
  2. Apply a unique CSS class to the new image and set the position Providing CSS class to a new image widget
    Click the new image widget’s handle > advanced under the layout tab > set the position to absolute so the image is removed from the DOM and it will stack with the site logo widget.

    Image remove from flow due to absolute positining

  3. Apply custom CSS to change the logo on scroll.
    
/* Original logo styles */
.site--logo {
    transform: scaleX(1); /* Initial scale */
    transform-origin: center; /* Set the transform origin to the center */
    transition:
        opacity var(--site-transition), /* Opacity transition */
        transform var(--site-transition); /* Transform transition */
}

/* Sticky effect for the logo when scrolling */
.elementor-sticky--effects .site--logo {
    transform: scale(.95); /* Reduce scale on sticky */
}

/* Sticky effect for the red logo when scrolling */
.elementor-sticky--effects .site--logo-red {
    opacity: 1; /* Make red logo visible on sticky */
    transform: scale(.95); /* Reduce scale on sticky */
}

/* Default styles for the logo */
.site--logo {
    opacity: 1; /* Make the logo fully visible by default */
}

/* Default styles for the red logo */
.site--logo-red {
    opacity: 0; /* Make the red logo fully transparent by default */
}

/* Additional effect for the logo when scrolling */
.elementor-sticky--effects .site--logo {
    opacity: 0; /* Make the logo fully transparent on sticky */
}

/* Additional effect for the red logo when scrolling */
.elementor-sticky--effects .site--logo-red {
    opacity: 1; /* Make the red logo fully visible on sticky */
    transform: scale(.95); /* Reduce scale on sticky */
}

    
    
/*
* Define your own background color for default and sticky.
* CSS Blend-mode rule is not included.
*/

/*
* Elementor Sticky Header: Change color on scroll.
* Change the color from transparent to white.
*/
.parent__container {
    --site-transition: 350ms linear;
    --bg-color__before: #00000000;
    --bg-color__after: #fff;
    --max__height: 140px;
    --min__height: 100px;

    --min-height: var(--max__height);
    background: var(--bg-color__before);
}

.sticky-header-container {
    transition:
        background-color var(--site-transition),
        backdrop-filter var(--site-transition),
        box-shadow var(--site-transition);
}

.elementor-sticky--effects.sticky-header-container {
    --bg-color__before:  var(--bg-color__after);
    box-shadow: hsl(0deg 0% 0% / 14%) 0 2px 40px;

    /* If you're using backdrop filter CSS properties, remove background color CSS properties and box-shadow CSS rule
       backdrop-filter: blur(10px);*/
    /*  just enable one of them
       mix-blend-mode: difference;
       mix-blend-mode: normal;
       mix-blend-mode: multiply;
    */
}

/*
* Elementor Sticky Header: Change color on scroll & Shrink sticky header.
*/
.elementor-sticky--effects.sticky-header-container {
    --max__height: var(--min__height);
    --bg-color__before: var(--bg-color__after);
    box-shadow: hsl(0deg 0% 0% / 14%) 0 2px 40px;

    /*
    * backdrop-filter: blur(10px);
    * -webkit-box-shadow: hsl(0deg 0% 0% / 14%) 0 2px 40px;
    * */
}

/*
* Using the transform CSS property is much better than width properties to scale in terms of performance.
*/
.site--logo {
    transform: scale(1);
    transform-origin: center;
    transition:
        transform var(--site-transition),
        transform-origin var(--site-transition);
}

.elementor-sticky--effects .site--logo {
    transform: scale(.9);
}

/*
* WordPress Navigation.
*/
.elementor-nav-menu--main .elementor-item {
    color: var(--_nav__before, #000);
}

.site-nav .elementor-nav-menu--main .elementor-item {
    /*
    * Define your color.
    */
    --_nav__before: #000;
    --_fw: 600;

    font-weight: var(--_fw);
    font-size: clamp(1rem, 0.8182rem + 0.6061vw, 1.25rem);
    transition:
        color var(--site-transition),
        font-weight var(--site-transition),
        font-size var(--site-transition);
}

.site-nav .elementor-nav-menu--main .elementor-item:hover {
    color: #000;
}

.elementor-sticky--effects .site-nav .elementor-nav-menu--main .elementor-item {
    font-size: clamp(1rem, 0.8636rem + 0.4545vw, 1.1875rem);
    --_nav__before: #fff;
    --_fw: 800;
}

/* For Hamburger menu */
/* Styling for the hamburger menu toggle button */
.site-nav .elementor-menu-toggle {
    background-color: #000;
    -webkit-transition: background-color var(--site-transition);
    -o-transition: background-color var(--site-transition);
    transition: background-color var(--site-transition);
    border-radius: 0;
}

/* Hamburger Menu's svg */
/* Styling for the hamburger menu icon */
.site-nav .elementor-menu-toggle .e-font-icon-svg {
    fill: #000;
    color: #000;
    -webkit-transition:
        fill var(--site-transition),
        color var(--site-transition);
    -o-transition:
        fill var(--site-transition),
        color var(--site-transition);
    transition:
        fill var(--site-transition),
        color var(--site-transition);
}

/* Styling changes for the hamburger menu in sticky mode */
.elementor-sticky--effects .site-nav .elementor-menu-toggle {
    background-color: #fff;
}

.elementor-sticky--effects  .site-nav .elementor-menu-toggle .e-font-icon-svg,
.elementor-sticky--effects .site-nav .elementor-menu-toggle .e-font-icon-svg {
    fill: #fff;
    color: #fff;
}

/* Styling for the sub-arrow icon in the navigation menu */
.elementor-nav-menu .sub-arrow .e-font-icon-svg {
    fill: var(--_nav__before);
    color: var(--_nav__before);
}

/* Styling changes for the sub-arrow icon in sticky mode */
.elementor-sticky--effects .elementor-nav-menu .sub-arrow .e-font-icon-svg,
.elementor-sticky--effects .elementor-nav-menu .sub-arrow .e-font-icon-svg {
    --_nav__before: #fff;
    fill: var(--_nav__before);
    color: var(--_nav__before);
}

/*
* Button
*/
.elementor-button {
    background: var(--_button, #000);
}

.sticky-btn .elementor-button {
    font-weight: 600;
    border-radius: 0;
    border: none;
    transition: background-color var(--site-transition);
}

.elementor-sticky--effects .sticky-btn .elementor-button {
    --_button: #fff;
}

/*
* Button Text
*/
.sticky-btn .elementor-button-text {
    color: #fff;
    transition: color var(--site-transition);
}

.elementor-sticky--effects .sticky-btn .elementor-button-text {
    color: #000;
}

/* Search icon */
.search-icon svg.e-font-icon-svg,
.search-icon i.e-font-icon-svg {
    fill: #000!important;
    color: #000;
    transition: fill var(--site-transition);
}

/* Search icon when sticky */
.elementor-sticky--effects .search-icon svg.e-font-icon-svg,
.elementor-sticky--effects .search-icon i.e-font-icon-svg {
    fill: #fff!important;
    color: #fff;
}

/*
* Logo Swap related
*/
.site--logo {
    transform: scaleX(1);
    transform-origin: center;
    transition:
        opacity var(--site-transition),
        transform var(--site-transition);
}

.elementor-sticky--effects .site--logo {
    transform: scale(.95);
}

.elementor-sticky--effects .site--logo-red {
    opacity: 1;
    transform: scale(.95);
}

.site--logo {
    opacity: 1;
}

.site--logo-red {
    opacity: 0;
}

.elementor-sticky--effects .site--logo {
    opacity: 0;
}

.elementor-sticky--effects .site--logo-red {
    opacity: 1;
    transform: scale(.95);
}

    

Conclusion:

Creating a sticky header in Elementor is a straightforward process with the right guidance. By following these steps and exploring advanced options, you can enhance your website’s navigation and user experience.

Picture of Kishorchand wearing Elementor Blue Shirt that I got it from wining Elementor Header competition

Thangjam Kishorchand Singh

Passionate about web performance, I specialize in assisting individuals and businesses in creating high-speed websites to elevate user experience, improve search rankings, and minimize bounce rates. I continually explore cutting-edge tools and techniques to optimize website performance, sharing insights through informative articles, engaging presentations, and valuable content.

Let's connect on my social media channels to engage in discussions about website speed and transform your site into a lightning-fast online experience.

Follow or chat with me -

Contact Me

87 Responses

  1. Hey! Thanks dor the tutorial. The blend mode does not seem to be working at all. My heading has some text and a nav menu, both in white, with a transparent background, and I wanted to include a Difference blend mode so when you scroll down you get an effect similar to the footer in this website: https://yambo-studio.com/

    Do you have any idea why it might not be working?

  2. Hi again :), the code :root{
    –transition: 300ms ease-in;
    } and the rest of it, is this for desktop view? because I could not see any changes applied? Thanks again!

    1. /*
      * This rest of the CSS is applied to Mobile only, it will not affect on Desktop but might affect on Tablet view
      * :root is the Custom Properties or CSS variables https://developer.mozilla.org/en-US/docs/Web/CSS/–*
      * If you want to remove it, you can

      :root{
      –transition: 300ms ease-in;
      }
      */

      .site–nav .elementor-menu-toggle{
      background-color: #502EFF;
      /* Instead of CSS variable – transition: background-color var(–transition);
      */
      transition: background-color 300ms ease-in;
      }

      .elementor-sticky–effects .site–nav .elementor-menu-toggle{
      background-color: pink
      }

      1. So this code is enough Kishorchand If I get you right? 🙂 (only want the hamburger and close on mobile and tablet to change color, nothing else) ? However thanks again

        * For Hamburger icons
        */

        .eicon-menu-bar:before{
        color:red;

        }
        /*
        * When Sticky
        */

        .elementor-sticky–effects .eicon-menu-bar:before{
        color:purple
        }

        /*
        * For Close Icons
        */

        .elementor-menu-toggle.elementor-active i:before{
        color:red;
        }

        /*
        * When Sticky
        */
        .elementor-sticky–effects .elementor-menu-toggle.elementor-active i:before{
        color:green;

  3. If you don’t want to change the color of the ‘close’ and ‘hamburger’ icons, you can remove it
    /*
    * Remove the code below
    * Both the CSS is meant for ‘close’ and ‘hamburger’ icons.
    */

    /*
    * For Hamburger icons
    */

    .eicon-menu-bar:before{
    color:red;

    }
    /*
    * When Sticky
    */

    .elementor-sticky–effects .eicon-menu-bar:before{
    color:purple
    }

    /*
    * For Close Icons
    */

    .elementor-menu-toggle.elementor-active i:before{
    color:red;
    }

    /*
    * When Sticky
    */
    .elementor-sticky–effects .elementor-menu-toggle.elementor-active i:before{
    color:green;

  4. Sure use this CSS

    :root{
    –transition: 300ms ease-in;
    }

    #1 Make you disable toggle Button Background color and Color, if you want to keep it, you have to add !important to overwrite
    :root{

    }
    .site–nav .elementor-menu-toggle{
    background-color: #502EFF;
    transition: background-color var(–transition);
    }

    .elementor-sticky–effects .site–nav .elementor-menu-toggle{
    background-color: pink
    }

    /*
    * For Hamburger icons
    */

    .eicon-menu-bar:before{
    color:red;

    }
    /*
    * When Sticky
    */

    .elementor-sticky–effects .eicon-menu-bar:before{
    color:purple
    }

    /*
    * For Close Icons
    */

    .elementor-menu-toggle.elementor-active i:before{
    color:red;
    }

    /*
    * When Sticky
    */
    .elementor-sticky–effects .elementor-menu-toggle.elementor-active i:before{
    color:green;
    }

  5. Hello! Im trying the logo change, and everything works but the after logo’s positioning is off. It appears to the right of where the before logo was.
    How do I fix this?

    1. Thank you so much for reporting. I forgot to add left: 0 that is why your logo position is off.
      Here the CSS, I have modified and the HTML https://gist.github.com/Kishorchandth/e7cdfb3f9547e32efaff23804eaa5f64

      .logo–wrapper{
      position: relative;
      }

      .before, .after{
      -webkit-transition: opacity 300ms ease-in-out;
      -o-transition: opacity 300ms ease-in-out;
      transition: opacity 300ms ease-in-out;
      }

      /* Second image opacity is set to 0*/
      .after{
      position: absolute;
      left:0;
      opacity: 0;
      pointer-events: none;

      }

      .elementor-sticky–effects .after {
      opacity: 1;
      pointer-events: auto;
      }

      .elementor-sticky–effects .before{
      opacity:0;
      pointer-events: none;
      }

Leave a Reply

Your email address will not be published. Required fields are marked *