Navigation et menus

Menu de navigation déroulant

Navigation responsive pour le survol sur ordinateur et le clic sur mobile.

HTMLCSSJavaScriptNavigation
Après activation de JavaScript, ce cas peut être modifié, exécuté et enregistré. Code source fixe ci-dessous :
<!doctype html>
<html lang="fr" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Menu de navigation déroulant</title>
  <style>
    * { box-sizing: border-box; }
    body { min-height: 100vh; margin: 0; color: #1d2a25; font-family: "Avenir Next", "Microsoft YaHei", sans-serif; background: #f7f5ef; }
    nav { position: relative; z-index: 5; display: flex; align-items: center; gap: 28px; width: min(1160px, calc(100% - 36px)); margin: 18px auto 0; padding: 12px 16px 12px 22px; border: 1px solid #d9ded7; border-radius: 18px; background: rgba(255,255,255,.92); box-shadow: 0 16px 40px rgba(42,64,55,.08); }
    .brand { color: #1d2a25; font: 800 22px/1 Georgia, serif; text-decoration: none; letter-spacing: -.04em; }
    .brand i { color: #e96545; font-style: normal; }
    .menu { display: flex; align-items: center; gap: 6px; margin-left: auto; padding: 0; list-style: none; }
    .menu > li { position: relative; }
    .menu a, .drop-trigger { display: flex; align-items: center; gap: 7px; padding: 11px 13px; border: 0; border-radius: 10px; color: #48554f; font: inherit; font-size: 14px; font-weight: 700; text-decoration: none; background: transparent; cursor: pointer; }
    .menu a:hover, .drop-trigger:hover, .drop-trigger[aria-expanded="true"] { color: #1d2a25; background: #f0f4ef; }
    .drop-trigger::after { content: "⌄"; color: #85928c; transition: transform .2s ease; }
    .drop-trigger[aria-expanded="true"]::after { transform: rotate(180deg); }
    .dropdown { position: absolute; top: calc(100% + 10px); left: 0; width: 270px; padding: 10px; border: 1px solid #dce1dc; border-radius: 15px; background: #fff; box-shadow: 0 20px 50px rgba(42,64,55,.16); opacity: 0; visibility: hidden; transform: translateY(-8px); transition: .2s ease; }
    .drop-trigger[aria-expanded="true"] + .dropdown { opacity: 1; visibility: visible; transform: none; }
    .dropdown a { align-items: flex-start; padding: 12px; }
    .dropdown b { display: block; color: #27352f; font-size: 13px; }
    .dropdown small { display: block; margin-top: 3px; color: #84908a; font-weight: 500; line-height: 1.4; }
    .nav-action { margin-left: 4px; padding: 11px 17px; border: 0; border-radius: 10px; color: white; font: inherit; font-weight: 800; background: #e96545; cursor: pointer; }
    .menu-toggle { display: none; margin-left: auto; width: 42px; height: 42px; border: 1px solid #dce1dc; border-radius: 10px; color: #27352f; font-size: 20px; background: white; cursor: pointer; }
    button:focus-visible, a:focus-visible { outline: 3px solid #e96545; outline-offset: 2px; }
    main { width: min(1100px, calc(100% - 40px)); margin: 0 auto; min-height: calc(100vh - 100px); display: grid; place-items: center; text-align: center; }
    .hero { max-width: 760px; }
    .eyebrow { color: #e96545; font-size: 12px; font-weight: 900; letter-spacing: .19em; }
    h1 { margin: 14px 0 18px; font: 700 clamp(44px, 9vw, 88px)/.95 Georgia, "STSong", serif; letter-spacing: -.05em; }
    .hero p { max-width: 600px; margin: auto; color: #6b7771; font-size: 17px; line-height: 1.8; }
    @media (min-width: 761px) { .has-dropdown:hover .dropdown { opacity: 1; visibility: visible; transform: none; } }
    @media (max-width: 760px) {
      nav { flex-wrap: wrap; }
      .menu-toggle { display: block; }
      .menu { display: none; flex: 1 0 100%; align-items: stretch; flex-direction: column; margin: 0; padding-top: 8px; border-top: 1px solid #e8ebe7; }
      .menu.is-open { display: flex; }
      .menu a, .drop-trigger { width: 100%; justify-content: space-between; }
      .dropdown { position: static; display: none; width: 100%; margin-top: 4px; box-shadow: none; opacity: 1; visibility: visible; transform: none; }
      .drop-trigger[aria-expanded="true"] + .dropdown { display: block; }
      .nav-action { width: 100%; margin: 4px 0 0; }
    }
    @media (prefers-reduced-motion: reduce) { .dropdown, .drop-trigger::after { transition: none; } }
  </style>
</head>
<body>
  <nav aria-label="Navigation principale">
    <a class="brand" href="#">North<i>·</i>Lab</a>
    <button id="menuToggle" class="menu-toggle" type="button" aria-expanded="false" aria-controls="mainMenu" aria-label="Développer la navigation">☰</button>
    <ul id="mainMenu" class="menu">
      <li><a href="#work">Œuvres</a></li>
      <li class="has-dropdown"><button class="drop-trigger" type="button" aria-expanded="false">Services</button><div class="dropdown"><a href="#strategy"><span><b>Stratégie de marque</b><small>Trouver une façon d’exprimer ce qui rend une marque vraiment unique</small></span></a><a href="#design"><span><b>Produits numériques</b><small>Conception d’une expérience complète, du prototype à la mise en ligne</small></span></a><a href="#motion"><span><b>Visuel dynamique</b><small>Raconter l’histoire d’un produit par le rythme et le mouvement</small></span></a></div></li>
      <li><a href="#about">À propos</a></li>
      <li><a href="#journal">Notes</a></li>
      <li><button class="nav-action" type="button">Commencer la collaboration</button></li>
    </ul>
  </nav>
  <main><section class="hero"><span class="eyebrow">INDEPENDENT DESIGN STUDIO</span><h1>Des problèmes complexes, une expression simple</h1><p>Cette navigation prend en charge le survol et le clic sur ordinateur, et se transforme automatiquement en menu déroulant sur les petits écrans. Essayez de redimensionner la fenêtre pour voir le changement.</p></section></main>
  <script>
    const menuToggle = document.querySelector('#menuToggle');
    const menu = document.querySelector('#mainMenu');
    const dropTrigger = document.querySelector('.drop-trigger');
    menuToggle.addEventListener('click', () => {
      const open = menuToggle.getAttribute('aria-expanded') !== 'true';
      menuToggle.setAttribute('aria-expanded', String(open));
      menu.classList.toggle('is-open', open);
    });
    dropTrigger.addEventListener('click', () => dropTrigger.setAttribute('aria-expanded', String(dropTrigger.getAttribute('aria-expanded') !== 'true')));
    document.addEventListener('click', event => {
      if (!event.target.closest('.has-dropdown')) dropTrigger.setAttribute('aria-expanded', 'false');
    });
  </script>
</body>
</html>
Commentaires sur la pageVous avez découvert un problème ou avez une suggestion d’amélioration ?
Les fonctions de retour nécessitent l’utilisation de la version en ligne

Veuillez activer JavaScript dans la version en ligne avant de soumettre ; les fonctionnalités locales de l’outil ou du cas ne sont pas affectées.

Aller vers la version en ligne pour envoyer des commentaires