"Create a smooth transition effect in CSS by fading out one div and fading in

I've set up a grid of buttons, and my goal is to have the grid fade out when a button is clicked, then fade in with a new div in its place. This involves animating opacity from 1 to 0 and vice versa while toggling the display:none property for content replacement.

I've managed to get this working (though it may not be the most elegant solution as I'm still learning about animations). However, I'm encountering an issue with the back button within the new div. The new div fades out smoothly, but the original grid initially snaps back before fading in, and I'm unsure how to resolve this.

(Note: I'm implementing this in Angular, but I've converted it to vanilla JS) Here's my code snippet, along with a link to the CodePen for reference:

function showAccordion(){
    document.getElementById('faq-support-boxes-grid')?.classList.add('fadeOut');
  setTimeout(() => {
      document.getElementById('faq-support-boxes-grid')?.classList.add('hide-element');
      document.getElementById('accordion-container')?.classList.add('fadeIn');
      document.getElementById('accordion-container')?.classList.add('show-element');
    }, 1000);
  }

function resetAccordion(){
    document.getElementById('accordion-container')?.classList.remove('fadeIn');
    document.getElementById('accordion-container')?.classList.add('fadeOut');
    setTimeout(() => {
      document.getElementById('accordion-container')?.classList.remove('show-element');

    }, 1000);
    setTimeout(() =>{
      document.getElementById('faq-support-boxes-grid')?.classList.remove('fadeOut');
      document.getElementById('faq-support-boxes-grid')?.classList.remove('hide-element');
      document.getElementById('faq-support-boxes-grid')?.classList.add('fadeIn');

    },2000)
}
.faq-support-boxes-grid {
  background-color: #fff;
      display: grid;
      gap: 1rem;
      grid-template-columns: repeat(3, 1fr);
      grid-template-rows: repeat(2, 1fr);

      opacity: 1;

      .feature-box{
        background-color:#a6a6a6;
        text-align:center;
        img{
          display: inline;
          width:40%;
        }
      }
    }

    .fadeOut {
      animation: fadeOutTop 1s ease-out;
      animation-fill-mode: forwards;
    }

    .fadeIn {
      animation: fadeInTop 1s ease-out 1s;
      animation-fill-mode: forwards;
    }
    .accordion-container{
      transform: translateY(-30rem);
      opacity: 0;
      display: none;
      transition: all 1s;
    }

    .accordion-container > div{
      display: none;
    }

    .accordion-back{
      transform: translateY(-10%);
      display: block;
      color:#325390 !important;
    }

    .show-element{
      display: block !important;
    }
    .hide-element{
      display: none !important;
    }

@keyframes fadeOutTop{
  0%{
      opacity: 1;
      transform: translate(0rem);
  }
  100%{
      opacity: 0;
      transform: translateY(-30rem);
  }
}

@keyframes fadeInTop{
  100%{
      opacity: 1;
      transform: translate(0rem);
  }
  0%{
      opacity: 0 ;
      transform: translateY(-30rem);
  }
}
<div id="faq-support-boxes-grid" class="faq-support-boxes-grid">
   <div id="feature-box-about" onclick="showAccordion()" class="feature-box" tabindex="1">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 1</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-security" onclick="showAccordion()" class="feature-box" tabindex="2">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading  2</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-using" class="feature-box" tabindex="3">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 3</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-account" class="feature-box" tabindex="4">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 4</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-billing" class="feature-box" tabindex="5">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 5</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-support" class="feature-box" tabindex="6">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 6</h3>
      <p>some text</p>
   </div>
</div>
<div id="accordion-container" class="accordion-container">
   <button class="accordion-back btn btn-secondary" onclick="resetAccordion()">
   Back
   </button>
</div>

Answer №1

If you want to make some changes, try this approach. Introduce a new class called Op0 that will adjust the opacity of the element to 0. Therefore, when you use fadeIn, the grid won't just suddenly appear; instead, it will have a display: block property but with an opacity of 0, making it invisible. As the fadeIn animation progresses, the proper visibility will be restored.

  1. Add the following CSS snippet inside .faq-support-boxes-grid { ... before the .fadeOut section:
   /* Add the following CSS */
   .Op0 {
     opacity: 0;
   }
  1. Update the showAccordion() function. Replace the first line
    document.getElementById('faq-support-boxes-grid')?.classList.add('fadeOut');
    with these lines:
    // remove the fadeIn class
    document.getElementById('faq-support-boxes-grid')?.classList.remove('fadeIn');
    // add Op0 class along with fadeOut
    document.getElementById('faq-support-boxes-grid')?.classList.add('fadeOut', 'Op0');
  1. Modify the resetAccordion() function. Move the indicated line from the second setTimeout to the first one.
   document.getElementById('faq-support-boxes-grid')?.classList.add('fadeIn');

You can find the complete code below.

function showAccordion(){
    // remove the fadeIn class
    document.getElementById('faq-support-boxes-grid')?.classList.remove('fadeIn');
    // add Op0 class along with fadeOut
    document.getElementById('faq-support-boxes-grid')?.classList.add('fadeOut', 'Op0');
  setTimeout(() => {
      document.getElementById('faq-support-boxes-grid')?.classList.add('hide-element');
      document.getElementById('accordion-container')?.classList.add('fadeIn');
      document.getElementById('accordion-container')?.classList.add('show-element');
    }, 1000);
  }

function resetAccordion(){
    document.getElementById('accordion-container')?.classList.remove('fadeIn');
    document.getElementById('accordion-container')?.classList.add('fadeOut');
    setTimeout(() => {
      // move adding fadeIn class here from next setTimeout function
      document.getElementById('faq-support-boxes-grid')?.classList.add('fadeIn');

    }, 1000);
    setTimeout(() =>{
      document.getElementById('faq-support-boxes-grid')?.classList.remove('fadeOut');
      document.getElementById('faq-support-boxes-grid')?.classList.remove('hide-element');
      document.getElementById('accordion-container')?.classList.remove('show-element');

    },2000)
  }
.faq-support-boxes-grid {
  background-color: #fff;
      display: grid;
      gap: 1rem;
      grid-template-columns: repeat(3, 1fr);
      grid-template-rows: repeat(2, 1fr);

      opacity: 1;

      .feature-box{
        background-color:#a6a6a6;
        text-align:center;
        img{
          display: inline;
          width:40%;
        }
      }
    }
    
    /* Add the following CSS */
    .Op0 {
      opacity: 0;
    }

    .fadeOut {
      animation: fadeOutTop 1s ease-out;
      animation-fill-mode: forwards;
    }

    .fadeIn {
      animation: fadeInTop 1s ease-out 1s;
      animation-fill-mode: forwards;
    }
    .accordion-container{
      transform: translateY(-30rem);
      opacity: 0;
      display: none;
      transition: all 1s;
    }

    .accordion-container > div{
      display: none;
    }

    .accordion-back{
      transform: translateY(-10%);
      display: block;
      color:#325390 !important;
    }

    .show-element{
      display: block !important;
    }
    .hide-element{
      display: none !important;
    }

@keyframes fadeOutTop{
  0%{
      opacity: 1;
      transform: translate(0rem);
  }
  100%{
      opacity: 0;
      transform: translateY(-30rem);
  }
}

@keyframes fadeInTop{
  100%{
      opacity: 1;
      transform: translate(0rem);
  }
  0%{
      opacity: 0 ;
      transform: translateY(-30rem);
  }
}
<div id="faq-support-boxes-grid" class="faq-support-boxes-grid">
   <div id="feature-box-about" onclick="showAccordion()" class="feature-box" tabindex="1">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 1</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-security" onclick="showAccordion()" class="feature-box" tabindex="2">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading  2</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-using" class="feature-box" tabindex="3">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 3</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-account" class="feature-box" tabindex="4">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 4</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-billing" class="feature-box" tabindex="5">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 5</h3>
      <p>some text</p>
   </div>
   <div id="feature-box-support" class="feature-box" tabindex="6">
      <img src="https://www.adaptivewfs.com/wp-content/uploads/2020/07/logo-placeholder-image.png" >
      <h3>Heading 6</h3>
      <p>some text</p>
   </div>
</div>
<div id="accordion-container" class="accordion-container">
   <button class="accordion-back btn btn-secondary" onclick="resetAccordion()">
   Back
   </button>
</div>

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

Develop an interactive React sidebar with changing elements

I'm in the process of developing a sidebar for a project, with the goal of making it similar to tools like Confluence. This means that we need the ability to rearrange documents and create subdirectory structures by simply moving the documents, with ...

Styling the content area to fill the entire window in CSS will

<div id="content"> </div> #content{ height:100%; z-index:2; position:relative; top:40px } The content within this DIV is positioned 40px from the top of the page and will scroll under a navigation bar that is 40px high. I am trying to figur ...

What is the best way to create three buttons for selecting various parameters?

I have a code snippet where I want to assign different parameters to each button when clicked. However, despite my logic, the functionality is not working as expected. Can someone help me with the correct syntax? For example, if I click the "Start (Easy) ...

Modifying various states within React using the useState() hook

Curiosity strikes me - what actually happens when I modify more than one state in a handler function? Will they be updated simultaneously, or will the changes occur sequentially? const [x, setX] = useState(0) const [y, setY] = useState(0) const handlerFu ...

Refreshing the Table to Update Data

I am working on a jquery application that includes a table with time and number fields. My goal is to increment the values every 3 seconds by creating a function to update the numbers automatically. Initially, the data in the table looks like this: Kobe ...

"Error: Vue prop is not defined when passed to computed functions during initial call

I am encountering an issue with my Vue component. Here is the code for reference: Vue.component('result', { props: ['stuff'], data: () => ({}), template: "<img :src='tag' class='result'></img>", ...

Submitting a file using Ajax XMLHttpRequest

Currently, I am facing an issue while attempting to send a file using the following XMLHttpRequest code. var url= "http://localhost:80/...."; $(document).ready(function(){ document.getElementById('upload').addEventListener('cha ...

Transmitting data from the backend to AngularJS during page load

After diving into Angular JS for the first time, I've hit a roadblock at an essential stage. My setup consists of an AngularJS front end and Grails backend. Check out the code snippets below along with my query. URL Mapping entry: as "/graph"(cont ...

What causes the button size to change in Bootstrap when switching to a spinner?

Every time I switch from a spinner back to a button, the button's size changes. I am struggling to identify the cause of this issue. function resizeButton() { var btn = document.getElementById('submitBtn'); btn.innerHTML = ' ...

Is RaphaelJS truly a vector-based tool?

Is it possible to position a circle at 50% of the width of the canvas using RaphaelJS without having to calculate the exact pixel value? I am looking for a simple way to place an element at half its container's width, but I'm not sure if this can ...

Trigger an event prior to the loading of a div

I have been working on a jQuery code that needs to run just before a specific div is displayed on the page. Take a look at the snippet below as an example of what I am trying to achieve: $(document).ready(function(){ $('.article').on('m ...

Send a vanilla JavaScript ajaxForm submission by completing the form

I am currently in the process of integrating JavaScript from an iOS application into a web application. I have control over the code for both apps. My objective is to develop a JavaScript function that can receive input from a barcode scanner, populate a w ...

"Enhance your data visualization with Highcharts Windbarb and effortless AJAX data

Alright. Let's rephrase a question that hasn't been answered yet. I've got a chart below with data loading dynamically via ajax. A simplified version (without ajax) of this graph works well as shown in this jsfiddle. The code below represe ...

What are some ways to eliminate spacing between child and parent div elements?

I am facing an issue with a parent div that contains multiple children. I want to add spacing between the children by applying margins, but this also creates unwanted space between the parent and the children. Is there a clean solution to remove this space ...

Obtain the value of a JavaScript form with a dynamically generated field name

I am struggling with a simple javascript code and for some reason, it's not working. var number = 5; var netiteration = "net"+number; // now netiteration is equal to net5 var formvalue = document.forms.myformname.netiteration.value; Why is this co ...

Navigating through the concept of passing objects by reference in child components of Angular 2+

Understanding that TypeScript uses object passing by reference can be challenging, especially when dealing with deep copy issues. This becomes particularly cumbersome when working within a theme. I recently encountered an issue with a component containing ...

handle an exception within the initializer of its object

I'm currently working with an Ajax object that is utilized in various other objects to load 'Json' files. One issue I'm facing is trying to catch the 404 'Not found' exception thrown in the initializer object. However, every ...

How can I dynamically adjust the font size of content in a React Material-UI Button when it's unexpectedly

In my web application project, I have created multiple choice questions where each answer is displayed within a single button: <Button fullWidth={true} variant="contained" onClick={(answer) => this.handleAnswer(this.state.answers[0].tex ...

Having trouble retrieving the chosen option from the select elements

Below is a portion of the code that I have written to capture the selected values of class code and section from a dropdown menu. Currently, only the first element of the select is being retrieved instead of the chosen element. HTML Code: <div id="dia ...

In the production mode, Webpack doesn't compile any code

I recently followed the typescript guide at https://webpack.js.org/guides/typescript/ After running webpack in "production" mode, I noticed that it emitted very minimal output. Below is the code from my src/index.ts file: export function foo() { return ...