Certains ne comprennent peut-être pas ce dont je veux parler par « menu fixe mais flottant selon la scrollbar », en fait je fais référence au nouveau menu dans Gmail qui est figé en haut mais suit la scrollbar lorsque nous descendons l’ascenseur.
Cet effet permet d’avoir toujours à disposition le menu où que nous soyons dans la lecture de nos mails.

Ça semble anodin au premier abord pour la plupart des gens, un peu de CSS, un petit « position: fixed » et le tour est joué ? hé bien non, c’est plus fort que ça, car au départ le menu est incrusté et c’est seulement lorque la scrollbar atteint un point précis (ici lorsque le haut de la fenêtre atteint le menu) que le menu devient flottant, c’est donc dynamique, à comprendre qu’il va falloir utiliser du JavaScript.
Ce menu m’a intrigué dès le départ car je ne savais pas moi-même réaliser un tel effet, jusqu’au jour où j’en ai eu besoin pour l’affichage d’un deck de type « Commander » sur MS.
Démo
En effet au niveau de la vue d’un deck, le survol de la souris sur le nom d’une carte fait afficher l’image de celle-ci sur le côté gauche. Le problème c’est que la quantité de cartes d’un deck « Commander » fait que l’image ne devient plus visible lorsque nous scrollons vers le bas pour voir l’intégralité des cartes. D’où l’idée de rendre flottante l’image de la carte lorsque la scrollbar tente de la masquer.
Code
Finalement c’est assez simple à comprendre et donc à mettre en place.
CSS
Votre élément (menu, image, bandeau, div, etc.) a rendre flottant a par défaut une position « relative » par rapport à son conteneur, cette position devra passée à « fixed » au moment où nous le choisirons, dans notre cas lorsque la scrollbar tentera de masquer notre élément.
Le changement d’état de notre élement se fera par le biais d’une classe CSS, appliquée par du JavaScript, la voici :
votre_menu_ou_votre_image_ou_votre_element.floatable {
position: fixed;
top: 10px; // non-obligatoire
}JS
Pour détecter qu’il est temps de changer la position de notre élément, il faut connaître le positionnement de la scrollbar et la comparer au positionnement de notre élément. Pour cela j’utilise la fonction $(window).scroll() de jQuery.
Voici le mécanisme à mettre en place :
// listen for scroll
var positionElementInPage = $('#votre_menu_ou_votre_image_ou_votre_element').offset().top;
$(window).scroll(
function() {
if ($(window).scrollTop() >= positionElementInPage) {
// fixed
$('#votre_menu_ou_votre_image_ou_votre_element').addClass("floatable");
} else {
// relative
$('#votre_menu_ou_votre_image_ou_votre_element').removeClass("floatable");
}
}
);Lorsque nous descendons l’image nous suit et reste visible, lorsque nous remontons, elle se recale à l’endroit du départ si nous dépassons son emplacement d’origine.
Sources
Si mes explications ne sont pas claires, voici un fichier d’exemple : menu_fixe_mais_flottant.html.
Merci pour l’article qui m’a bien servi aujourd’hui 🙂
Bonjour,
J’aimerais bien l’utiliser mais je n’ai pas de fichier menu.js.
J’ai un menu nav.menu.js dans mon wordpress , c’est tout 🙁
Des idées?
c super! ca ma vraiment aide… merci encore une fois!
ça c’est une façon d’expliquer
Vivedidi, dans l’exemple donné on teste si la scroll masque le menu pour le faire descendre, il faut dans ton cas (qui est aussi le mien sur magicsupremacy) que tu rajoutes la même chose pour ton footer et tester quand la scroll arrive au niveau de ton footer pour ne pas le masquer, quelque chose du genre :
var hauteurMenu = 30; var positionMenu = $('#votre_menu').offset().top; var positionFooter = $('#votre_footer').offset().top; $(window).scroll( function() { var scrollTop = $(window).scrollTop(); if (scrollTop >= positionMenu && scrollTop <= (positionFooter - hauteurMenu)) { $('#votre_menu').addClass("floatable"); } else { $('#votre_menu').removeClass("floatable"); } } );Bonjour,
merci beaucoup pour ce post fort utile ! Cependant je suis dans le même cas que Vivedidi, je voudrais que le position fixed que j’ai ne chevauche pas mon footer. Il faudrait donc rajouter une troisième classe (relative 2) avec en css un vertical-align bottom, jusque là ça va. Mais n’étant pas familier du javascript ou du jquery, je n’arrive pas à bidouiller une condition pour déterminer si l’élément est rendu au footer ou non …
Un peu d’aide serait la bienvenue
Merci !
Bonjour, je remonte un vieil article, j’espère avoir une réponse quand même ^^
J’ai suivi cet article, fait l’installation, fonctionne correctement, sauf que mon menu ne s’arrête pas à la fin du div contenant mon menu (le menu est dans le footer ensuite).
Je n’ai pas fais de Jquery, mais j’ai quand même tenté des truc en utilisant la position du pied de page, du scroll, ou du bas du menu, mais je n’ai pas encore trouvé.
Donc si quelqu’un pouvait m’apporter son aide, peut-être est-ce dû au code css.
j’ai bidouillé un truc, mais il doit y avoir tellement plus simple
(voir: http://carrecarre.com/newindex2.php)
Les seuls petits defaults que je trouve à redire sont
Le petit espace qui se cree au top de la balise p qui se regle en la remplacant par une div par exemple.
Et ce petit saut (de la taille de la fenetre (encore elle)) lorsqu’elle se transforme en floatable et qui recouvre les trois premiére ligne du texte en dessous
J’essaye de regler sur ma page test http://carrecarre.com/newindex2.php encore 5 minutes et je vais prendre une coupe de champagne.
merci pour l’aide et l’article.
Merci beaucoup ! C’est très clair !
Voilà, section « sources » en bas de l’article.
et bien je pense que nous attendons ca avec impatience.
merci du temps accordé
D’accord, je vais essayer de vous faire ça dans la journée, je vous tiens au courant.
je suis preneur aussi, j’aimerais bien arriver à le faire.
Bonjour,
Pourriez-vous créer un fichier d’exemple simple téléchargeable ? votre menu semble en effet très intéressant mais l’explication n’est peut-être pas très claire pour un « amateur » (comme moi).
Merci !
Merci !
Bonne continuation à vous !
Une bonne chose de faite, bonne continuation.
Je me suis creusé la tête longtemps… longtemps…
J’avais mal paramétré mon fichier css du coup il croyait que mon menu commencer tout en haut de la page. J’ai décalé mon menu et tout est rentré dans l’ordre !
$ est une fonction jQuery, il semblerait donc que tu pointes sur un fichier jQuery non disponible, le navigateur n’arrive pas à télécharger la bibliothèque jQuery, creuse de ce côté là peut-être.
$ is not defined
menu2.js()menu2.js (ligne 1)
[Stopper sur une erreur] var positionElementInPage = $(‘#menu’).offset().top;
Voila ce que ça me donne sous firebug. Elle est peut être là l’erreur mais je la comprend pas.
Non ce n’est pas pareil :
– « #menu .ok » signifie l’élément dont la classe est « ok » et dont un de ses éléments parent possède un identifiant « menu »
– « #menu.ok » signifie l’élément dont l’identifiant est « menu » et dont la classe est « ok »
Essaie de débugger avec Firebug sous Firefox, tu dois avoir une erreur quelque part.
Pour le point numéro 1, j’ai essayé mais ça ne change rien (et je pense que c’est pareil en css), et pour le point numéro 2 … c’est pareil !!
Ça m’embête mon histoire !
@Valentin : 2 pistes pour ton problème :
1/ dans ton css tu as mis « #menu .ok » au lieu de « #menu.ok » (aucun espace)
2/ essaie ensuite de charger le fichier menu.js en bas de page, juste avant le </body>
Envoyé !
Etrange, envoie-moi un zip avec ton code si tu veux, je prendrai le temps de regarder ce que tu fais.
Merci beaucoup, effectivement je l’avais oublié.
Mais ça n’a absolument rien changé, je ne comprends pas !
Bonjour Valentin, déjà il faut que tu saches si tu inclus bien la bibliothèque jQuery, si ce n’est pas le cas voici la ligne à rajouter dans ton head :
<script type= »text/javascript » src= »http://code.jquery.com/jquery-1.5.2.min.js »></script>
Retente avec ça on sait jamais.
Bonjour,
Je souhaite utiliser ce code pour mon site mais je suis incapable de le mettre en pratique.
Je n’ai pas de connaissance en javascript car je n’ai pas le temps d’apprendre pour le moment.
Ce que je fais :
– Dans mon css, j’ai deux fois mon menu (un avec « #menu » et l’autre « #menu.floatable »),
– Dans mon html j’ai une balise
– Et dans menu.js j’ai ce que vous avez écrit (var …blablabla )
Mais voilà, ça marche pas !
La raison est sûrement évidente mais je ne la vois pas.
Merci pour votre aide !
C’est pile ce que je recherchais,
infiniment : Merci 😉
+1, tous les détails comptent 😀
Sympa l’effet en pratique, en effet 🙂