Después de varios intentos de agregar una animación de entrada / salida simple con opacidad, obtuve el resultado que quería. Sin embargo, la animación está provocando destellos no deseados.
Si cambia de un elemento a otro, notará que el contenido parpadeará por un momento. Qué estoy haciendo mal ?
Además, ¿hay una forma "más limpia" y más corta de lograr el mismo efecto?
var dropdownBtn = document.querySelectorAll('.menu-btn'); dropdownBtn.forEach(btn => btn.addEventListener('click', function() { var menuContent = this.nextElementSibling; closeMenusExcept(menuContent); if (!menuContent.classList.contains("show")) { menuContent.classList.add("show"); } else { menuContent.classList.add("hide"); setTimeout(function(){ menuContent.classList.remove("show"); menuContent.classList.remove("hide"); },100) } })); function closeMenusExcept(menuContent) { dropdownBtn.forEach((element) => { if (menuContent !== element.nextElementSibling) { element.nextElementSibling.classList.remove("show"); element.nextElementSibling.classList.add("hide"); } }) } .menu-btn { background: #e0e0e0; padding: 10px; margin: 5px 0px 0px 0px; } .menu-btn:hover { background: #000; color: #fff; } .drop_container { display: none; background-color: #fff; animation:animateFromBottom 0.3s } .drop_container.show { display: block; } .drop_container.hide { animation:animateToBottom 0.3s; } .drop_container > .item { display: flex; flex-direction: column; margin-left: 10px; padding: 10px 0px 0px 0px; } @keyframes animateFromBottom { from{opacity:0} to{opacity:1} } @keyframes animateToBottom { from{opacity:1} to{opacity:0} } <div class="dropdown-menu"> <div class="menu-btn">One</div> <div class="drop_container"> <a class="item" href="#">Contact Us</a> <a class="item" href="#">Visit Us</a> </div> <div class="menu-btn">Two</div> <div class="drop_container"> <a class="item" href="#">Contact Us</a> <a class="item" href="#">Visit Us</a> </div> </div>Debe cambiar la opacidad por altura máxima, aquí está su solución: https://codepen.io/nitinsuri/pen/bGLrLQB
var dropdownBtn = document.querySelectorAll('.menu-btn'); dropdownBtn.forEach(btn => btn.addEventListener('click', function() { var menuContent = this.nextElementSibling; closeMenusExcept(menuContent); if (!menuContent.classList.contains("show")) { menuContent.classList.add("show"); } else { menuContent.classList.add("hide"); setTimeout(function(){ menuContent.classList.remove("show"); menuContent.classList.remove("hide"); },100) } })); function closeMenusExcept(menuContent) { dropdownBtn.forEach((element) => { if (menuContent !== element.nextElementSibling) { element.nextElementSibling.classList.remove("show"); element.nextElementSibling.classList.add("hide"); } }) } .menu-btn { background: #e0e0e0; padding: 10px; margin: 5px 0px 0px 0px; } .menu-btn:hover { background: #000; color: #fff; } .drop_container { background-color: #fff; max-height: 0; overflow: hidden; } .drop_container.show { max-height: 100vh; animation:animateFromBottom 1s; } .drop_container > .item { display: flex; flex-direction: column; margin-left: 10px; padding: 10px 0px 0px 0px; } @keyframes animateFromBottom { from{ max-height: 0; overflow: hidden;} to{max-height: 100vh;} } @keyframes animateToBottom { from{max-height: 100vh;} to{ max-height: 0; overflow: hidden;} } <div class="dropdown-menu"> <div class="menu-btn">One</div> <div class="drop_container"> <a class="item" href="#">fist link of One</a> <a class="item" href="#">second link of One</a> </div> <div class="menu-btn">Two</div> <div class="drop_container"> <a class="item" href="#">fist link of Two</a> <a class="item" href="#">second link of Two</a> </div> </div>En Jquery puedes abordarlo de esta manera. puede usar alternar o deslizar alternar lento o rápido como lo desee. Acabo de agregar una clase nueva para que su css no se vea afectado. Déjame saber si esto es lo que estás viendo.
$(document).ready(function(){ $(".btn1").click(function(){ $(".container1").slideToggle(); $(".container2").hide("slow"); }); $(".btn2").click(function(){ $(".container2").slideToggle(); $(".container1").hide("slow"); }); }); .menu-btn { background: #e0e0e0; padding: 10px; margin: 5px 0px 0px 0px; } .menu-btn:hover { background: #000; color: #fff; } .drop_container { display: none; background-color: #fff; animation:animateFromBottom 0.3s } .drop_container.show { display: block; } .drop_container.hide { animation:animateToBottom 0.3s; } .drop_container > .item { display: flex; flex-direction: column; margin-left: 10px; padding: 10px 0px 0px 0px; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <div class="dropdown-menu"> <div class="menu-btn btn1">One</div> <div class="drop_container container1"> <a class="item" href="#">Contact Us</a> <a class="item" href="#">Visit Us</a> </div> <div class="menu-btn btn2">Two</div> <div class="drop_container container2"> <a class="item" href="#">Contact Us</a> <a class="item" href="#">Visit Us</a> </div> </div>