Animation nav menu slide latérale : slide retour compliqué

Résolu/Fermé
rdbn Messages postés 95 Date d'inscription samedi 3 avril 2021 Statut Membre Dernière intervention 26 décembre 2022 - 31 déc. 2021 à 19:38
rdbn Messages postés 95 Date d'inscription samedi 3 avril 2021 Statut Membre Dernière intervention 26 décembre 2022 - 6 janv. 2022 à 17:05
Bonjour,

J'ai codé une nav bar personnalisé avec un bouton de type hamburger à droite où si l'on clique dessus un menu slide de droite vers la gauche. Donc quand je clique à nouveau sur le bouton hamburger maintenant une "croix" il revient en slide de gauche à droite à sa position initiale c'est à dire empilé les un sur les autre comme un position absolute, mais ne disparaît pas...
Pour expliqué un peu, c'est pour avoir cette effet qu'il parte tous de la même position plus au moins en opacity 0 à opacity 1 sur chacun sa positon exemple : "menu - menu - menu - menu ".


Si j'ai pas était assez clair je vous laisse le morceaux de code nécessaire html css et js. Vous pourrez directement visualisé par vous même l'effet et mon problème de retour.

Car dans la logique ca devrais être de opacity:1 à opacity:0 pour avoir l'effet inverse mais le problème c'est qu'en faisant comme cela le slide ne fonctionne plus de gauche à droite pour fermer et ca fait juste un opacity: 0.
En gros il y a plus rien quand je clique sur la croix mais pour ouvrir le menu ca slide toujours. Donc cette différence esthétiquement ne colle pas.

Merci d'avance !

Code html :

<!DOCTYPE html>
<html lang="fr">
<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">
    <title>Menu-slide</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    
    <nav>
        <div class="container">
            <h3 class="logo">Menu<span>Slide</span></h3>

            <div class="list-menu">
                <ul>
                    <li class="home"><a href="">Home</a></li>
                    <li class="work"><a href="" >Work</a></li>
                    <li class="about"><a href="">About</a></li>
                    <li class="contact"><a href="">Contact</a></li>
                </ul>
            </div>

            <div class="hamburger-menu">
                <div class="bar"></div>
            </div>

        </div>
    </nav>

    <script type="text/javascript" src="script.js"></script>
</body>
</html>


Code css :

@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@200;300;400;500;600;700;800;900&display=swap');

* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

body {
    font-family: 'Nunito', sans-serif;
    background-color: rgb(180, 180, 180);
}

.container {
    padding: 0 2rem;
    margin: 0 auto;
}

header {
    width: 100%;
    height: 100vh;
    position: relative;
    overflow: hidden;
}

header:after {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    background: rgba(0, 0, 0, 0.05);
    z-index: 25;
}

nav {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    padding: 1.5rem 0;
    z-index: 30;
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0.1), transparent);
}

nav .container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

nav .container .list-menu ul {
    display: flex;
}

nav .container .list-menu ul li {
    top: 30px;
    list-style: none;
    margin-left: 4rem;
}

nav .container .list-menu ul li.home {
    transform: translateX(650px);
    opacity: 0;
    transition: transform .6s ease-in-out;
    opacity: .6s ease-in-out;
}

nav .container .list-menu ul li.home.close {
    transform: translateX(650px);
    opacity: 1;
    transition: transform .9s ease-in-out;
    opacity: .6s ease-in-out;
}

nav .container .list-menu ul li.work {
    transform: translateX(500px);
    opacity: 0;
    transition: transform .7s ease-in-out;
    opacity: .6s ease-in-out;
}

nav .container .list-menu ul li.work.close {
    transform: translateX(500px);
    opacity: 1;
    transition: transform .8s ease-in-out;
    opacity: .6s ease-in-out;
}

nav .container .list-menu ul li.about {
    transform: translateX(350px);
    opacity: 0;
    transition: transform .8s ease-in-out;
    opacity: .6s ease-in-out;
}

nav .container .list-menu ul li.about.close {
    transform: translateX(350px);
    opacity: 1;
    transition: transform .7s ease-in-out;
    opacity: .6s ease-in-out;
}

nav .container .list-menu ul li.contact {
    transform: translateX(180px);
    opacity: 0;
    transition: transform .9s ease-in-out;
    opacity: .6s ease-in-out;
}

nav .container .list-menu ul li.contact.close {
    transform: translateX(180px);
    opacity: 1;
    transition: transform .6s ease-in-out;
    opacity: .6s ease-in-out;
}

nav .container .list-menu ul li a {
    text-decoration: none;
    color:  #fff;
    padding: 6px 15px;
    font-size: 1.5rem;
    font-weight: 300;
}

nav .container .list-menu ul li a:hover {
    background-color: #F0BB68;
    border-radius: 20px;
}


/** Animation menu-liste droite ouverture  **/
nav .container .list-menu ul li.contact.open,
nav .container .list-menu ul li.about.open,
nav .container .list-menu ul li.work.open,
nav .container .list-menu ul li.home.open {
    transform: translateX(0px);
    opacity: 1;
}
/** Animation menu-liste droite ouverture **/

.logo {
    color: #F0BB68;
    font-size: 2rem;
    text-transform: uppercase;
    font-weight: 600;
    letter-spacing: 2px;
}

.logo span {
    color: #fff;
    font-weight: 300;
}

.hamburger-menu {
    width: 2rem;
    height: 1.5rem;
    display: flex;
    align-items: center;
    cursor: pointer;
    transition: all .5s ease-in-out;
    z-index: 31;
}

.bar {
    position: relative;
    width: 100%;
    height: 3px;
    background-color: #F0BB68;
    border-radius: 2px;
    transition: all .5s ease-in-out;
}

.bar::before, .bar::after {
    content: '';
    position: absolute;
    width: 2rem;
    height: 3px;
    background-color: #fff;
    border-radius: 2px;
    transition: all .5s ease-in-out;
}

.bar::before {
    transform: translateY(-11px);
}

.bar::after {
    transform: translateY(11px);
}

/** Animation hamburger-menu to cross-menu **/
.hamburger-menu.open .bar {
    transform: translateX(-10px);
    background: transparent;
}

.hamburger-menu.open .bar::before {
    transform: rotate(45deg) translate(10px, -10px);
}

.hamburger-menu.open .bar::after {
    transform: rotate(-45deg) translate(10px, 10px);
}
/** Animation hamburger-menu to cross-menu **/


Code js :


const hamburger_menu = document.querySelector('.hamburger-menu');
const home = document.querySelector('.home');
const work = document.querySelector('.work');
const about = document.querySelector('.about');
const contact = document.querySelector('.contact');
let hamburger_menu_open = false;

window.addEventListener('click', () => {
    if(!hamburger_menu_open) {
        hamburger_menu.classList.add('open');
        home.classList.add('open');
        home.classList.remove('close');
        work.classList.add('open');
        work.classList.remove('close');
        about.classList.add('open');
        about.classList.remove('close');
        contact.classList.add('open');
        contact.classList.remove('close');
        hamburger_menu_open = true;
    } else {
        hamburger_menu.classList.remove('open');
        home.classList.remove('open');
        home.classList.add('close');
        work.classList.remove('open');
        work.classList.add('close');
        about.classList.remove('open');
        about.classList.add('close');
        contact.classList.remove('open');
        contact.classList.add('close');
        hamburger_menu_open = false;
    }
});



Configuration: Windows / Chrome 96.0.4664.110
A voir également:

2 réponses

Pitet Messages postés 2826 Date d'inscription lundi 11 février 2013 Statut Membre Dernière intervention 21 juillet 2022 524
4 janv. 2022 à 19:06
Bonjour,

Par défaut au chargement de la page, chaque élément de menu possède sa propre classe pour laquelle l'opacité est définie à 0 :
nav .container .list-menu ul li.home {
    transform: translateX(650px);
    opacity: 0;
    transition: transform .6s ease-in-out;
    opacity: .6s ease-in-out;
}

(la 4ème ligne "opacity: .6s ease-in-out;" n'est pas correcte, on ne peut pas mélanger opacité et transition comme cela)

A l'ouverture du menu, la classe open est appliquée sur chaque élément de menu, celle-ci surcharge l'opacité à 1 afin de faire apparaitre les éléments :
nav .container .list-menu ul li.home.open {
    transform: translateX(0px);
    opacity: 1;
}


Par contre à la fermeture du menu, la classe close remplace la classe open mais l'opacité reste à 1 avec cette classe :
nav .container .list-menu ul li.home.close {
    transform: translateX(650px);
    opacity: 1;
    transition: transform .9s ease-in-out;
    opacity: .6s ease-in-out;
}


Il faut donc repasser l'opacité à 0 lorsque la classe close est appliquée pour masquer les éléments.

Tu devrais vraiment factoriser ton code en utilisant une classe commune pour tous les éléments de menu car tu as beaucoup de code dupliqués, ce qui t'oblige à modifier ton code à plusieurs endroits si tu veux changer le style des éléments ou ajouter d'autres éléments.
Tu peux par exemple ajouter sur chaque élément de menu une classe nommée "menu-item" ou un autre nom de ton choix, puis appliquer le style commun à tous les éléments dans cette classe. Tu peux en plus conserver la classe unique pour chaque élément (home, about, contact, ...) si besoin de surcharger le style d'un menu différemment des autres.
Un début de factorisation possible pour les éléments de menu (ligne 63 pour le css avec le code factorisé mis en commentaire) : https://jsfiddle.net/er5t7m3j/
1
rdbn Messages postés 95 Date d'inscription samedi 3 avril 2021 Statut Membre Dernière intervention 26 décembre 2022
6 janv. 2022 à 17:05
Bonjour, merci pour ton aide. Le faite de factorisé grâce à une classe commune aide énormément à visualisé proprement le code et réduire le code en quelque ligne. Et encore merci pour l'exemple sur jsfiddle.
0