Minimizing stationary header when scrolling down the page

I am working on a website that has a fixed header. The homepage displays additional content in the header when you are at the top of the page. However, I would like to hide this extra content and reduce the size of the header as users scroll down the page.

My goal is to hide the additional header content with a smooth animation while adjusting the margin of the content below it. I want the top of the content to still be visible underneath the header, transitioning to a normal scrolling behavior from there.

The code snippet below illustrates what I am trying to achieve:

var head_height = $('#header').outerHeight(true);
$('#page_content').css('margin-top', (head_height)+'px');

if($('#extra_header_content').length != 0){
    $('#header').addClass('home');
    
    var main_head_height = $("#main_header_content").outerHeight(true);
    var extra_head_height = $('#header').outerHeight(true);
    
    $(document).on("scroll", function(){
        if($(document).scrollTop() >= main_head_height){
            $("#extra_header_content").slideUp("slow");
            $('#page_content').css('margin-top', (main_head_height)+'px');
            $('#header').removeClass('home');
        }else{
            $("#extra_header_content").slideDown("slow");
            $('#page_content').css('margin-top', (extra_head_height)+'px');
            $('#header').addClass('home');
        }
    });
}else{
    $('#header').removeClass('home');
}
div{padding:0px;margin:0px;}

#header{background-color:#d33;position:fixed;top:0px;width:100%;}
.home{background-color:#3d3 !important;}

#main_header_content{height:50px;width:100%;}
#extra_header_content{height:50px;width:100%;}

#page_content{background-color:#33d;height:5000px;width:100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
  <div id="main_header_content">Main header</div>
  <div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">This should still be visible when header initially reduces</div>

Answer №1

To make the necessary adjustments in your JavaScript code, you should replace the margin reduction with padding when the page starts scrolling. Here is a suggested modification:

var head_height = $('#header').outerHeight(true);
    $('#page_content').css('margin-top', (head_height)+'px');

    if($('#extra_header_content').length != 0){
        $('#header').addClass('home');
        
        var main_head_height = $("#main_header_content").outerHeight(true);
        var extra_head_height = $('#header').outerHeight(true);
        
        $(document).on("scroll", function(){
            if($(document).scrollTop() >= main_head_height){
                $("#extra_header_content").slideUp("slow");
                // $('#page_content').css('margin-top', (main_head_height)+'px');
                $('#page_content').css(
                  {'margin-top': (main_head_height)+'px', 'padding-top': (main_head_height)+'px'}
                );
                $('#header').removeClass('home');
            }else{
                $("#extra_header_content").slideDown("slow");
                $('#page_content').css('margin-top', (extra_head_height)+'px');
                $('#header').addClass('home');
            }
        });
    }else{
        $('#header').removeClass('home');
    }
div{padding:0px;margin:0px;}

#header{background-color:#d33;position:fixed;top:0px;width:100%;}
.home{background-color:#3d3 !important;}

#main_header_content{height:50px;width:100%;}
#extra_header_content{height:50px;width:100%;}

#page_content{background-color:#33d;height:5000px;width:100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
  <div id="main_header_content">Main header</div>
  <div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">This should still be visible when header initially reduces</div>

Answer №2

If you want to achieve this effect, follow these steps:

var headerHeight = $('#header').outerHeight(true);
$('#page_content').css('margin-top', (headerHeight)+'px');

if($('#extra_header_content').length != 0){
    $('#header').addClass('home');
    
    var mainHeaderHeight = $("#main_header_content").outerHeight(true);
    var extraHeaderHeight = $('#extra_header_content').outerHeight(true);
    
    $(document).on("scroll", function() {
        const scrollTop = $(document).scrollTop();
        if (scrollTop  >= headerHeight) {
            $("#extra_header_content").css('height', 0);
            $('#page_content').css('margin-top', mainHeaderHeight);
            $('#header').removeClass('home');
        } else if (scrollTop  > 0) {
            $("#extra_header_content").css('height', extraHeaderHeight - scrollTop);
            $('#page_content').css('margin-top', headerHeight);
            $('#header').removeClass('home');
        } else {
            $("#extra_header_content").css('height', extraHeaderHeight);
            $('#page_content').css('margin-top', headerHeight);
            $('#header').addClass('home');
        }
    });
}else{
    $('#header').removeClass('home');
}
div{padding:0px;margin:0px;}

#header{background-color:#d33;position:fixed;top:0px;width:100%;}
.home{background-color:#3d3 !important;}

#main_header_content{height:100px;width:100%;}
#extra_header_content{height:100px;width:100%; overflow: hidden;}

#page_content{background-color:#33d;height:500px;width:100%;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="header">
  <div id="main_header_content">Main header</div>
  <div id="extra_header_content">Extra Header</div>
</div>
<div id="page_content">This should still be visible when header initially reduces</div>

Answer №3

I have an alternative solution that does not require JavaScript

body,html{
    padding:0;
    margin:0;
}
#main-header{
  position:fixed;
  top:0;
  left:0;
  right:0;
  height: 50px;
  background: green;
  z-index:3;
}
#extra-header{
  position:fixed;
  top:50px;
  left:0;
  right:0;
  height: 50px;
  background: lime;
  z-index: 0;
}
#content{
  margin-top:100px;
  height:2000px;
  position:relative;
  z-index:1;
  background:blue;
}
#content>div{
  height:200px;
  background: #efefef;
}

#content>div:nth-of-type(2n){
  background: red;
}
<div id="main-header">
  Main
</div>
<div id="extra-header">
Extra
</div>
<div id="content">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Answer №4

If you're looking for a smoother solution than using position sticky, I have another option with a smooth animation.

var head_height = $('#header').outerHeight(true);
    //$('#page_content').css('padding-top', (head_height)+'px');

    if ($('#extra_header_content').length != 0) {
        $('#header').addClass('home');

        var main_head_height = $("#main_header_content").outerHeight(true);
        var extra_head_height = $('#header').outerHeight(true);

        $(document).on("scroll", function() {
            if ($(document).scrollTop() >= main_head_height) {
                $('#page_content').css('padding-top', (main_head_height) + 'px');
                $("#extra_header_content").slideUp("slow");
                //$('.page_content_wrapper').addClass('scrolled');
                //$('.page_content_wrapper').css('top', (main_head_height)+'px');

                $('#header').removeClass('home');
            } else {
                $("#extra_header_content").slideDown("slow");
                $('#page_content').css('padding-top', 0);
                //$('.page_content_wrapper').css('top', 0);
                //$('#header').addClass('home');
            }
        });
    } else {
        $('#header').removeClass('home');
    }
* {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }

    div {
        padding: 0px;
        margin: 0px;
    }

    #header {
        background-color: #d33;
        position: sticky;
        top: 0px;
        width: 100%;
        z-index: 9;
    }

    .home {
        background-color: #3d3 !important;
    }

    #main_header_content {
        height: 50px;
        width: 100%;
    }

    #extra_header_content {
        height: 50px;
        width: 100%;
    }

    #page_content {
        background-color: #33d;
        height: 5000px;
        width: 100%;
    }

    .page_content_wrapper {
        position: relative;
        top: 0px;

    }

    #page_content .page_content_wrapper {
        transition: top 1s;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="header">
        <div id="main_header_content">Main header</div>
        <div id="extra_header_content">Extra Header</div>
    </div>
    <div id="page_content">
        <div class="page_content_wrapper">This should still be visible when header initially reduces</div>
    </div>
    <span class="hamBurger"></span>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The background image allows the top images and headers to overlay, while ensuring that the other images and headers remain below

As a novice in HTML and CSS, I'm facing a puzzling issue while learning at school. The first header and two images within the container where my background image is placed are overlapping the background image, creating a large gap. Strangely, the subs ...

What could be causing the loss of my <textarea> information in the $_POST submission?

I have been working on a script that takes form data and displays it in a PDF or another printable format. There is a "New Line" button at the bottom of the form, which when clicked adds a new line to the form and stores the previous line's data in an ...

Customize Your Google Maps with Checkboxes for Style Options

Trying to make dynamic changes in the style of a Google Maps using checkboxes. Some checkboxes control colors of features, while others control visibility. Having trouble figuring out how to combine different features of styles since they are not strings ...

Ajax using JQuery received a 200 status code, but did not register as a 'success'

I am attempting to utilize AJAX in order to send a query to Google Books and showcase the results on my website. My approach involves using JQuery to dispatch the request and manage the response, as demonstrated below: var userQuery = [gathered input from ...

Tips for achieving a static background image while allowing scrolling on a webpage in asp.net

I am struggling to implement this on my website. The background image needs to be fixed while the content of the webpage should scroll in asp.net <head runat="server"> <title></title> <style type="text/css"> body { backgr ...

Changing the background color of .pane and .view elements in an Ionic web application using JavaScript

Looking to modify the background-color of two css selectors, .pane and .view, that are located within the ionic.css file. Despite multiple attempts to do so using JavaScript directly in the index.html file, the changes are not reflected. The code snippet ...

Error: Attempting to access the 'HotelInfo' property of an undefined variable led to an uncaught TypeError

//initiating an AJAX request to access the API jQuery(document).ready(function() { jQuery.ajax({ url:"http://localhost:8080/activitiesWithRealData?location=%22SEA%22&startDate=%2205-14-16%22&endDate=%2205-16-16%22&a ...

Using router-links with events: A simple guide

My current issue involves passing information to another page. During testing without using routes, I was successful in passing information from one component to another. However, after implementing routes, clicking the event navigates to the other compo ...

What is the best way to avoid XSS errors when submitting a form post-AJAX test?

When a user finishes and attempts to submit a form, I want to check with the server if they are authenticated. If not, a login window should pop up which will close after successful login, keeping the form data intact for submission. The issue arises when ...

Creating a conditional statement in jQuery that will append text to a specific DIV element after a form has been successfully

I currently have a form set up that is functioning properly, but I am looking to make some changes. Instead of redirecting the user to a new page with a success message upon submitting the form, I want the success message to be displayed in a div next to t ...

Navigating with the mouse in THREE.js

Big shoutout to the amazing Stack Overflow community for always being there to help budding coders like myself! I've successfully implemented first-person camera movement in my project, allowing me to navigate forward, backward, sideways, and rotate ...

Tips for modifying the href attribute when a user clicks

Is there a way to dynamically change the value of this link <a href="/Countries/388/10">next</a> without having to refresh the page? For example, if a user clicks on the link, it should update to <a href="/Countries/388/20">next</a&g ...

JQuery - Triggering $(document).ready() before the elements are fully loaded

While working on retrieving data from a MVC3 action that returns Json with parameters and content as a string, I encountered an issue. After appending the content to a div, a JQuery event placed in a partial view's document.ready function executes bef ...

Something seems off with Chrome

I am facing a unique issue that I need help with. Unfortunately, the code is too long to post here but essentially it involves creating a menu for a website. The menu works perfectly and looks great on all browsers except for Chrome. This is unusual as Ch ...

Focusing on div elements nested within other div elements

Having some trouble making this hover effect work properly. The desired outcome is for div.sdf to hide when someone hovers over div.lol. I'm unsure of how to incorporate div.dang into the script in order to achieve this functionality. If I remove div ...

Tips for accessing and displaying JSON data using jQuery

Data in JSON format: [ { "ID":"25", "Serial":"1", "Purchase_id":"8", "Item":"23", "Unit":"1", "HSN":"84212120", "Quantity":"10", "Purchase_rate":"100", ...

Safari having trouble with cross-domain cookie functionality

I currently manage 2 different websites: 3rdpartycookiemanager.com website.com When I access website: I initiate an Ajax call to: using the following jQuery call: $.ajax({ ... type: 'POST', url: 'https://www.3rdpartycookiemanag ...

Is there a way to effectively communicate and pass state information between sibling components in React?

Is there a way to share state data between two React component functions that are both children of another component? I am new to React and have tried exporting a const from my App.jsx file with a structure containing the state properties, but when queri ...

Tips on customizing the size of tooltips within ui-select-choices

While working on a small website for a homework assignment, I have encountered an issue with styling the size of a tooltip. The tooltip is part of an attribute in a span tag under the ui-select-choices. I only want to customize the style of the tooltip w ...

Here's a new version: "Strategies for deactivating a text field in a desktop application that

I am currently using WiniumDriver to automate a desktop application. My goal is to disable a text field once a value has been entered into it. // Launch the desktop application WiniumDriver driver = null; DesktopOptions option = new DesktopOptions(); o ...