Dynamic background color sliding sticky header

After countless hours of searching online, I couldn't find anything that matched exactly what I was looking for. I attempted to create it myself, but after two days of trying, I gave up due to various reasons. So now I'm reaching out to all of you here to see if anyone can help me. Imagine a sticky header that stays fixed at the top of a website as you scroll down. My vision is that every time the header reaches a section with data-color="#2D2D2D", the background color of the header would change to match it. But not just a simple color change - I want it to transition smoothly with a background image, so as you scroll back up, the coloring changes gradually back to the previous color.

I came across an article that had a similar effect, but it only involved an image within the content.

Here's a link to my attempt on CodePen: http://codepen.io/muuvmuuv/pen/MarxYx

And here's an image to give you an idea: https://i.sstatic.net/4TYhj.jpg

Answer №1

I have created a simple example accordion based on your requirements. Please review it and let me know if I have accurately understood your instructions. Additional explanations have been included in the JavaScript code, and you can find the fiddle link at the end of this post.

Here is the basic HTML markup:

<heade id="webHeader">
    <nav>
        <ul>
            <li><a href="#">Nav item 1</a></li>
            <li><a href="#">Nav item 2</a></li>
            <li><a href="#">Nav item 3</a></li>
        </ul>
    </nav>
</heade>

<section id="section-1" data-color="#330000"></section>
<section id="section-2" data-color="#00B200"></section>
<section id="section-3" data-color="#803380"></section>

I am using SCSS for styling, but it can be easily converted to basic CSS. I have assumed that the sticky header is default, so I added padding to the body equal to the header's height.

$headerHeight: 100px;

body {
    padding-top: $headerHeight;
}

#webHeader {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: $headerHeight;
    background: #000F1F;

    nav {
        padding: 40px;
        float: right;

        li {
            display: inline-block;
            margin: 0 10px;
        }

        a {
            color: #fff;
            font-weight: 700;
            text-decoration: none;
        }
    }
}

section {
    width: 100%;
    height: 500px;
    background-color: grey;
    border-bottom: 1px dashed #fff;
}

Below is the jQuery code:

(function($){
    // cache dom elements
    var $header = $('#webHeader');
    var $window = $(window);
    var headerHeight = $header.outerHeight(true);

    var colors = [];
    var sections = [];

    $('section').each(function(){
        var $this = $(this);

        colors.push($this.data('color'));
        sections.push($this.position().top);
    });

    colors.unshift(colors[0]);

    $window.on('scroll', function(){
        var position = $window.scrollTop() + headerHeight;
        var index = inInterval(position, sections);
        var distance = position - sections[index];

        $header.attr('style', linearGradient( colors[index+1], colors[index], distance ) );

    }).trigger('scroll');

})(jQuery);

function inInterval(value, array) {
    var arrLen = array.length;
    
    array.push(array[arrLen-1]*2);

    for (var i = 0; i < arrLen+1; i++)
        if (value >= array[i] && value <= array[i+1])
            return i;
}

function linearGradient(start, end, distance) {
    var distanceStart = distance + '%';
    var distanceEnd = 100 - distance + '%';
    return "background: -webkit-gradient(linear, left top, left bottom, color-stop(0, "+ start +"), color-stop("+ distanceStart +", "+ start +"), color-stop("+ distanceStart +", "+ end +"), color-stop(100, "+ end +")";
}

You can view the working example in this fiddle. While I may not be able to make updates currently, I suggest exploring more about jQuery debounce and trying out smart scroll for optimizing scroll event performance.

I hope this meets your requirements! :)

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

Changing Float Attributes to String in Google Earth Engine

I am trying to export data from Google Earth Engine to my Google Drive. To name the file, I am using information from its data properties which results in 2019.0_1.0. However, I would like the file name to be in a different format - '2019_1'. Bel ...

Is it advisable to consolidate all of my JavaScript files into a single file?

Is it necessary for me to combine all my JavaScript files into one single file and then include that file in a folder? I currently have 10 separate JS files within a "javascript" folder - is this bad for the website, or is it okay? P.S. I am new to web de ...

Trouble displaying data with Angular 6 JSON object pipe

Having an issue with displaying tasks from a MongoDB project schema in HTML. The tasks are stored in a nested array and I want to show the task name and description. Here's the code: <div class="card-body"> {{project.taskName | json}} </ ...

The functionality of jQuery plugins does not seem to extend to content loaded via Ajax

Hello everyone, I have encountered a frustrating issue. I am currently utilizing bootstrap 2.3 along with some jQuery plugins for form styling and other purposes. However, I've noticed that when I load ajax content, particularly select elements, the ...

Error: The array's property is not defined

I am currently working on a visualization tool for sorting algorithms, but I keep encountering an error that says "Cannot read properties of undefined (reading 'map')" in line let bars = this.state.array.map((value, index) =>. You can find my ...

Script executing single run only

I'm currently working on a side menu that slides open and closed from the left with the press of a button. I have successfully implemented the CSS and HTML code, but I am facing issues with the JavaScript. The functionality works flawlessly at first: ...

Getting directions using the node-googlemaps module in node.js can be achieved by following these steps

For the past day, I've been attempting to make progress with this Node.js Google Maps directions example, but so far, no success. Every time I run it, I keep seeing ·· √ OK » 2 honored (0.848s). I've previously asked a similar question on U ...

How to implement an 8-column layout within a 12-grid bootstrap framework?

Hey guys, so I've been trying to recreate this page with Bootstrap and it's all going smoothly except for this one part. Here is the link I'm referring to: https://i.sstatic.net/0mXMm.png I have 2 questions: Which HTML element should I us ...

Styling emails in an inbox with CSS

I am developing an email application and aiming for the inbox layout to be similar to that of Mac Mail. The emails are fetched from a database using ajax, outputting to XML. I then loop through the entries to extract the necessary elements. My concern li ...

What's the reason the element inside the <div> is not displayed when a value is selected in the dropdown box?

I am perplexed as to why the element inside the does not appear when a value is selected in the drop down box. However, it works perfectly fine in JSFiddle: JSFiddle Below is my HTML code and Jquery script that functions properly in my own system: <t ...

Ensure that you wait for all asynchronous $http requests to finish in AngularJS before continuing

I am facing a challenge with a page that generates a varying number of $http requests based on the length of a certain variable. I aim to update the scope with the data only after all requests have been completed. Without relying on jQuery for this project ...

CompleteCalendar JSON string with quoted attributes

Issue Resolved (refer to N69S's comment) (Using Laravel) I am trying to display my events in a calendar view, but I am encountering an issue when parsing my JSON data. The code snippet returned is: "start":"2018-10-01 10:00:00","end":"2018-10-01 ...

Challenges with nesting radio button groups in jQuery validation

Trying to implement a custom validation method for a group of radio buttons in v1.9 of the jQuery validate plugin. Despite this article, it is indeed feasible to have radio buttons with the same name attribute, as long as different class rules are applied ...

Passing JSON data from an ASP.NET controller to a view

My issue arises when a web page is loaded and triggers a controller action to retrieve data based on user selection. I am trying to return this data as a JSON object, but it appears as a single string within the HTML page. The basic structure of the contro ...

Text that is curving around a D3.js pie chart

I am currently working on creating a 3D-Js chart and I would like the pie text to wrap around the pie itself. This is the exact effect that I am trying to achieve: https://i.sstatic.net/YOLdo.png I am facing two main issues: I am currently printi ...

Utilizing JavaScript in AJAX Responses

Can I include JavaScript in an AJAX response and run it, or should I only use JSON or plain HTML for a more elegant solution? I'm trying to figure out the best way to handle AJAX requests that involve inserting HTML or running JavaScript based on user ...

I encounter an error when I link or embed a middleware within another

I am facing an issue while trying to implement a nested middleware within another middleware. Upon calling the nested middleware, I encounter the following error: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client Below ...

The CSS content spills beyond the edge of the screen

I am facing an issue with aligning my content in the center as it is currently shifting to the right side and going off the screen. Below is the code snippet I am working with: <?php /* Template Name: About Us */ $aboutheading = get_field('abou ...

What could be causing the event listener to not be triggered?

I'm having an issue with a simple code that is supposed to display an alert box when a hyperlink is clicked, but it's not working. I believe the script is not being called. Can someone help me figure out what's wrong? Here is the HTML code: ...

How to retrieve data from a nested object within a JSON array using JavaScript

When I use Logger.log(response.data.phone), the following data is displayed in my log: [{label=work, primary=true, value=5558675309}, {label=work, value=6108287680, primary=false}, {value=6105516373, label=work, primary=false}] My goal is to have the two ...