Layouts – One Page Layout avec Top Menu (menu en tête de page)

LEÇON PRATIQUE

 

Caractéristiques

Tout le contenu du site est sur une seule page web. Les éléments dans le menu déclenchent du code JavaScript / jQuery pour activer l'ascenseur (scroll) et accéder de façon "automatique" à la section de la page qui correspond. Le mouvement de la page est implémenté de façon "lisse" - c'est à dire on accélère le scroll au départ, et on décélère à la fin pour arriver à la section doucement : c'est beaucoup plus esthétique.

 

onepagelayout-basic-topmenu-screenshotOne Page Layout - Top Menu

Page en ligne : Ouvrir

Code source (fichier ZIP) : Télécharger

 

Comment ça marche ?

Pour le scroll "automatique" :

  • on exploite la fonction "animate" de jQuery pour animer la propriété "scrollTop" du document.
  • cette animation est déclenché par un clic sur un lien dans le menu
  • les liens de menu sont retrouvés par le JavaScript / jQuery car ils ont tous le même format : src="#section-1", src="#section-2", etc)
  • la section dans la page a retrouver via le scroll est la section avec l'identifiant qui correspond à la valeur dans le lien

La mise en place du menu :

  • le menu est en "position:fixed" pour être toujours en tête de page
  • le menu (div avec id='#menu') étant donc un élément hors-flux on a besoin d'une autre div (id='#menu-margin') pour bouffer du flux à sa place en haut de page. La div #menu-margin est présent pour occuper l'espace derrière le menu en tête de page, et ainsi éviter que la première section de la page puisse passer derrière le menu.
  • responsive design : le menu est redimensionné via JavaScript / jQuery pour avoir toujours les bonnes dimensions par rapport à l'écran
  • il y a quelques instructions CSS de type "@media queries" pour gérer le responsive design aussi (instructions plus ou moins classiques)

 

HTML


    <body>

        <div id="wrapper">

            <div id="menu">
              <ul>
                <li><a href="#section-1">Viverra Lorem</a></li>
                <li><a href="#section-2">Cursus Vitae</a></li>
                <li><a href="#section-3">Rhoncus Sodales</a></li>
                <li><a href="#section-4">Inceptos Himenaeos</a></li>
              </ul>
            </div>

            <div id="menu-margin"></div>

            <div class="content" id="section-1">
                ...
            </div>

            <div class="content" id="section-2">
                ...
            </div>

            <div class="content" id="section-3">
                ...
            </div>

            <div class="content" id="section-4">
                ...
            </div>

        </div>

    </body>

 

CSS


#menu
{
  position:fixed;
  top:0;
  left:auto;
  background-color:#191919;
  border-bottom:1px solid #444444;
}

...

#menu-margin
{
  height:0; /* sera recalculé par le javascript/jquery */
}

...

@media screen and (max-width: 1000px)
{
  #menu ul li
  {
    display:block;
    width:inherit; /* l'élément li prend la largeur du premier parent dimensionné (#menu) donc aura la largeur de la page */
    margin:0;
  }
}

 

JavaScript / jQuery


          function setMenuDimensions()
          {
            $('#menu').width($('#wrapper').width());             /* faire en sorte que la largeur de '#menu' soit toujours égale à la largeur de '#wrapper' */
            $('#menu-margin').height($('#menu').height() + 20);  /* #menu étant un élément hors-flux on a besoin de #menu-margin pour bouffer du flux à sa place en haut de page. */
                                                                 /* Ceci est pour éviter que les premiers contenus s'affichent derrière le menu. Les pixels en plus sont de la marge */
                                                                 /* entre le menu et les premiers contenus. */
          }

          $(window).load(function() {
            setMenuDimensions();                                                      /* établir les dimensions initiales du menu */
            $('a[href^="#"]').on('click',function (e) {                               /* definir l'action suite à un clic sur lien avec dièse (liens menu) */
              e.preventDefault();                                                     /* faire en sorte que l action par défaut ne soit pas déclenchée */
              var target = $(this.hash).offset().top - $('#menu-margin').height();    /* calculer la distance Y du haut de la page vers la section cible, décalé pour #menu-margin */
              $('html, body').stop().animate( { 'scrollTop': target }, 750, 'swing'); /* arrêter toute animation en cours puis animer le scroll vers le cible avec effet swing */
            });
          });

          $(window).resize(function() {
            setMenuDimensions(); /* quand la fenêtre est retaillée on refait les dimensions du menu */
          });