Mega menú desplegable

Ejercicio para practicar habilidades de HTML y CSS. Barra Lateral minimizable para todos los dispositivos sin framework.

Podés visitar el ejercicio que desarrollaremos aquí

💻 Ver explicación en video de youtube.

HTML

 <!DOCTYPE html>
<html lang="es">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" />
   <link rel="stylesheet" href="style.css">
   <title>Barra Lateral</title>
</head>
<body class="">
     <!-- Como es un ejercicio de cápsula, nos concentraremos en la estructura HTML, los estilos necesarios para el correcto funcionamiento de la misma en todos los dispositivos y el javascript necesario.
   No lo complicaremos con variación de colores, svg,etc.   -->

   <!-- Celulares -->
   <header id="celulares">
       <button>
           <span class="material-symbols-rounded">menu</span>
       </button>
   </header>
   <!-- Escritorio -->
    <main>
       <aside class="">
           <header>
               <a href="#" id="logo"><span>🏢</span><span>LOGO</span></a>
               <button>
                   <span class="material-symbols-rounded">chevron_left</span>
               </button>
           </header>
           <div class="contenido-barra">
               <ul class="opciones">
                   <li>
                       <a href="#seccion1" class="activa" >
                           <span class="material-symbols-rounded">star</span>
                           <span>seccion1</span>
                       </a>
                   </li>
                   <li>
                       <a href="#seccion2">
                           <span class="material-symbols-rounded">home</span>
                           <span>seccion2</span>
                       </a>
                   </li>
                   <li>
                       <a href="#seccion3">
                           <span class="material-symbols-rounded">settings</span>
                           <span>seccion3</span>
                       </a>
                   </li>
                   <li>
                       <a href="#seccion4">
                           <span class="material-symbols-rounded">favorite</span>
                           <span>seccion4</span>
                       </a>
                   </li>
                   <li>
                       <a href="#seccion5">
                           <span class="material-symbols-rounded">check</span>
                           <span>seccion5</span>
                       </a>
                   </li>
                   <li>
                       <a href="#seccion6">
                           <span class="material-symbols-rounded">star</span>
                           <span>seccion6</span>
                       </a>
                   </li>
                   <li>
                       <a href="#seccion7">
                           <span class="material-symbols-rounded">star</span>
                           <span>seccion7</span>
                       </a>
                   </li>
                   <li>
                       <a href="#seccion8">
                           <span class="material-symbols-rounded">star</span>
                           <span>seccion8</span>
                       </a>
                   </li>
                   <li>
                       <a href="#seccion9">
                           <span class="material-symbols-rounded">star</span>
                           <span>seccion9</span>
                       </a>
                   </li>
                   <li>
                       <a href="#seccion10"
                       ><span class="material-symbols-rounded">star</span>
                       <span>seccion10</span
                   ></a
               ></li>
               </ul>
               <ul class="pie">
                   <li>
                       <a href="#conclusion">
                           <span class="material-symbols-rounded">help</span>
                           <span>Conclusión</span>
                       </a>
                   </li>
                   <li>
                       <a href="https://codigoenweb.com" target="_blank">
                           <span class="material-symbols-rounded">logout</span>
                           <span>Salir</span>
                       </a>
                   </li>
               </ul>
           </div>
       </aside>
       <section>
           <h1>Título principal</h1>
           <article id="seccion1">seccion1</article>
           <article id="seccion2">seccion2</article>
           <article id="seccion3">seccion3</article>
           <article id="seccion4">seccion4</article>
           <article id="seccion5">seccion5</article>
           <article id="seccion6">seccion6</article>
           <article id="seccion7">seccion7</article>
           <article id="seccion8">seccion8</article>
           <article id="seccion9">seccion9</article>
           <article id="seccion10">seccion10</article>
           <article id="conclusion">Conclusión</article>
           <footer>
               Creado por <strong>caterinaweb.net</strong>
           </footer>
       </section>
    </main>
    <script src="script.js"></script>
</body>
</html>

CSS

   *{
       margin: 0;
       padding: 0;
       box-sizing: border-box;
   }
   html{
       scroll-behavior: smooth;
       scroll-padding-top: 6rem;
   }
   a{
       text-decoration: none;
       color: inherit;
       white-space: nowrap;
   }
   ul{
       list-style: none;
   }
   button{
       background: none;
       border: none;
       cursor: pointer;
   }
   #celulares button span{
       font-size: 2.5rem;
   }
   #celulares button{
       display: none;
   }
   /* Escritorio */

   main{
       display: flex;
   }
   main aside{
       position: sticky;
       top: 0;
       left: 0;
       height: 100vh;
       width: 270px;
       /* Para que no pueda encogerse */
       flex-shrink: 0;
       background-color: white;
       border-right: 4px solid black;

       /* aplica a los hijos */
       display: flex;
       flex-direction: column;

       /* Para los futuros movimientos que agreguemos */
       transition: 0.4s ease;
   }
   /* Si la etiqueta aside tiene la clase minimizada (la agregaremos con javascript) */
   main aside.minimizada{
       width: 90px;
   }


   /* hijo 1 */
   main aside header{
       padding: 20px 18px;
       display: flex;
       justify-content: space-between;
       align-items: center;
       border-bottom: 1px solid rgba(0,0,0,0.5);
   }

   main aside header a#logo{
       font-size: 1.3rem;
       font-weight: 700;
       /* sus hijos (los 2 span) */
       display: flex;
       justify-content: center;
       align-items: center;
   }

   main aside.minimizada header a#logo span:first-child{
       font-size: 2rem;
   }
   main aside.minimizada header a#logo span:last-child{
   display: none;
   }

   main aside header button{
       height: 40px;
       width: 40px;
       position: absolute;
       right: 18px;
       background-color: #f2f2f2;
       border-radius: 0.5rem;
       /* Para centrar el chevron */
       display: grid;
       place-items: center;
       cursor: pointer;
   }
   main aside.minimizada header button{
       transform: translate(-10px,65px);
   }
   main aside header button span{
       font-size: 1.75rem;
       /* después va a girar */
       transition: 0.4s ease;
   }
   main aside.minimizada header button span{
       transform: rotate(180deg);
   }


   main aside header button:hover{
       background-color: black;
       color: white;
   }
   /* hijo 2 - contenido de la barra */
   main aside .contenido-barra{
   
       flex: 1;
       /* su altura es toda la altura del dispositivo - la parte del header */
       height: calc(100vh - 2rem);
       padding: 20px 18px;
   }
   main aside.minimizada .contenido-barra{
       transform: translateY(50px);
   }

   main aside ul{
       display: flex;
       flex-direction: column;
       gap:2px;
   }
   main aside ul a{

       /* hijos del a : los 2 span */
       display: flex;
       align-items: center;
       gap:8px;
       border-radius: 0.5rem;
       transition: 0.4s ease;
   }

   main aside ul a span{
       padding: 8px;
       text-transform: capitalize;
   }
   main aside ul a:is(:hover, .activa){
       background-color: black;
       color: white;
   }

   main aside.minimizada ul a span:last-child{
       opacity: 0;
       /* Para que apareza cuando hacemos hover */
       transform: translateX(-100%);
       pointer-events: none;
       transition: transform 0.4s ease;
   }
   main aside.minimizada ul a:hover span:last-child{
       opacity: 1;
       pointer-events: auto;
       transform: translateX(0);
       background-color: black;
       color: white;
       border-radius: 0.5rem;
       margin-left: 0.5rem;
   }

   main aside ul.pie{
       position: absolute;
       bottom: 3rem;
       left: 18px;
       width: 90%;
   }
   main aside.minimizada ul.pie{
       bottom: 6rem;
   }
   main aside.minimizada ul a:hover {
       width: 3rem;
   }


   /* Parte central */

   main section{
       width: 100%;
       padding: 0 2rem;
       max-width: 1100px;
       margin: 0 auto;
   }
   main section h1{
       position: sticky;
       top:0;
       background-color: white;
       padding-bottom: 1rem;
       padding-top: 1rem;
       border-bottom: 5px solid black;
   }

   main section article{
       background-color: #f2f2f2;
       min-height: 300px;
       margin-top: 2rem;
       width: 100%;
       border-radius: 0.5rem;
       display: grid;
       place-items: center;
       font-size: 3rem;
       text-transform: uppercase;
   }

   footer{
       margin-top: 1rem;
       text-align: right;
   }

   /* celulares */

   @media (max-width:768px) {
       header#celulares button{
           display: block;
           position: fixed;
           top:1rem;
           right: 2.5rem;
           z-index: 20;
           }
       main aside{
           position: fixed;
           top:0;
           left:-125%;
           width: 270px;
           overflow: hidden;
           border:none;
           box-shadow: 2px 2px 10px rgba(0,0,0,0.05);
           z-index: 10;
           transition: 0.4s ease;
       }
       /* Si el body tiene la clase abierti, el aside se muestra, sino está oculto */
       body.abierto main aside{
           left:0;
       }
       body.abierto main section::after{
           content: "";
           position:fixed;
           inset: 0;
           background-color: rgba(0,0,0,0.05);
           backdrop-filter: blur(15px);
           pointer-events: none;
       }
             
   }

Javascript

   const minimizar = document.querySelector('main header button');
   const barra = document.querySelector('main aside');
   const abrirMenu = document.querySelector('header button');

   const opciones = document.querySelectorAll('main aside ul a');

   minimizar.onclick = ()=>{
       if (window.innerWidth <= 768){
           //cuando estamos en celular, con un click en ese ícono el menú cierra.
           document.body.classList.remove('abierto');

       }else{
           barra.classList.toggle('minimizada');

       }

   }

   abrirMenu.onclick=()=>{
       document.body.classList.toggle('abierto');
   }

   window.addEventListener('resize',()=>{
       if (window.innerWidth <= 768){
           barra.classList.remove('minimizada');
       }
   });

   opciones.forEach((opcion)=>{
       opcion.addEventListener('click',()=>{
           //1- Le quitamos la clase activa a todos
           opciones.forEach(cadauna=>cadauna.classList.remove('activa'));
           //2- Se la ponemos a la que se le hizo click
           opcion.classList.add('activa');
           if(window.innerWidth <= 768){
               document.body.classList.remove('abierto');
           }
       })
   })

Recursos

Íconos: https://fonts.google.com