Implement a transition animation effect on the navigation bar

I've implemented a sticky navbar that changes color on scroll, but the transition feels abrupt. Here's the code snippet:

// jshint esversion: 6
window.onscroll = function() { myFunction(); };

let navbar = document.getElementsByClassName("navigation")[0];
let sticky = navbar.offsetTop;

function myFunction() {
  if (window.pageYOffset >= sticky) {
       navbar.classList.add("sticky");
  } else {
       navbar.classList.remove("sticky");
  }
}
/* CSS styles */
....(CSS content)
<!DOCTYPE html>
<html lang="en">
....(HTML content)
</html>

I'm looking to add a smoother transition effect when the navbar sticks to the top using CSS transitions. Any suggestions or help would be greatly appreciated.

Answer №1

To create a smoother background change effect in the navigation class, simply add the property transition: background duration;.

// jshint esversion: 6
window.onscroll = function() { myFunction(); };

let navbar = document.getElementsByClassName("navigation")[0];
let sticky = navbar.offsetTop;

function myFunction() {
  if (window.pageYOffset >= sticky) {
       navbar.classList.add("sticky");
  } else {
       navbar.classList.remove("sticky");
  }
}
/* CSS code for basic reset and reusable content */
...
<!DOCTYPE html>
<html lang="en">
<head>
     <!-- Required meta tags -->
     ...

     <title>Arun Bohra - Design Business Solutions</title>
</head>
<body>

     <header>
          ...
     </header>

     <div class="navigation">
          ...
     </div>

     <section class="about-section">
          ...
     </section>

     <script src="js/index.js" charset="utf-8"></script>
</body>


</html>

Answer №2

If you're looking to enhance your navbar, consider utilizing max-height along with the desired transition. Here's a suggestion:

// jshint esversion: 6
window.onscroll = function() { myFunction(); };

let navbar = document.getElementsByClassName("navigation")[0];
let sticky = navbar.offsetTop;

function myFunction() {
  if (window.pageYOffset >= sticky) {
       navbar.classList.add("sticky");

       // add the ready class after a tiny delay
       setTimeout(() => {
           navbar.classList.add("ready");
       }, 100);
  } else {
       navbar.classList.remove("sticky");
       
       // don't forget to also remove ready class
       navbar.classList.remove("ready");
  }
}
/* ------------------------------------- */
/* BASIC RESET */
/* ------------------------------------- */
* {
     margin: 0;
     padding: 0;
     box-sizing: border-box;
}

html { font-size: 62.5%; }

body {
     box-sizing: inherit;
     color: #777;
     background-color: #fff;
     font-family: 'Roboto', sans-serif;
     font-size: 1.8rem;
     font-weight: 400;
     line-height: 1.5;
}

.clearfix {zoom: 1;}
.clearfix:after {
    content: '.';
    clear: both;
    display: block;
    height: 0;
    visibility: hidden;
}

/* Reusable Content */

/* HTML contents */

h1, h2.header-heading, h2 {
     margin: 0;
     text-transform: uppercase;
}

h1 {
     font-size: 4.5rem;
     color: #fff;
     letter-spacing: .4rem;
     word-spacing: .5rem;
     font-weight: 300;
}

h2 {
     font-size: 3.5rem;
}

/* Links */

a {
     text-decoration: none;
     display: inline-block;
}

/* Buttons */

.btn {
     border: 1px solid #fff;
     border-radius: .3rem;
     font-size: 1.6rem;
     padding: 1.2rem 3.5rem;
     text-transform: uppercase;
     color: #fff;
     background-color: transparent;
     font-weight: bold;
     letter-spacing: .3rem;
     transition: all .2s;
}

.btn:hover {
     background-color: #fff;
     color: #000;
}

/* Utility classes */

.u-margin-top-small {
     margin-top: 2.5rem;
}

.u-text-align-center {
     text-align: center;
}

.u-inline-block {
     display: inline-block;
}

/* Header Section */

header {
     background-color: #353353;
     height: 98vh;
}

.hero-text-box {
     position: absolute;
     top: 40%;
     left: 50%;
     transform: translate(-50%, -50%);
}

h2.header-heading {
     font-size: 3.5rem;
     margin-top: 2rem;
     color: #F9F871;
     font-weight: 400;
}

/* Navbar Styling */

.navigation {
     position: relative;
     padding: 1rem;
     border-bottom: .5px solid #777;
}

.logo-box {
     float: left;
}

.logo {
     color: #353353;
     text-transform: uppercase;
     font-weight: 700;
     font-size: 4rem;
     letter-spacing: .4rem;
     margin-left: 5rem;
}

nav {
     padding: 1rem;
}

.navbar {
     float: right;
     list-style: none;
     margin-right: 10rem;
     margin-top: 1.5rem;
}

.navbar li {
     display: inline-block;
}

.navbar li a {
     margin: 0 1rem;
     padding: .2rem .6rem;
     color: black;
     text-transform: uppercase;
     border-bottom: 2px solid transparent;
     transition: all .3s;
}

.navbar li a:hover {
     border-bottom: 2px solid #F9F871;
     transition: all .3s;
}

/* Sticky Navbar Effect */

.sticky {
     position: fixed;
     background-color: #353353;
     top: 0;
     width: 100%;
     max-height: 0px; /* set max-height as 0 */
     transition: height 1500ms linear; /* define your max-height transition */
}
.sticky.ready {
     max-height: 9999px; /* when "ready" the sticky navbar transitions to have a height */
}

.sticky .navbar-lists {
     color: #fff;
}

.sticky .logo {
     color: #fff;
}
<!DOCTYPE html>
<html lang="en">
<head>
     <!-- Required meta tags -->
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <meta http-equiv="X-UA-Compatible" content="ie=edge">

     <!-- Rubik fonts link -->
     <link rel="preconnect" href="https://fonts.gstatic.com">
     <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@100;300;400;700&display=swap" rel="stylesheet">

     <!-- CSS links -->
     <link rel="stylesheet" href="css/normalize.css">
     <link rel="stylesheet" href="css/styles.css">

     <title>Arun Bohra - Design Business Solutions</title>
</head>
<body>

     <header>
          <div class="hero-text-box u-text-align-center u-inline-block">
               <h1>Hello my name is Arun</h1>
               <h2 class="header-heading u-margin-top-small">I'm a front-end developer</h2>
               <a href="#" class="btn u-margin-top-small u-inline-block">Who am I</a>
          </div>
     </header>

     <div class="navigation">
          <nav class="clearfix">
               <div class="logo-box">
                    <a href="#" class="logo">
                         Arun
                    </a>
               </div>

               <ul class="navbar">
                    <li><a href="#" class="navbar-lists">Home</a></li>
                    <li><a href="#" class="navbar-lists">About me</a></li>
                    <li><a href="#" class="navbar-lists">Skills</a></li>
                    <li><a href="#" class="navbar-lists">Projects</a></li>
                    <li><a href="#" class="navbar-lists">Contact</a></li>
               </ul>
          </nav>
     </div>

     <section class="about-section">
          <h2>Who am I</h2>
          <h2>Who am I</h2>
          <h2>Who am I</h2>
         <!-- Display more "Who am I" sections here for demonstration purposes -->

     </section>

     <script src="js/index.js" charset="utf-8"></script>
</body>


</html>

You can adjust the setTimeout delay and the transition duration for a smoother effect.

Answer №3

I made enhancements to the header and navigation by utilizing flexbox and transitions in the code, resulting in a smoother transition effect.

// jshint esversion: 6
window.onscroll = function() { myFunction(); };

let navbar = document.getElementsByClassName("navigation")[0];
let sticky = navbar.offsetTop;

function myFunction() {
  if (window.pageYOffset >= sticky) {
       navbar.classList.add("sticky");
  } else {
       navbar.classList.remove("sticky");
  }
}
/* ------------------------------------- */
/* BASIC RESET */
/* ------------------------------------- */
* {
     margin: 0;
     padding: 0;
     box-sizing: border-box;
}

html { font-size: 62.5%; }

body {
     box-sizing: inherit;
     color: #777;
     background-color: #fff;
     font-family: 'Roboto', sans-serif;
     font-size: 1.8rem;
     font-weight: 400;
     line-height: 1.5;
}

.clearfix {zoom: 1;}
.clearfix:after {
    content: '.';
    clear: both;
    display: block;
    height: 0;
    visibility: hidden;
}

/* ------------------------------------- */
/* THE REUSABLE CONTENT */
/* ------------------------------------- */

/* HTML contents */

h1, h2.header-heading, h2 {
     margin: 0;
     text-transform: uppercase;
}

h1 {
     font-size: 4.5rem;
     color: #fff;
     letter-spacing: .4rem;
     word-spacing: .5rem;
     font-weight: 300;
}

h2 {
     font-size: 3.5rem;
}

/* Links */

a {
     text-decoration: none;
     display: inline-block;
}

/* Buttons */

.btn {
     border: 1px solid #fff;
     border-radius: .3rem;
     font-size: 1.6rem;
     padding: 1.2rem 3.5rem;
     text-transform: uppercase;
     color: #fff;
     background-color: transparent;
     font-weight: bold;
     letter-spacing: .3rem;
     transition: all .2s;
}

.btn:hover {
     background-color: #fff;
     color: #000;
}

/* Utility classes */

.u-margin-top-small {
     margin-top: 2.5rem;
}

.u-text-align-center {
     text-align: center;
}

.u-inline-block {
     display: inline-block;
}

/* ------------------------------------- */
/* THE HEADER SECTION */
/* ------------------------------------- */

header {
     background-color: #353353;
     height: 98vh;
}

.hero-text-box {
     position: absolute;
     top: 40%;
     left: 50%;
     transform: translate(-50%, -50%);
}

h2.header-heading {
     font-size: 3.5rem;
     margin-top: 2rem;
     color: #F9F871;
     font-weight: 400;
}

/* ------------------------------------- */
/* THE NAVBAR */
/* ------------------------------------- */

.navigation {
  display: flex;
  justify-content: center;
  align-items: center;
  position: relative;
  border-bottom: .5px solid #777;
  box-sizing: border-box;
  height: 80px;
  transition: all .5s;
  padding: 1rem;
}

.logo-box {
     float: left;
}

.logo {
     color: #353353;
     text-transform: uppercase;
     font-weight: 700;
     font-size: 4rem;
     letter-spacing: .4rem;
}

nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-sizing: border-box;
  width: 100%;
  height: 50px;
}

.navbar {
     float: right;
     list-style: none;
}

.navbar li {
     display: inline-block;
}

.navbar li a {
     margin: 0 1rem;
     padding: .2rem .6rem;
     color: black;
     text-transform: uppercase;
     border-bottom: 2px solid transparent;
     transition: all .3s;
}

.navbar li a:hover {
     border-bottom: 2px solid #F9F871;
     transition: all .3s;
}

/* The sticky navbar */

.sticky {
  position: fixed;
  background-color: #353353;
  top: 0;
  width: 100%;
  height: 50px;
  padding: 0rem 1rem;
}

.sticky .navbar-lists {
     color: #fff;
}

.sticky .logo {
     color: #fff;
}
<!DOCTYPE html>
<html lang="en">
...

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 issue with GatsbyJS and Contentful: encountering undefined data

Within the layout folder of my project, I have a Header component that includes a query to fetch some data. However, when I attempt to log this.props.data in the console, all I get is 'undefined'. Could someone please point out where I might be m ...

What is the best way to implement "computeIfAbsent" or "getOrElseUpdate" functionality for a Map in JavaScript?

If we assume that m represents a Map<number, V> for a certain type V k is a number, how can we create an expression that can either retrieve an existing V for the key k, or generate a new v: V, insert it into the map for the key k, and result in v ...

What is the best way to modify the text color in an MUI Text Field?

I'm completely new to using MUI and React, and I've run into an issue with changing the text color in my input field. Even though I specified inputProps={{sx: { color: "CCCCCC" }}}, the text color remains black while the label and searc ...

I am experiencing an issue where the data on the server is not being updated when I click the "back" button in the browser using jQuery, Ajax,

Here's the issue at hand: Upon clicking the "purchase" button, it changes color, updates the link, and adds the product to the cart: $(document).ready(function(c) { $('.item_add').click(function (event) { var addButton = $(this).c ...

Changing the color of an object in Three.JS using assigned materials

I am trying to apply a material/color to a loaded object using Three.js, but I am struggling with the syntax and which variables/functions to use. Although I can successfully load the object, I am facing difficulties when trying to set a material for it. ...

Guide on including a dropdown-item within the navbar

I've implemented a header with a navbar inside. I want to create a dropdown menu element, but for some reason, my item is not appearing. On this link, it looks simple: https://getbootstrap.com/docs/4.0/components/navs/ Pills with dropdowns <l ...

Creating an Interactive Countdown Timer with JavaScript

I am currently working on a website that includes a modified version of a JavaScript countdown element. While I have been learning a lot about flex grids, I haven't delved much into block/inline-block layouts. One issue I'm facing is that when t ...

Setting up VSCode for THREE.js development

Struggling with implementing my JavaScript code in VSCode, trying to move away from CodePen and use an actual code editor. Transition seemed simple but can't get it to work. Using the following files: test.html <!DOCTYPE html> <html> .. ...

Creating a simple to-do list, I noticed that upon refreshing and retrieving data from the local storage, instead of just displaying "wash dishes", it shows as {"TODO_ITEM:1":"wash dishes"}

I have created a basic todo list where I am facing an issue. When I add an item like "wash dishes" through the input, it displays correctly. However, upon refreshing the page and accessing the object in the array from local storage, I get back {"TODO_ITE ...

Obtaining the URL of web pages using ajax

This website contains various "subpages" with user reviews embedded via ajax. To access a specific URL for certain pages (like ?page=4), I want to direct users to particular reviews without them having to manually navigate through multiple pages. Here is a ...

Can anyone provide guidance on how to calculate the total sum of a JavaScript array within an asynchronous function?

Currently, I am working with Angularjs Protractor for end-to-end testing and faced an issue while trying to calculate the sum of values in a column. Although I am able to print out each value within the loop successfully, I am struggling to figure out ho ...

Monitoring Clicks within an Iframe

Is there a way to track a click event on a hyperlink within an iframe using Google Analytics? The iframe is located within the same domain as the main page. How can this be achieved? The iframe is added dynamically to the page after it has loaded. Is i ...

The execution of the Mocha test script is hindered by a socket.io issue causing it to

Running my tests (mocha) by typing npm run test in the console was working fine until I pulled down some code from my team. There seems to be an issue now. We are building an app that utilizes Socket.io, and for some reason, it appears in the command promp ...

Create spacing on the right side of a div with Bootstrap 4 offset, instead of the typical left side offset

Looking for a solution in Bootstrap 4 that mirrors the offset feature in Bootstrap 3, but pushes a div to the left instead of right. Need a way to have multiple dynamic divs within a row, where one div is pushed to the left on its own row without the nee ...

Angular's $location is reverting back after the modification

When using Angular, I encountered an issue where the user was not redirected to the view page after submitting a form. To handle this, I attached the following function to the scope: $scope.create = function () { return $scope.customer.$save({}, funct ...

Preventing the inclusion of current URL in the URL input

I have a situation where I need to print custom URLs in the footer that are retrieved from a database. For example, let's say the URL is www.google.com. <li><a href="<?php echo $links['link_url']?>"><?php echo $links[&a ...

Instructions on how to divide an email address at the @ symbol and showcase it in two separate table cells

I'm having trouble displaying the values separately after using the explode() function. My table is showing two values that are exactly the same, and I can't figure out why. I've searched extensively on StackOverflow but haven't been ab ...

What steps are involved in adding an image to an autocomplete script?

I need help adding an image to my autocomplete script. Below is my code that I'm struggling with. My Controller: function getsearch($c_id) { $searchTerm = $_GET['term']; $query = $this->db->query("SELECT state_name FROM state ...

Issue encountered while trying to utilize MongoDB on a live host through evennode.com

I recently uploaded my first project to a free node.js host on EvenNode, but unfortunately, it's not working. I've updated all of my connection codes as recommended by EvenNode, but the issue is that I can't use Express, which is crucial for ...

Do not transfer any files during the migration process from NGINX to Apache

I have a specific URL structure: http://www.example.com/folder/index.php?dir=dir1 I want to make it accessible from: http://www.example.com/folder/dir1 To achieve this, I set up rules in my .htaccess file located in the 'folder' directory: O ...