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