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
⇒ Changez votre adresse IP et accédez aux contenus bloqués ou géo-restreints partout dans le monde
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.
J’ai regardé rapidement, il ne devrait pas avoir de position fixed dans ton css pour ton menu en tout . La class qui fixed le menu est à appelé avec le bout de code jQuery mis plus haut ..
Effectivement jQuery est chargé bizarrement, remplace les $ par jQuery dans ton script que tu viens de déplacer.
Mimie, mille merci pour cette précision, pas évident de s’en sortir au début.
J’ai déplacé le javascript et je ne vois pourtant aucun changement ?
Lut Vydja, ton javascript doit être placé avant la fermeture de la balise body (tout en bas de page) et non tout au début …
Je ne vois pas ton code, par contre je suis sur ton blog, je regarde et te redis si je trouve l’erreur
;D
J’ai envoyé un message plus haut où je donnais tout mon code, mais je ne sais pas s’il est passé.
J’ai finalement réussi à enlever les caractères spéciaux affichés sur la page.
Je souhaiterais simplement de l’aide pour ce qui est du menu fixe.
Désolée pour le nombre de messages ! 😉
Ah, et Vydja = Diane ! Scuse, je me suis emmêlée les pinceaux dans mes pseudos.
c’est en réponse à Vydja. Diane, il faudrait que je puisse voir ton code…
Tu as du surement laissé un caractère inattendu.. Regarde ce que tu as écrit. Tu as peu être oublier de fermer une balise ou quelque chose de ce genre. .. Je peux voir le bug ?
Rebonjour,
j’ai fait une grosse bourde dans mon code que je ne sais pas réparer, et sur mon blog s’affiche un pavé de code.
Help !
Bonjour,
je bloque complètement depuis quelques heures sur mon menu en haut de page.
C’est la première fois que j’utilise jQuery donc j’ai sûrement fait une erreur quelque part.
Pouvez-vous m’aider ?
Merci 🙂
sinon tu ne trouve pas. .. il te suffit de rajouter une bordure à ton menu qui est au dessus de l’autre.
border-width: 0 0 1px; (épaisseur du tracé, ici en bas)
border-style: solid; (type de tracé)
border:color: red; (couleur du tracé)
pour plus de détails : http://www.w3schools.com/css/css_border.asp
ok, Merci beaucoup Benjamin 🙂 🙂
tu devrais lire l’article que je t’ai mise en lien, il te serait pas mal utile pour faire ce que tu souhaite.. il y a des exemples pour que tu comprennes les possibilités des margin, padding,etc.
solution magicien :
il faut que tu comble l’écart entre tes deux menus par une ligne de couleur qui correspond à ton arrière plan.. et on ne verra plus le contenu au travers tes menus.. par exemple avec une div et un padding…
bon, en fait, mon pb c’est que j’ai 2 menus en haut de ma page, ok? et entre les 2 menus il y a un petit espace à travers lequel on peut voir le bckground.
je veux que le défilement s’arrête juste avant le 2ème menu (celui en bas) . quand je fixe le margin à 0, les deux menus seront collés , alors que moi je désire garder le petit espace
🙂
Ok… là j’ai compris ! 😀
En fait tu vois dans l’exemple, il n’y a pas de règles de margin sur pou les autres éléments du coup par défaut une marge est créée pour tout le monde. .. pour qu’il n’y ait plus cette espace/marge il faut que tu rajoute margin: 0 auto; le 0 pour les marges hautes et basses et l’auto pour la gauche et la droite. ..
si tu veux tu peux regarder l’article : http://www.alsacreations.com/article/lire/629-fusion-des-marges.html
bon, ok, j’essaie de me faire comprendre 🙂
Dans cet exemple https://desgeeksetdeslettres.com/sources/menu_fixe_mais_flottant.html, lorsqu’on défile, on voit le texte « bloblo » touuuut en haut de la page (au dessus de « Mon texte fixe »), moi je veux qu’il disparaisse. je veux que le défilement s’arrête juste avant « Mon texte fixe ».
j’espère être claire 🙂
merci bcp.
Je ne suis pas sûr d’avoir compris, le menu doit rester au dessus du contenu ? j’avoue ne pas vraiment comprendre.
.. .essaie de rajouter un z-index : 50 (par exemple) à ton menu, il devrait passer au dessus de ton contenu ..
Sinon rajoute une marge à ton contenu pour faire la différence de hauteur conteneur/menu.. .
Vu que je ne suis pas certain d’avoir compris ce que tu demandais je réponds un peu au pif. . Bon courage
bonjour
merci pour l’article, sauf que j’ai un petit soucis, je souhaite que mon contenu s’arrête juste au dessous de mon menu, c-à-d que lorsque je défile, mon contenu ne passe pas derrière mon menu, ça défile et puis ça disparait, je ne le vois pas passer au dessus du menu.
j’espère avoir été claire 🙂 🙂
Merci pour ta réponse, Mars.
@Loïc
Je viens de réussir à le faire fonctionner dans un WordPress. Je passe par les mêmes étapes que toi, à savoir :
– dans header.php, dans le « head» de la page, j’ajoute un appel à la bibliothèque jQuery (1.7.1.min.js pour avoir comme dans la demo) vérification faite, il le faut.
– toujours dans header.php, la «div id= »#navbar » class= » navbar »» de mon thème devient une «div id= »#navbar » class= » »»
– dans style.css je crée une #navbar.floatable { avec les instructions qui vont bien}
-dans footer.php je copie le script juste avant «/body»
J’avais plantage sur plantage avant de voir que Firebug me renvoyait une synthax error :
dans le javascript j’avais (recopié)
if ($(window).scrollTop()
& g t ;
= positionElementInPage) {
alors qu’il faut
if ($(window).scrollTop() >= positionElementInPage) {
comme tu peu le voir sur la démo.
depuis ça marche, j’ai même ajouté une condition pour afficher 28px plus bas pour les admins à cause de la barre (que je masque pour les autres utilisateurs).
J’aimerai utiliser cette fonction pour mon site mais je rencontre des difficultés…
Je travail sur un WordPress, et il semble que le script ne soit pas prit en compte car le navigateur affiche par default le CSS de menu-float.floatable {position:fixed} et non menu-float {…}.
voici se que j’ai fait :
– j’ai modifié le fichier header.php en y appelant dans le head:
– ensuite dans le fichier footer.php, juste avant le j’appel la fonction :
// listen for scroll
var positionElementInPage = $(‘#menu-float’).offset().top;
$(window).scroll(
function() {
if ($(window).scrollTop() >= positionElementInPage) {
// fixed
$(‘#menu-float’).addClass(« floatable »);
} else {
// relative
$(‘#menu-float’).removeClass(« floatable »);
}
}
);
– enfin j’ai défini mes 2 étapes dans le CSS :
#menu-float{
margin: 0 auto;
max-width: 1600px;
width: 100%;}
#menu-float.floatable {
position: fixed;
top: 0; // non-obligatoire
}
Ma question est donc pourquoi le script ne se déclenche pas? y’a t’il une déclaration spécifique pour les wordpress?
Merci de votre aide !
Super !
Merci beaucoup.
Bonjour Thomas,
Pour que ton menu garde la même largeur il faut que tu modifie le css de ta div enfant de ta Div menu. Donner une largeur à la div enfant par exemple, margin : 0 auto.. .
MERCI !!! SUPER
Bonjour,
Tout d’abord merci pour l’article cependant je rencontre deux problèmes :
1 : TypeError: jQuery(…).offset(…) is undefined
Du coup pour pouvoir tester le reste j’ai remplacer la variable » positionElementInPage « , par une valeur fixe mais j’aimerais tout de même réussir à récupérer la position de ma div à l’aide d’une fonction (ça fait plus propre).
2 : Le css est modifié.
Je m’explique, sur le principe ça fonctionne, mais quand je j’appelle » .addClass(« floatable »); « , cela modifie le design de ma page. En effet, je suis censé avoir un menu qui ne prend pas toute la largeur de ma page, mais dans ce cas, ma barre de menu s’agrandit et prend toute la largeur…
Si quelqu’un pourrait me donner des conseils/indices pour résoudre mes problèmes, ça serait vraiment sympa.
En vous remerciant par avance,
Bonjour,
merci beaucoup pour ce tuto, cependant je rencontre un petit problème. J’utilise le CMS Joomla (1.5), et je suis parvenu à faire fonctionner ce script, mais uniquement sur ma page d’accueil… Si je navigue dans une autre page du site, le menu ne se déplace plus… Auriez-vous une idée ?
Merci d’avance
Bonjour, j’ai essayé de suivre les étapes mais sans succès. Voici ce que j’ai effectué :
dans mon .tpl :
// listen for scroll
var positionElementInPage = $(‘#content_prices’).offset().top;
$(window).scroll(
function() {
if ($(window).scrollTop() >= positionElementInPage) {
// fixed
$(‘#content_prices’).addClass(« floatable »);
} else {
// relative
$(‘#content_prices’).removeClass(« floatable »);
}
}
);
Source article : https://desgeeksetdeslettres.com/programmation-java/menu-fixe-mais-flottant-selon-la-scrollbar-js-css#ixzz2bIBWLtkv
et dans mon .css :
.content_prices {
/*margin-top:-110px;
padding-top:10px;
/*border-top:1px solid #ccc; */
/*text-align:right;
width: 125px ;
float: right;
margin-left:600px; */
/*margin-top: 5px; */
/*padding: 10px; */
/*position: fixed;*/
/*border: 1px solid #CCCCCC; */
float: right;
text-align: right;
width: 178px;
height: 0px;
/*position: relative;*/
margin-left: 573px;
}
.content_prices.floatable {
position: fixed;
}
Super, très bien, exactement ce qu’il me fallait !!
J’ai mis le paquet de texte dans une div et j’ai un un petit souci de largeur du texte mais cela passe très bien quand même.
Merci
Bonjour,
Très bonne ressource, qui fonctionne chez moi.
Je cherche maintenant à borner le menu une seconde fois en bas (pour ne pas empiéter sur le footer).
Les modification que j’ai faites fonctionnent mais uniquement sous firefox (et pas sous chrome), et de manière stroboscopique… c’est décoiffant 🙂
Avez vous déjà réalisé un menu flottant doublement borné ? Si oui je suis preneur d’infos.
Dans tous les cas je suis à votre disposition pour vous fournir mon code (qui n’a pas de place dans un commentaire à mon sens).
Bonne journée,
Etienne
Un grand grand merci !!!
Merci pour ce script très simple à mettre en place surtout pour un débutant comme moi.
Cependant je rencontre un problème gênant: selon la résolution de l’écran le menue ce déplace.
Existe il une façon de corriger ce problème, sachant que je suis débutant en CSS.
Merci pour ton aide. Exact, ma page est en mode Quirks et effectivement cela fonctionne avec les bons modes de document. Le soucis c’est que mes pages ont été faites avec frontpage (avec des tableau et du css bidouillé ) et que je n’ai que ça en haut de ma page :
Pas de doctype…
En mettant en normes IE9, ça fonctionne mais mon disign de site est alors … ravagé :/
Bref, je suis un peu coincé …
Chez moi cela fonctionne bien (testé IE9 et IE10), vérifie bien que le « Mode navigateur » soit IE9 et que le « Mode de document » soit aussi en « normes IE9 » ou « normes » tout court.
Tu appuies sur F12 pour voir apparaître tout ça.
Bonjour
Sur firefox ok, safari ok, IE 9 : marche pas :/ Vraiment dommage…
Idem pour cette page : https://desgeeksetdeslettres.com/sources/menu_fixe_mais_flottant.html
Une solution pour IE ?
C’est ce que je cherchais big thx to you
Bon, et bien, j’ai trouvé une petite bidouille.
J’ai crée un deuxième élément « fantome » qui prend la place du premier quand celui ci sort du flux.
Au cas où certains auraient le problème, voilà l’idée :
CSS :
#infoGhost{
width:100%;
display:none;
}
JS :
var fixedLimit = $(‘#info’).offset().top;
$(‘#infoGhost’).css(‘height’, $(‘#info’).height() + ‘px’);
$(window).trigger(‘scroll’);
$(window).scroll(function(event){
if($(window).scrollTop()>= fixedLimit){
$(‘#info’).addClass(‘fixed’);
$(‘#infoGhost’).show();
}else{
$(‘#info’).removeClass(‘fixed’);
$(‘#infoGhost’).hide();
}
});
Bonjour,
Tout d’abord, merci pour ce petit bout de code.
Petite question tout de fois. Mon élément que je passe en « fixed » n’est pas un élément placé sur le côté de ma page mais bien dans le corps de mon site. Du coup, en le positionnant en fixe et donc en le faisant sortir de mon flux, le scroll se refait automatiquement car la taille verticale de ma page se modifie.
Et là, j’ai un problème, car lorsque cela se produit, il passe tour à tour dans les deux conditions (à savoir supérieur à la limite, et inférieur ensuite), ce qui ajoute et enlève la classe, et empêche le scroll de ma page. Je ne rencontre pas le problème lorsque la taille de ma page est plus importante mais vu qu’elle est de taille variable, cela peut se produire.
Je ne sais pas si c’est très clair, et je ne peux pas montrer d’exemple en ligne pour le moment. Mais, quelqu’un aurait une idée pour résoudre ca ?
Bonjour,
Merci pour le code et le tuto !
Par contre je n’arrive pas à le faire fonctionner avec wordpress. Une idée pour m’aider ?
Merci 🙂
Salut, j’adore ce petit code, mais j’ai un petit problème lors de l’implémentation, les navigateurs bloque sur cette erreur « var positionElementInPage = $(‘#menuprincipal’).offset().top; Uncaught TypeError: Cannot read property ‘top’ of undefined » à tu une idée de la solution ?!
#menuprincipal.floatable {position:fixed;top:0;}
// listen for scroll
var positionElementInPage = $(‘#menuprincipal’).offset().top;
$(window).scroll(
function() {
if ($(window).scrollTop() >= positionElementInPage) {
// fixed
$(‘#menuprincipal’).addClass(« floatable »);
} else {
// relative
$(‘#menuprincipal’).removeClass(« floatable »);
}
}
);