Lección 9: Menú | Curso de Maquetación Web

Lección 9: Menú

En la siguiente lección, o código de ejemplo, crearemos un completo menú Responsive Design que se adapta tanto a escritorio como smartphone. Cuando se encuentra en una resolución reducida podrás visualizar un botón hamburguesa que despliega un menú a pantalla completa del navegador. Mientras que en escritorio se ensancha ocupando todo el espacio disponible, colocando el logo a la izquierda y el navegador a la derecha en dirección horizontal.

Empezaremos con una buena estructura del HTML, siguiendo un buen orden y usando etiquetas de contenido como <header> o <nav> y una lista desordenada para estructurar el menú, se construye la base en la cual trabajaremos con el CSS más adelante.

Adicionalmente, y siempre de manera opcional, se ha añadido un minimalista framework de JavaScript, denominado AlpineJS, para gestionar los eventos. Se debe a que tenemos 2 clics en smartphone que deben añadir o quitar la clase nav--show. Un modificador encargada mostrar u ocultar el menú. Puedes usar JavaScript plano si tienes cierta experiencia.

Deberemos añadir en el <head> algunos metas importantes.

<!-- Desactivar el zoom del viewport -->
<meta
    name="viewport"
    content="width=device-width, initial-scale=1.0, shrink-to-fit=no"
>
<!-- Normalizador CSS -->
<link
    rel="stylesheet"
    type="text/css"
    href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css"
>
<!-- AlpineJS -->
<script src="https://unpkg.com/alpinejs" defer></script>

Nuestro HTML quedaría de la siguiente forma:

<header
    class="header"
    x-data="{
           show: false,
           isUpScroll: true,
           lastPosScroll: 0
    }"
    @scroll.window="window.pageYOffset > lastPosScroll ? (isUpScroll = false, lastPosScroll =  window.pageYOffset) : (isUpScroll = true, lastPosScroll =  window.pageYOffset)"
            :class="isUpScroll ? '' : 'header--hide'"
>
    <div class="container">
        <a href="/" class="link" role="heading" aria-level="1">
            Tu logo
        </a>
        <button class="is-in-mobile button header__open" @click="show = true">Abrir</button>
        <nav class="nav" :class="show ? 'nav--show' : ''">
            <button class="is-in-mobile button header__close" @click="show = false">Close</button>
            <ul class="ul-reset nav__ul">
                <li class="nav__item"><a class="link nav__link" href="#">Inicio</a></li>
                <li class="nav__item"><a class="link nav__link" href="#">Sobre mi</a></li>
                <li class="nav__item"><a class="link nav__link" href="#">Portafolio</a></li>
                <li class="nav__item"><a class="link nav__link" href="#">Blog</a></li>
                <li class="nav__item"><a class="link nav__link" href="#">Contacto</a></li>
            </ul>
        </nav>
    </div>
</header>

Los atributos x-data, @scroll.window y :class son propios de AlpineJS. Se utilizan para gestionar cuando debe aparecer y desaparecer las clases nav--show (mostrar/ocultar el navegador en smartphone) y header--hide (mostrar/ocultar <header> según haga scroll).

Presta atención como se ha convertido el hipervínculo del logo en un <h1> para mantener una coherencia con las cabeceras de la web.

Ahora vamos a implementar los estilos CSS:

:root {
    /* Colors */
    --color-black: #000;
    --color-white: #fff;
    --color-primary: orange;
    --color-secondary: purple;

    /* Gaps */
    --gap-s: 0.9rem;
    --gap-m: 1rem;
    --gap-l: 1.5rem;
    --gap-xl: 2rem;
    --gap-xxl: 3rem;
}

/* Componentes */
.ul-reset {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  padding: 0;
}

.link {
  display: inline-block;
  color: inherit;
  text-decoration: none;
}

.container {
    margin-inline: auto;
    max-width: 1000px;
    padding: 1rem;
}

.is-in-mobile {
    display: none;
    @media (width < 600px) {
        display: inherit;
    }
}

/* Header */

.header {
    position: fixed;
    inset: 0 0 auto;
    background-color: var(--color-primary);
    color: var(--color-white);
    transition: .5s;

    &.header--hide {
        transform: translateY(-12rem);
    }

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

    .nav__link {
        padding-inline: var(--gap-m);
    }

    @media (width < 600px) {
        .nav {
            display: grid;
            grid-template-columns: 1fr;
            grid-template-rows: var(--gap-xl) 1fr;
            position: fixed;
            inset: 0;
            transform: translateX(-100vw);
            transition: .5s;
            background-color: var(--color-secondary);
        }

        .nav--show {
            transform: translateX(0);
        }

        .nav__ul {
            flex-direction: column;
            justify-content: center;
            align-items: center;
        }

        .nav__link {
            padding: var(--gap-l);
        }
    }
}

.main {
    margin-top: 6rem;
}

Y con esto, ya tenemos un menú de navegación adaptable a cualquier dispositivo.

Si quieres obtener más información sobre otros tipos menús de navegación, puedes visitar los siguientes tutoriales:

Esta obra está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional.

Atribución/Reconocimiento-NoComercial-SinDerivados 4.0 Internacional

¿Me ayudas?

Comprame un café
Pulsa sobre la imagen

No te sientas obligado a realizar una donación, pero cada aportación mantiene el sitio en activo logrando que continúe existiendo y sea accesible para otras personas. Además me motiva a crear nuevo contenido.

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario