How come the cubic bezier timing function works flawlessly just on the first try when staggered transitioning element opacity over time with CSS and a touch of JS?

I'm currently working on a menu overlay that expands to fill the screen when a user clicks a button in the corner. I'd like the menu items to fade in one by one, similar to the effect used on this website:

Most of the functionality is there, but I'm facing an issue where the menu items only fade in smoothly the first time the button is clicked. After that, they just appear suddenly (except for the first item). Can anyone help me figure out how to fix this?

You can view my code on CodePen.

Here's the HTML snippet:

<html>
  <head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  </head>
  <body>
<div id="menu"></div>
<div id="menu-button"></div>
<div id="menu-container">
    <div id="links">
        <a href="#Portfolio" id="portfolio">Portfolio</a><br />
        <a href="#Services" id="services">Services</a><br />
        <a href="#About" id="about">About</a><br />
        <a href="#Contact" id="contact">Contact</a><br />
    </div>
</div>

My CSS styling:

#menu {
    position: absolute;
    top: 0;
    left: 0;
    width: 100px;
    height: 100px;
    z-index: 1;
    background-color: #111;
    -webkit-transition: width 0.5s, height 0.5s;
            transition: width 0.5s, height 0.5s;
}

#menu.active {
    width: 100%;
    height: 100%;
}
...

Javascript function:

let menu = {
    div: document.getElementById('menu'),
    button: document.getElementById('menu-button'),
    container: document.getElementById('menu-container'),
    isExpanded: false,
    adjust: function() {
        menu.isExpanded = !menu.isExpanded;
        if (menu.isExpanded) {
            menu.div.classList.add("active");
            menu.button.classList.add("active");
            menu.container.classList.add("active");
        } else {
            menu.div.classList.remove("active");
            menu.button.classList.remove("active");
            menu.container.classList.remove("active");
        }
    }
}
let links = document.getElementById('links').childNodes; 
...

Note: Initially, I omitted mentioning that my original HTML uses Bootstrap's reset CSS. I have since added a link to a Bootstrap CDN.

Answer №1

The explanation provided in the initial response effectively clarifies the issue with your code.

An alternative solution involves making slight adjustments to your CSS code.

.active #portfolio {
  -webkit-transition: opacity 1s;
  transition: opacity 1s;
}

.active #services {
  -webkit-transition: opacity 1.5s;
  transition: opacity 1.5s;
}

.active #about {
  -webkit-transition: opacity 2s;
  transition: opacity 2s;
}

.active #contact {
  -webkit-transition: opacity 2.5s;
  transition: opacity 2.5s;
}

To activate the transition only when the menu-item has the .active parent, simply add the .active class before the menu-item.

Check out the CODEPEN demo here!

Answer №2

Your issue stems from the fact that once you close the menu, the links take 2 seconds to fully transition to opacity: 0, based on the longest transition time set.

If you try to reopen the menu before 2 seconds have passed, it won't work properly. However, you can resolve this by reducing the transition time to a shorter duration after closing the menu.

Here is an example of how you can achieve this: JsFiddle

You can update your JavaScript code to implement this solution:

let menu = {
    div: document.getElementById('menu'),
    button: document.getElementById('menu-button'),
    container: document.getElementById('menu-container'),
    isExpanded: false,
    adjust: function() {
        menu.isExpanded = !menu.isExpanded;
        if (menu.isExpanded) {
            menu.div.classList.add("active");
            menu.button.classList.add("active");
            menu.container.classList.remove("finished");
            menu.container.classList.add("active");
        } else {
            menu.div.classList.remove("active");
            menu.button.classList.remove("active");
            menu.container.classList.add("finished");
            menu.container.classList.remove("active");
        }
    }
}

let links = document.getElementById('links').childNodes;

for (let i = 0; i < links.length; i += 1) {
    if (links[i].nodeName.toLowerCase() == 'a') {
        links[i].addEventListener('mouseup', menu.adjust);
    }
}  

menu.button.addEventListener('mousedown', menu.adjust);

Be sure to add the following CSS code as well:

#menu-container.finished>#links>a {
    -webkit-transition: opacity 0.1s;
            transition: opacity 0.1s;
}

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

Is it possible to eliminate the sticky class as you scroll down?

Check out this jQuery code I wrote to remove the sticky class while scrolling down: $(window).scroll(function (e) { if ($('.main_form_wrapper').length != 0) { var window_scroll = $(window).scrollTop(); console.log(window_scro ...

Creating square elements using only HTML and CSS

This is just a longer text to demonstrate multiple lines being centered. ...

Overriding the !important declaration in inline styles within various CSS IDs and classes

I need to find a way to override an inline !important declaration that is nested inside multiple CSS ids and classes. Let's analyze the following situation: <div class="A"> <div class="B"> <div class="C"> < ...

Enhance your slideshow with a stylish fade effect

I found this slideshow on codepen and decided to customize it to make it my own. While everything is working well, I wanted to incorporate a fade effect into the transition between slides. I'm unsure whether I should add something to the CSS file or m ...

Having difficulty changing placeholder text style in Scss

I'm a newcomer to SCSS and I'm attempting to customize the color of my placeholder text from light gray to dark gray. Below is the HTML code snippet: <div class="form-group"> <textarea class="thread-textarea" ng-maxlength="255" ma ...

How can a CSS class be inherited from a different file?

I have defined a class for styling a button: .client-header button { /*Properties*/ } And I also have a class to indicate when the menu is open: .client-menu-open { /*Properties*/ } My goal is to change the background of the button depending on ...

What is the best way to alternate between two CSS stylesheets when using jQuery-UI?

Just getting started with jQuery and javascript and decided to test out 2 different jQuery-ui stylesheets in a simple .html file. The goal is to have the example dialog open with the "flick" stylesheet and the datepicker within the dialog open with the "u ...

Apply the "selected" class to the menu located in the common header

I have implemented a menu in the header.php file that will be displayed on all pages such as index.php or contact-us.php. However, I am facing an issue with adding the selected class to the active main category in the menu. The code provided works fine wh ...

Adjust background image size to fit the dimensions of the foreground content

I have a div where an image and content are inside. I am trying to make the background image adjust its size based on the content within it, rather than showing the full image size with empty space. My current styling uses flexbox: .section { height: ...

The parallax background features a sleek design with crisp white borders framing the edges

We are currently facing an issue while attempting to incorporate a parallax background on our website. The problem lies in an unwanted white border surrounding the image that can be seen at this link: https://i.stack.imgur.com/pt0Pf.jpg. Despite trying va ...

Screening through the outgoing html documents

For all my *.html files, I have added custom syntax that must be filtered through filter.php before being displayed. I believe this can be achieved using .htaccess. It's important to note that I do not want the *.html files to be parsed as PHP. ...

Arranging various JavaScript arrays

I've been working on a script using the Haversine formula, but I'm running into an issue where it always directs me to the first location in the array, no matter how many times I switch them around. Any suggestions? var locations = new Array( ...

Types of Content in Solr Responses

My journey with Solr has been enlightening, but I've hit a bump in the road. When querying Solr using: curl "http://localhost:8983/solr/myCollection/select?q=*:*&wt=json&rows=0" I receive a webpage displaying the JSON response. However, the ...

Is there a way to extract the content within the HTML tags as well as the text enclosed within parentheses?

When working with my HTML content, I came across the following line: <span>(48 עמודים סה"כ )</span> I am seeking a way to extract only the text "48 עמודים סה"כ" and store the number 48 into an integer variable. Although in t ...

HTML links have been disabled

I have been making updates to the charity website I manage, heroinitiative.org. You can view the revamp progress here: (please note that this is not live code, it is simply for my boss to see the progress and does not need to be kept secret, hence why I a ...

Incorporate JavaScript to include a new class and attribute

Apologies for any language barriers.. I grasp that it involves using addClass and removeClass, but I am uncertain about how to write the terms. I need to ensure that if the screen resolution is less than 768 pixels, then the attributes id="dLabel" type="b ...

Customize button appearance within mat-menu in Angular versions 2 and above

Is there a way to style my mat-menu to function similar to a modal dialog? I am having difficulty with the styling aspect and need advice on how to move the save and reset buttons to the right while creating space between them. I have attempted to apply st ...

Tips for adjusting the placement of enlarged images within colorbox

I recently discovered colorbox and decided to use it as my lightbox solution. However, I encountered a challenge with positioning the background (#cboxOverlay). I wanted to move it 120px to the left so that some content from the original page would still ...

Can you explain the significance of this HTML code?

While examining some source code, I came across the following: <div class="classname {height: 300px; width: 200px}"></div> I am aware that element styling can be done using the style="" attribute. Could you explain what this code snippet sig ...

Angular 8 UI not displaying mockAPI data as expected

My mockAPI is successfully fetching the data, but the json response structure is quite complex. It looks something like this: [ { "planList": [ // plan details here ] } ] Everything in the UI is displaying correctly, except ...