The issue with the max-height transition not functioning properly arises when there are dynamic changes to the max-height

document.querySelectorAll('.sidebarCategory').forEach(el =>{
      el.addEventListener('click', e =>{
          let sub = el.nextElementSibling
          if(sub.style.maxHeight){
              el.classList.remove('opened')
              sub.style.maxHeight=null
          }
          else{
              document.querySelectorAll('.sidebarSubcategories').forEach(element => {
                  element.style.maxHeight=null
                  element.previousElementSibling.classList.remove('opened')
              })
              el.classList.add('opened')
              sub.style.maxHeight = sub.scrollHeight + "px";
          }
      })
  })
  document.querySelectorAll('.sidebarSubcategories > div:not(.sidebarSubSubcategories)').forEach(el =>{
      el.addEventListener('click', e =>{
          let sub = el.nextElementSibling
          if(sub!=null && sub.classList.contains('sidebarSubSubcategories'))
          {
              if(sub.style.maxHeight){
                  sub.style.maxHeight=null
                  sub.style.marginBottom=0
                  sub.style.padding='0 30px'
              }
              else{
                  sub.style.marginBottom='15px'
                  sub.style.padding='15px 30px'
                  sub.style.maxHeight = sub.scrollHeight + 30 + "px"
                  el.parentNode.style.maxHeight=el.parentNode.style.maxHeight.slice(0,el.parentNode.style.maxHeight.length-2) + sub.scrollHeight + 30 + "px"
              }
          }
      })
  })
.main{
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%,-50%);
      width: 400px;
      height: 300px;
      overflow-y: auto;
      background-color: aquamarine;
  }
  .sidebarCategory{
      color: white;
      position: relative;
      height: 60px;
      min-height: 60px;
      display: flex;
      align-items: center;
      justify-content: flex-start;
      font-size: 20px;
      flex-wrap: wrap;
      font-weight: 600;
      fill: white!important;
      cursor: pointer;
      padding-left: 15px;
      transition: 0.4s;
  }
  .sidebarCategory.opened{
      background-color: rgba(3, 63, 109, 0.588);
  }
  .sidebarSubcategories{
      max-width: 100%;
      position: relative;
      background-color: rgba(3, 63, 109, 0.588);
      max-height: 0;
      transition: 0.4s;
      overflow-y: hidden;
  }
  .sidebarSubcategories > div:not(.sidebarSubSubcategories){
      max-height: 45px;
      /* height: 45px; */
      position: relative;
      min-height: 45px;
      color: white;
      cursor: pointer;
      overflow-y: hidden;
      display: flex;
      align-items: center;
      justify-content: flex-start;
      flex-wrap: wrap;
      padding: 0 30px;
      border-bottom: 1px solid var(--blue);
  }
  .sidebarSubSubcategories{
      max-height: 0;
      overflow-y: hidden;
      transition: 0.4s;
      background-color: white;
      border-radius: 5px;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: wrap;
      margin: 0 15px;
  }
  .sidebarSubSubcategories > div{
      cursor: pointer;
      transition: 0.2s;
      display: flex;
      justify-content: center;
      border-radius: 5px;
      align-items: center;
      padding: 10px;
      width: 49%;
  }
  .sidebarSubSubcategories > div:hover{
      background-color: #f3f3f3;
  }
<body>
    <div class="main">
        <div class="sidebarCategory">
            Lorem ipsum dolor sit amet.
        </div>
        <div class="sidebarSubcategories">
            <div>
                Subcategory
            </div>
            <div class="sidebarSubSubcategories">
                <div>Sub Subcategory</div>
                <div>Sub Subcategory</div>
                <div>Sub Subcategory</div>
                <div>Sub Subcategory</div>
            </div>
            <div>
                Subcategory
            </div>
            <div>
                Subcategory
            </div>
            <div>
                Subcategory
            </div>
         </div>
     </div>

It appears that the first drop-down does not close smoothly when interacting with the second drop-down menu. This issue arises from nested accordions where changing the max-height property causes a problem in the transition of the outer accordion on interaction with the inner accordion.</p>
    </div></questionbody>
<exquestionbody>
<div class="question">
                
<p><div>
<div>
<pre class="lang-js"><code>document.querySelectorAll('.sidebarCategory').forEach(el =>{
      el.addEventListener('click', e =>{
          let sub = el.nextElementSibling
          if(sub.style.maxHeight){
              el.classList.remove('opened')
              sub.style.maxHeight=null
          }
          else{
              document.querySelectorAll('.sidebarSubcategories').forEach(element => {
                  element.style.maxHeight=null
                  element.previousElementSibling.classList.remove('opened')
              })
              el.classList.add('opened')
              sub.style.maxHeight = sub.scrollHeight + "px";
          }
      })
  })
  document.querySelectorAll('.sidebarSubcategories > div:not(.sidebarSubSubcategories)').forEach(el =>{
      el.addEventListener('click', e =>{
          let sub = el.nextElementSibling
          if(sub!=null && sub.classList.contains('sidebarSubSubcategories'))
          {
              if(sub.style.maxHeight){
                  sub.style.maxHeight=null
                  sub.style.marginBottom=0
                  sub.style.padding='0 30px'
              }
              else{
                  sub.style.marginBottom='15px'
                  sub.style.padding='15px 30px'
                  sub.style.maxHeight = sub.scrollHeight + 30 + "px"
                  el.parentNode.style.maxHeight=el.parentNode.style.maxHeight.slice(0,el.parentNode.style.maxHeight.length-2) + sub.scrollHeight + 30 + "px"
              }
          }
      })
  })
.main{
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%,-50%);
      width: 400px;
      height: 300px;
      overflow-y: auto;
      background-color: aquamarine;
  }
  .sidebarCategory{
      color: white;
      position: relative;
      height: 60px;
      min-height: 60px;
      display: flex;
      align-items: center;
      justify-content: flex-start;
      font-size: 20px;
      flex-wrap: wrap;
      font-weight: 600;
      fill: white!important;
      cursor: pointer;
      padding-left: 15px;
      transition: 0.4s;
  }
  .sidebarCategory.opened{
      background-color: rgba(3, 63, 109, 0.588);
  }
  .sidebarSubcategories{
      max-width: 100%;
      position: relative;
      background-color: rgba(3, 63, 109, 0.588);
      max-height: 0;
      transition: 0.4s;
      overflow-y: hidden;
  }
  .sidebarSubcategories > div:not(.sidebarSubSubcategories){
      max-height: 45px;
      /* height: 45px; */
      position: relative;
      min-height: 45px;
      color: white;
      cursor: pointer;
      overflow-y: hidden;
      display: flex;
      align-items: center;
      justify-content: flex-start;
      flex-wrap: wrap;
      padding: 0 30px;
      border-bottom: 1px solid var(--blue);
  }
  .sidebarSubSubcategories{
      max-height: 0;
      overflow-y: hidden;
      transition: 0.4s;
      background-color: white;
      border-radius: 5px;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-wrap: wrap;
      margin: 0 15px;
  }
  .sidebarSubSubcategories > div{
      cursor: pointer;
      transition: 0.2s;
      display: flex;
      justify-content: center;
      border-radius: 5px;
      align-items: center;
      padding: 10px;
      width: 49%;
  }
  .sidebarSubSubcategories > div:hover{
      background-color: #f3f3f3;
  }
<body>
    <div class="main">
        <div class="sidebarCategory">
            Lorem ipsum dolor sit amet.
        </div>
        <div class="sidebarSubcategories">
            <div>
                Subcategory
            </div>
            <div class="sidebarSubSubcategories">
                <div>Sub Subcategory</div>
                <div>Sub Subcategory</div>
                <div>Sub Subcategory</div>
                <div>Sub Subcategory</div>
            </div>
            <div>
                Subcategory
            </div>
            <div>
                Subcategory
            </div>
            <div>
                Subcategory
            </div>
        </div>
    </div>
</body>
Upon inspection, it seems like the first drop-down encounters an issue while closing smoothly upon interaction with the second drop-down menu. This inconvenience stems from implementing nested accordions using the max-height property, causing a disruption in the transition effect of the external accordion when interacting with the internal one.

Answer №1

It appears that the main issue lies within this particular line of code

el.parentNode.style.maxHeight.slice(0,el.parentNode.style.maxHeight.length-2) + sub.scrollHeight...."

The problem arises from attempting to concatenate a string with a number, resulting in unintended behavior. When you add a number to a string, it will simply combine the two as new string values. To resolve this issue, make sure to convert the string to an integer (you can also omit slicing off the 'px' unit).

//Rather than 
el.parentNode.style.maxHeight.slice(0,el.parentNode.style.maxHeight.length-2)
//Use this approach          
parseInt(el.parentNode.style.maxHeight)

Answer №2

In my analysis, the issue lies in the sidebarSubcategories element lacking a defined height. Initially, it has a max-height set to 0, which is then changed to null using JavaScript.

The default value for height is auto. Therefore, setting maxHeight to null results in the max-height being interpreted as auto, causing transitions not to function correctly on auto values. This occurs because the browser cannot determine the specific value to transition to. If it is imperative for this functionality and manually setting the height of each sidebarSubcategories beforehand is not feasible, one solution could involve storing the innerHeight of each expanded sidebarSubcategories element and reapplying it when it needs to expand again.

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 there a way to add a fade-in and slide-in effect to this dropdown JavaScript, as well as a fade-out and

Although I lack the necessary knowledge of Javascript, I am aware that my request may be a bit much. The code I currently have is directly from the w3school dropdown-list demo. Would it be possible for you to help me implement a fade in and slide in effect ...

Tips for preserving the integrity of square brackets while extracting data from JSON

Everyone: We've decided to utilize Newtonsoft JSON.NET for serializing some C# POCOs, and here's what we have: { "RouteID": "123321213312", "DriverName": "JohnDoe", "Shift": "Night", "ItineraryCoordinates": [ [ 9393, 44 ...

Issue encountered while attempting to install datagrid library with Nuxt3

Currently, I am working on a Nuxt3 project and attempting to integrate the " @revolist/vue3-datagrid" library. Following the instructions provided in the library's documentation, I executed the command "npm i @revolist/vue3-datagrid --save". Unfortuna ...

Validating Credit Card Expiration Dates in AngularJS Form

I recently started learning AngularJS and decided to create a credit card validator. I successfully implemented the Luhn Algorithm in a custom filter, but now I'm facing issues with validating the expiration date as well. The conditions for a valid ex ...

Unable to link to 'mdMenuTriggerFor' as it is not a recognized attribute of 'button'

During the execution of my angular application using ng serve, I encounter the following error: Can't bind to 'mdMenuTriggerFor' since it isn't a known property of 'button' Despite importing all the necessary components, I a ...

Collapsing table row in Bootstrap upon button click within the same row

The snippet showcases a basic table with one row containing a button group. Upon clicking the 'main' button (the reset button), the following table row will appear. This behavior is intended only when clicking on the table row itself, not the but ...

Tips for aligning text in MUI Breadcrumbs

I am currently utilizing MUI Breadcrumb within my code and I am seeking a solution to center the content within the Breadcrumb. Below is the code snippet that I have attempted: https://i.stack.imgur.com/7zb1H.png <BreadcrumbStyle style={{marginTop:30}} ...

Tips for aligning controls in a column using Bootstrap

My coding issue: <div class="col-lg-4"> <label>Expiration ID</label> <div class="row "> <div class="col-lg-5"> <input type="text" class="form-control input-sm" id="TextIDExpire" /> </div> < ...

Tips on updating the default checkbox dynamically based on the current checkbox using JavaScript

Seeking to enhance the design of a Perl-generated form with custom CSS effects, rather than relying on the default Perl form. Despite successful functionality, encountering an issue where radio button focus reverts to default selection (Date) after submitt ...

The operation of executing `mongodb - find()` does not exist as a function

I am having trouble printing all documents from the "members" collection. I attempted to use the find() function, but encountered an error stating that find() is not a function. Here is a snippet from member_model.js located in the models/admin folder: v ...

Tips for defining the operational scope of orbit controls in three.js

I've been working on creating an orientation cube in threeJS and have set up 2 scenes with different viewports, cameras, and controls. Check out the fiddle here var controls = new THREE.OrbitControls( view.camera, container.domElement ); In the fid ...

Ways to determine if content is visible within a div

My website contains a script that brings in content from an ad network and displays it within a div element. Unfortunately, this particular ad network only fills ads 80% of the time, leaving the remaining 20% of the time without any ads to display. This la ...

Adjust the object's width and position based on the window's width

I am currently attempting to adjust the width of a box and the position of a btn based on the size of the window. Q1. How can I eliminate the excess white space located behind the scroll bar? (I have already set it to 100%..) Q2. After clicking the ...

Detecting the preferential usage of -webkit-calc instead of calc through JavaScript feature detection

While it's commonly advised to use feature detection over browser detection in JavaScript, sometimes specific scenarios call for the latter. An example of this can be seen with jQuery 1.9's removal of $.browser. Despite the general recommendatio ...

Tips for utilizing JavaScript to upload a file in Webform and make it accessible in the global PHP variable $_FILES

I'm feeling a little overwhelmed and frustrated. I've come across a bunch of solutions, but none of them seem to work fully or correctly!? My task is to create an HTML form that allows users to upload one or more files to the web server using AJ ...

Constructing an Http Post URL with form parameters using the Axios HTTP client

I need assistance in creating a postHTTP request with form parameters using axios on my node server. I have successfully implemented the Java code for constructing a URL, as shown below: JAVA CODE: HttpPost post = new HttpPost(UriBuilder.fromUri (getPro ...

Issue with reCAPTCHA callback in Firebase Phone Authentication not functioning as expected

I have been working on integrating phone authentication into my NextJS website. I added the reCAPTCHA code within my useEffect, but for some reason, it does not get triggered when the button with the specified id is clicked. Surprisingly, there are no erro ...

Ways to prevent a div containing a lengthy content string from extending beyond other divs

Check out my Codepen project here Here is the HTML code for my personal website: <div id="splash" class="divider"> <h1 class="text-center text-uppercase">vincent/rodomista</h1> <p class="text-center text uppercase">Full Stack ...

Ajax received a response from http 409 and is now parsing it

Hey there! I've been working on parsing out the message object using Ajax, and I'm having a bit of trouble getting a reference to messages.msg. It's strange because it displays perfectly fine in Postman, but for some reason, I can't see ...

Pressing the submit button will not successfully forward the form

I've encountered an issue with my submit buttons - when I click on them, nothing happens. They were functioning properly before, but now they seem to be unresponsive. What could be causing this problem? <form id="contact" name="updateorder" acti ...