Reputation: 3242
Here is a Fiddle of my problem (Click the image next to the 'Werknemers' or 'Verzuimdossiers').
I got a sidebar in which some items have subcontent and some don't. So I made an accordion with subnav items. The problem is that the opening animation works fine. However, the closing animation is not being fired.
What could be the issue here?
Code for reference
openSubnav = (evt, subNavName) => {
let i, subnavContent, subnavLinks;
//Check if the current accordion is clicked again to close it.
const subNav = document.getElementById(subNavName)
if (getComputedStyle(subNav).display === 'block') {
subNav.style.display = 'none'
evt.currentTarget.className = evt.currentTarget.className.replace(" subnav-isActive", "");
subNav.style.maxHeight = null;
return
}
//hide alle subnav content
subnavContent = document.getElementsByClassName("subnav-content");
for (i = 0; i < subnavContent.length; i++) {
subnavContent[i].style.display = "none";
}
//delete the subnav-isActive class
subnavLinks = document.getElementsByClassName("subnav-item");
for (i = 0; i < subnavLinks.length; i++) {
subnavLinks[i].className = subnavLinks[i].className.replace(" subnav-isActive", "");
}
//Display the content
subNav.style.display = "block";
//Add the subnav-isActive class
evt.currentTarget.className += " subnav-isActive";
//If there currently is a max-height on the element, delete it.
if (subNav.style.maxHeight) {
subNav.style.maxHeight = null;
}
subNav.style.maxHeight = subNav.scrollHeight + "px";
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.root {
display: flex;
font-family: 'Poppins', sans-serif;
}
nav {
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
-o-user-select:none;
user-select:none;
}
.icon-container {
width: 60px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
}
/* .sidebar:hover {
width: 250px;
overflow: visible;
} */
.sidebar {
width: 250px;
}
.sidebar {
background-color: #8dc4d9;
position:absolute;
top:0;
bottom:0;
height:100%;
left:0;
/* width:60px; */
overflow:hidden;
-webkit-transition:width .05s linear;
transition:width .05s linear;
}
.sidebar>ul {
margin: 10px 0;
}
.sidebar li {
width:250px;
}
.sidebar li>span {
position: relative;
display: table;
border-collapse: collapse;
border-spacing: 0;
font-size: 14px;
transition: all .1s linear;
}
.sidebar .nav-text {
display: table-cell;
vertical-align: middle;
/* 250px breed totaal - 60px breed icoon = 190 */
width: 190px;
}
.sidebar .nav-dropdown {
display: table-cell;
vertical-align: middle;
cursor: pointer;
padding-right: 20px;
padding-top: 8px;
}
.sidebar .nav-dropdown img {
transform: rotate(270deg);
transition: transform .3s ease;
}
.sidebar .nav-dropdown.subnav-isActive img {
transform: rotate(360deg);
}
.user {
margin-bottom: 20px;
}
.sidebar li:hover>span {
background-color:#76abbf;
}
.subnav-content {
display: none;
/* 17px omdat de afbeelding 24x24 is en de breedte van de sidebar 60px.
Met de afbeelding houd je dus 17px aan beiden kanten over. */
padding: 10px 17px;
background-color:#76abbf;
list-style: none;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.content {
width: calc(50% - 30px);
background-color: #f3f6f9;
}
.preview {
width: calc(50% - 30px);
background-color: #f3f6f9;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<title>Sidebar</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">
</head>
<body>
<div class="root">
<nav class="sidebar">
<ul>
<li class="user">
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/user32.png" alt="">
</div>
<span class="nav-text">
Mijn account
</span>
</span>
</li>
<li>
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/bureaublad24.png" alt="">
</div>
<span class="nav-text">
Dashboard
</span>
</span>
</li>
<li class="has-subnav">
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/werknemers24.png" alt="">
</div>
<span class="nav-text">
Werknemers
</span>
<span class="nav-dropdown subnav-item" onclick="openSubnav(event, 'Werknemers')">
<img src="./icons24/DropdownArrow16.png">
</span>
</span>
<ul id="Werknemers" class="subnav-content">
<li>kaas</li>
<li>brood</li>
<li>eieren</li>
</ul>
</li>
<li>
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/verzuimdossiers24.png" alt="">
</div>
<span class="nav-text">
Verzuimdossiers
</span>
<span class="nav-dropdown subnav-item" onclick="openSubnav(event, 'Verzuimdossiers')">
<img src="./icons24/DropdownArrow16.png">
</span>
</span>
<ul id="Verzuimdossiers" class="subnav-content">
<li>boter</li>
<li>friet</li>
<li>pasta</li>
</ul>
</li>
<li>
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/trajecten24.png" alt="">
</div>
<span class="nav-text">
Trajecten
</span>
</span>
</li>
<li>
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/projecten24.png" alt="">
</div>
<span class="nav-text">
Projecten
</span>
</span>
</li>
</ul>
</nav>
<div class="content">
Content
</div>
<div class="preview">
Preview
</div>
</div>
</body>
</html>
Upvotes: 0
Views: 451
Reputation: 146
You need to set timeout before the display: none
so it has time to prosecute the closing animation.
Like in this code:
const subNav = document.getElementById(subNavName)
if (getComputedStyle(subNav).display === 'block') {
evt.currentTarget.className = evt.currentTarget.className.replace(" subnav-isActive", "");
subNav.style.maxHeight = null;
setTimeout(function(){subNav.style.display = 'none';}, 100);
return
}
Here you have the right code complete (idk why, but you need to expand the snippet to see it working, click on Run code snippet and then Full page link):
openSubnav = (evt, subNavName) => {
let i, subnavContent, subnavLinks;
//Check if the current accordion is clicked again to close it.
const subNav = document.getElementById(subNavName)
if (getComputedStyle(subNav).display === 'block') {
evt.currentTarget.className = evt.currentTarget.className.replace(" subnav-isActive", "");
subNav.style.maxHeight = null;
setTimeout(function(){subNav.style.display = 'none';}, 100);
return
}
//hide alle subnav content
subnavContent = document.getElementsByClassName("subnav-content");
for (i = 0; i < subnavContent.length; i++) {
subnavContent[i].style.display = "none";
}
//delete the subnav-isActive class
subnavLinks = document.getElementsByClassName("subnav-item");
for (i = 0; i < subnavLinks.length; i++) {
subnavLinks[i].className = subnavLinks[i].className.replace(" subnav-isActive", "");
}
//Display the content
subNav.style.display = "block";
//Add the subnav-isActive class
evt.currentTarget.className += " subnav-isActive";
//If there currently is a max-height on the element, delete it.
if (subNav.style.maxHeight) {
subNav.style.maxHeight = null;
}
subNav.style.maxHeight = subNav.scrollHeight + "px";
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.root {
display: flex;
font-family: 'Poppins', sans-serif;
}
nav {
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
-o-user-select:none;
user-select:none;
}
.icon-container {
width: 60px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
}
/* .sidebar:hover {
width: 250px;
overflow: visible;
} */
.sidebar {
width: 250px;
}
.sidebar {
background-color: #8dc4d9;
position:absolute;
top:0;
bottom:0;
height:100%;
left:0;
/* width:60px; */
overflow:hidden;
-webkit-transition:width .05s linear;
transition:width .05s linear;
}
.sidebar>ul {
margin: 10px 0;
}
.sidebar li {
width:250px;
}
.sidebar li>span {
position: relative;
display: table;
border-collapse: collapse;
border-spacing: 0;
font-size: 14px;
transition: all .1s linear;
}
.sidebar .nav-text {
display: table-cell;
vertical-align: middle;
/* 250px breed totaal - 60px breed icoon = 190 */
width: 190px;
}
.sidebar .nav-dropdown {
display: table-cell;
vertical-align: middle;
cursor: pointer;
padding-right: 20px;
padding-top: 8px;
}
.sidebar .nav-dropdown img {
transform: rotate(270deg);
transition: transform .3s ease;
}
.sidebar .nav-dropdown.subnav-isActive img {
transform: rotate(360deg);
}
.user {
margin-bottom: 20px;
}
.sidebar li:hover>span {
background-color:#76abbf;
}
.subnav-content {
display: none;
/* 17px omdat de afbeelding 24x24 is en de breedte van de sidebar 60px.
Met de afbeelding houd je dus 17px aan beiden kanten over. */
padding: 10px 17px;
background-color:#76abbf;
list-style: none;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
}
.content {
width: calc(50% - 30px);
background-color: #f3f6f9;
}
.preview {
width: calc(50% - 30px);
background-color: #f3f6f9;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
<title>Sidebar</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">
</head>
<body>
<div class="root">
<nav class="sidebar">
<ul>
<li class="user">
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/user32.png" alt="">
</div>
<span class="nav-text">
Mijn account
</span>
</span>
</li>
<li>
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/bureaublad24.png" alt="">
</div>
<span class="nav-text">
Dashboard
</span>
</span>
</li>
<li class="has-subnav">
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/werknemers24.png" alt="">
</div>
<span class="nav-text">
Werknemers
</span>
<span class="nav-dropdown subnav-item" onclick="openSubnav(event, 'Werknemers')">
<img src="./icons24/DropdownArrow16.png">
</span>
</span>
<ul id="Werknemers" class="subnav-content">
<li>kaas</li>
<li>brood</li>
<li>eieren</li>
</ul>
</li>
<li>
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/verzuimdossiers24.png" alt="">
</div>
<span class="nav-text">
Verzuimdossiers
</span>
<span class="nav-dropdown subnav-item" onclick="openSubnav(event, 'Verzuimdossiers')">
<img src="./icons24/DropdownArrow16.png">
</span>
</span>
<ul id="Verzuimdossiers" class="subnav-content">
<li>boter</li>
<li>friet</li>
<li>pasta</li>
</ul>
</li>
<li>
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/trajecten24.png" alt="">
</div>
<span class="nav-text">
Trajecten
</span>
</span>
</li>
<li>
<span>
<div class="icon-container">
<img class="nav-icon" src="./icons24/projecten24.png" alt="">
</div>
<span class="nav-text">
Projecten
</span>
</span>
</li>
</ul>
</nav>
<div class="content">
Content
</div>
<div class="preview">
Preview
</div>
</div>
</body>
</html>
Upvotes: 3
Reputation: 1365
The reason is because your animation takes some time to execute, but you assign display: none
before your animation has any chance to be rendered.
Upvotes: 2