Also available in: English
J’ai bossé récemment sur plusieurs sites web, et la requête d’un menu sticky était quasiment systématique. Parfois elle était justifiée, parfois je me rapprochais du contre-exemple ergonomique stéréotypé. (Dois-je utiliser un sticky menu ?) Mais quand même ! Je vous propose de voir ensemble comment on peut faire ça.
Concept du menu sticky
J’aime bien partir d’une idée et poser quelques éléments par écrit pour ne pas partir tête baissée dans le code. Dans un premier temps, nous sommes tous d’accord sur la définition du menu sticky ? C’est ce truc qui colle au haut (souvent) de la page lorsque l’on scroll vers le bas.
Je veux bien diviser le fond (HTML), la forme (CSS) et les interactions (JS), et dans cet ordre là précisément. Je vais donc m’interdire toute forme d’animation ou de positionnement en JS, je vais utiliser CSS pour cela.
Le comportement attendu est celui-ci : J’ai un en-tête avec un logo et un menu qui sont « classiquement » positionnés. Au delà d’un certain seuil de scroll (descente) dans la page, je veux ré-afficher le menu à l’utilisateur pour lui permettre un accès plus rapide. Dans un premier temps, la valeur de scroll sera arbitraire (définie manuellement par nos soins), puis dans un second temps nous ferons en sorte que le menu n’apparaisse que lorsque le scroll aura passé un certain élément dans la page. Enfin, nous verrons également une variante où le menu ne réapparait que si l’utilisateur remonte dans la page.
Nous aurons à la fin quelque chose dans ce goût :
La structure de notre menu sticky
Je vous invite à utiliser cette structure de menu, et éventuellement à copier/coller le Lorem Ipsum de ma page de démonstration pour avoir du contenu et pouvoir scroller dans votre page.
<header id="header" role="banner" class="main-header">
<div class="header-inner">
<div class="header-logo">
<img src="logo.png" alt="Creative Juiz" width="150" height="45">
</div>
<nav class="header-nav">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">Our projects</a></li>
<li><a href="#">About us</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
</div>
</header>
J’utilise l’élément <header>
avec le role banner
pour définir l’en-tête de ma page. Le reste est assez classique. Il est important de noter que l’identifiant (header
) va me servir ici en JS afin d’accéder rapidement à l’élément.
Les styles de notre sticky menu
Ces styles vont être assez sommaires et ne traitent pas le cas du responsive. Dans l’idéal, l’aspect sticky ne devrait être « activé » que sur des écrans assez larges et hauts pour éviter de gêner la visibilité du contenu.
Commençons par faire un mini reset de certains styles :
/* micro reset */
* {
box-sizing: border-box;
}
html, body, ul {
padding: 0; margin: 0;
}
Puis à définir nos styles de base. Je vais utiliser les couleurs de mon blog, faites comme vous le souhaitez, bien entendu.
/* Quelques styles de base */
body {
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
line-height: 1.75;
color: #F1EEDD;
background: #B13C2E;
}
.main-header {
color: #B13C2E;
background: #FFF;
}
Vous pouvez actualiser votre page dans votre navigateur si vous suivez le tutoriel au fur et à mesure, comme cela vous verrez précisément les modifications que nous faisons.
Nous allons maintenant placer nos éléments sur la même ligne. Au lieu d’utiliser le positionnement en flottant, j’ai décidé d’utiliser table layout pour cette fois. Il serait également possible d’utiliser flexbox, mais il faut bien faire un choix 🙂
/* Les éléments sont placés l'un à côté de l'autre */
.header-inner {
display: table;
width: 100%;
max-width: 1100px;
margin: 0 auto; /* on centre l'élément */
padding: 20px 25px; /* on ventile un peu */
}
.header-inner > * {
display: table-cell;
vertical-align: middle;
}
En utilisant ce positionnement en tableau sans utiliser table-layout: fixed;
sur le parent, les cellules vont se dimensionner suivant le contenu de chacune. Profitons-en !
Il va maintenant falloir passer notre liste de liens sur une seule ligne et espacer un peu les items les uns des autres. Il faut également que nous alignions le menu à droite. Je vais vous montrer une astuce pour éviter d’utiliser la propriété float
.
/* Alignement du menu */
.header-nav {
text-align: right;
}
/*
Faire passer le menu en inline (inline-block, inline-table ou inline-flex) pour le rendre sensible à l'alignement à droite. Ses items aussi sont en inline.
*/
.header-nav ul,
.header-nav li {
display: inline;
list-style: none;
}
.header-nav a {
position: relative;
display: inline-block;
padding: 8px 20px;
vertical-align: middle;
font-weight: 300; /* entre regular et light */
letter-spacing: 0.025em;
color: inherit;
text-decoration: none;
}
Sur les liens, j’ai décidé de faire une petite animation au survol (et focus) : un trait de la taille du mot va venir s’ajouter en remontant vers le mot en fondu. Pour cela je vais utiliser un pseudo-élément :after
pour générer un trait.
/* Animation du lien */
.header-nav a:after {
content: "";
position: absolute;
bottom: 0; right: 20px; left: 20px;
height: 2px;
background-color: #B13C2E;
/* Préparation de notre animation */
opacity: 0;
transform: translateY(5px);
transition: all .4s;
}
/* Le trait va remonter et apparaitre */
.header-nav a:hover:after,
.header-nav a:focus:after {
opacity: .6;
transform: translateY(0);
}
/* Je vire outline car juste au-dessus je définis un style :focus */
.header-nav a:focus {
outline: none;
}
Voilà, nous avons globalement un header minimaliste au goût du jour et l’aspect sticky de notre menu va pouvoir être travaillé grâce à du JS. Mais avant cela, petite parenthèses.
Menu sticky : la propriété CSS position: sticky;
La propriété CSS position
et sa valeur sticky
ont été introduites en CSS Level 3 mais a eu beaucoup de mal à être implémentée dans nos navigateurs, et encore aujourd’hui (à l’heure où j’écris ces lignes) seuls Firefox 32+ (et 41+ pour Android), Safari 6.1+ (préfixe -webkit-, et Safari iOS 6.1+) le supportent.
Chrome a fait une tentative entre les versions 23 et 36 sous la forme d’option d’expérimentation à activer (flag), mais a retiré ce flag en version 37, depuis plus de nouvelle.
Cette valeur de propriété est un mélange de la valeur fixed
et de la valeur relative
.
En effet, lorsque vous utilisez la valeur fixed, vous sortez l’élément du flux, c’est à dire que l’élément que vous positionnez va voir sa « boîte » sortie du calcul de positionnement général des éléments les uns par rapport aux autres. Autrement dit, vous passez cet élément sur un nouveau plan, il n’est alors plus compté sur son plan d’origine où les autres éléments vous faire leur petite vie sans lui.
Si vous voulez faire un essai dans votre navigateur voici une petite explication (5 min) en vidéo.
Voici le code utilisé :
/* Si seulement ça suffisait */
.main-header {
position: sticky;
top: 0;
}
Mais nous n’allons pas l’utiliser pour la suite de ce tutoriel.
Un peu de JavaScript !
Le JavaScript présenté ici est dit « Vanilla », c’est à dire que le code est fonctionnel nativement dans vos navigateurs et n’a pas besoin de jQuery pour fonctionner. Mais il peut quand même fonctionner si vous utilisez une bibliothèque JS.
Ce code est normalement fonctionnel à partir de IE8 (non testé), mais j’ose espérer que plus aucun de mes lecteurs ne supportent ce navigateur. (je dis ça pour votre bien et celui de vos clients)
Pour commencer, dans votre document JS, inscrivez ce polyfill de requestAnimationFrame()
.
/*
RequestAnimationFrame Polyfill
http://paulirish.com/2011/requestanimationframe-for-smart-animating/
http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
by Erik Möller, fixes from Paul Irish and Tino Zijdel
MIT license
*/
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if ( ! window.requestAnimationFrame ) {
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if ( ! window.cancelAnimationFrame ) {
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}
}());
Je ne vais pas détailler ce code, mais pour faire court si votre navigateur ne reconnaît pas les fonctions natives requestAnimationFrame()
et cancelAnimationFrame()
, nous les créons sur la base d’un setTimeout()
. Nous avions déjà vu une méthode similaire sur l’article : Un onresize
ou onscroll
plus performant en JS.
Commençons par écrire notre code en le protégeant. Ci-dessous, w
et d
correspondent à window
et document
:
(function(w,d,undefined){
// ici le code JS qui va suivre
}(window, document));
Le code que l’on va ainsi exécuter sera protégé des autres scripts pour éviter les conflits.
Placez donc le code qui suit à la place du commentaire du code précédent.
var el_html = d.documentElement,
el_body = d.getElementsByTagName('body')[0],
header = d.getElementById('header'),
menuIsStuck = function() {
// Nous allons compléter notre code ici
},
onScrolling = function() {
// on exécute notre fonction menuIsStuck()
// dans la fonction onScrolling()
menuIsStuck();
// on pourrait faire plein d'autres choses ici
};
// quand on scroll
w.addEventListener('scroll', function(){
// on exécute la fonction onScrolling()
w.requestAnimationFrame( onScrolling );
});
Voyons ce code ensemble.
Les 11 premières lignes (le premier gros bloc) servent à déclarer quatre variables, dont deux sont en fait des fonctions.
el_html
correspond au nœud <html>
et header
est le nœud de notre en-tête que nous allons positionner en sticky par la suite.
La fonction menuIsStuck
va nous permettre de faire les calculs de positionnement dans la page pour coller/décoller notre en-tête au bon moment. C’est dans cette fonction que nous placerons le prochain bout de code JS.
La fonction onScrolling
va se déclencher au moment du scroll dans la page, et exécutera à son tour la fonction menuIsStuck
. J’ai l’habitude d’encapsuler certaines fonctions dans une plus globale, notamment lorsque j’ai besoin d’exécuter plusieurs fonctions lors du même évènement, et/ou lorsque certaines variables sont partagées entre les fonctions.
Le bloc qui suit sert à déclarer l’écouteur d’évènement, ici pour l’évènement scroll
. Dès qu’un scroll est effectué, la fonction requestAnimationFrame()
va exécuter la fonction onScrolling
. Cette première fonction permet d’exécuter aussi souvent que possible une action suivant les capacités du navigateur.
Complétons notre fonction menuIsStuck
en remplaçant le commentaire par ce code :
var wScrollTop = w.pageYOffset || el_body.scrollTop,
regexp = /(nav\-is\-stuck)/i,
classFound = el_html.className.match( regexp ),
navHeight = header.offsetHeight,
bodyRect = el_body.getBoundingClientRect(),
scrollValue = 600;
// si le scroll est d'au moins 600 et
// la class nav-is-stuck n'existe pas sur HTML
if ( wScrollTop > scrollValue && !classFound ) {
el_html.className = el_html.className + ' nav-is-stuck';
el_body.style.paddingTop = navHeight + 'px';
}
// si le scroll est inférieur à 2 et
// la class nav-is-stuck existe
if ( wScrollTop < 2 && classFound ) {
el_html.className = el_html.className.replace( regexp, '' );
el_body.style.paddingTop = '0';
}
Nous avons ici trois blocs principaux de code : une déclaration de variables diverses et variées, et deux contrôles.
La déclaration réunit tous nos besoins en calculs et variables.
wScrollTop
est la position de notre scroll dans la page.regexp
permet d’enregistrer l’expression régulière qui va nous permettre de détecter la classe CSSnav-is-stuck
que nous allons utiliser.classFound
enregistre si oui ou non l’élément HTML est porteur de notre classe CSS.navHeight
enregistre la hauteur de notre header (oui ça peut varier).bodyRect
nous retourne plusieurs valeurs liée à notre élément body (comme la largeur, la hauteur, la position dans la page, etc.).scrollValue
est la distance que nous avons choisi pour déclencher l’effet sticky, c’est à dire ici 600px.
Une fois ces variables enregistrées ou mises à jour (elles le seront pour certaines à chaque mouvement de scroll), nous effectuons deux contrôles qui ne peuvent théoriquement pas être « vrais » en même temps.
Le premier contrôle permet de vérifier lorsque l’on arrive au seuil de scroll que l’on a déclaré. Dès que c’est le cas, on ajoute la class nav-is-stuck
sur l’élément HTML et on ajoute un padding
à body
équivalent à la hauteur du header. En effet si nous ne faisons pas cet ajout de padding
, nous allons nous retrouver avec un effet du bord (un saut bizarre) dû à la sortie du flux du header. (voir la vidéo ci-dessus)
Le second contrôle permet de vérifier lorsque l’on arrive en haut de la page. Dès que c’est le cas, on retire la classe et le padding
pour replacer le header dans le flux, à sa position d’origine.
Dans les deux cas, avant d’ajouter la classe et le padding
, on vérifie simplement que la classe n’est pas déjà présente, ça évite de faire l’action inutilement. Idem dans l’autre sens, avant de la retirer, on vérifie si elle n’a pas déjà été retirée.
Voici le code JS complet pour cette partie, sans le polyfill.
(function(w,d,undefined){
var el_html = d.documentElement,
el_body = d.getElementsByTagName('body')[0],
header = d.getElementById('header'),
menuIsStuck = function() {
var wScrollTop = w.pageYOffset || el_body.scrollTop,
regexp = /(nav\-is\-stuck)/i,
classFound = el_html.className.match( regexp ),
navHeight = header.offsetHeight,
bodyRect = el_body.getBoundingClientRect(),
scrollValue = 600;
// si le scroll est d'au moins 600 et
// la class nav-is-stuck n'existe pas sur HTML
if ( wScrollTop > scrollValue && !classFound ) {
el_html.className = el_html.className + ' nav-is-stuck';
el_body.style.paddingTop = navHeight + 'px';
}
// si le scroll est inférieur à 2 et
// la class nav-is-stuck existe
if ( wScrollTop < 2 && classFound ) {
el_html.className = el_html.className.replace( regexp, '' );
el_body.style.paddingTop = '0';
}
},
onScrolling = function() {
// on exécute notre fonction menuIsStuck()
// dans la fonction onScrolling()
menuIsStuck();
// on pourrait faire plein d'autres choses ici
};
// quand on scroll
w.addEventListener('scroll', function(){
// on exécute la fonction onScrolling()
w.requestAnimationFrame( onScrolling );
});
}(window, document));
C’est long à expliquer pour moi et à intégrer peut-être pour vous, mais finalement cela ne fait pas beaucoup de code à écrire 🙂
Ok… mais on a toujours pas de sticky avec ça, juste un changement de classe CSS et un padding
en plus. Passons au complément de CSS.
Notre menu sticky animé
Nous allons utiliser uniquement du CSS pour faire notre animation, et si jamais l’animation CSS n’est pas comprise par le navigateur (ce qui devient rare), et bien il n’en aura pas, tout simplement.
.nav-is-stuck .main-header {
position: fixed;
top: 0;
left: 0;
right: 0;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
animation: stickAnim .3s;
}
@keyframes stickAnim {
0% {
transform: translateY(-86px);
}
100% {
transform: translateY(0);
}
}
Dès que l’élément HTML possède la classe nav-is-stuck
, je peux cibler le header grâce au sélecteur de descendance et le fixer. Tout en le fixant, je lui attribue l’animation stickAnim
déclarée juste après.
Cette animation fait faire une translation CSS en Y de -86px (environ la hauteur du menu) vers 0, son emplacement d’origine. Cela nous donne l’effet exact de la démo.
Et voilà, vous êtes arrivés au bout de ce tutoriel !
Pour les plus courageux, nous allons voir un petit complément de notre code JS pour définir le déclenchement du sticky seulement lorsque le scroll atteint un autre élément de la page.
Bonus : Déclencher le sticky quand il atteint un élément
Il va s’agir pour nous de rendre dynamique la valeur de la variable scrollValue
en la remplaçant par la valeur en pixel de l’élément HTML déclencheur. Dans mon code de démo, j’ai défini plusieurs autres sections et éléments HTML. Je vous invite à faire de même. Attribuez un identifiant (attribut id
) à l’un de ces éléments, nous en aurons besoin.
Dans la fonction onScrolling()
, repérez l’appel à menuIsStuck()
et ajoutez en paramètre d.getElementById('VOTRE_ID')
où VOTRE_ID
est l’identifiant de l’élément HTML déclencheur.
La fonction ressemble alors à cela :
onScrolling = function() {
menuIsStuck( d.getElementById('main') );
};
Il faut que nous ajoutions ce paramètre à notre fonction menuIsStuck (plus haut dans le code). La ligne qui déclare la fonction ressemble alors à cela :
menuIsStuck = function(triggerElement) {
Cette variable triggerElement
est récupérable en l’état dans notre code à l’intérieur de la fonction. Il ne nous reste plus qu’à éditer la valeur de la variable srollValue
comme suit :
scrollValue = triggerElement ? triggerElement.getBoundingClientRect().top - bodyRect.top - navHeight : 600,
Ça vous parle ? Je pourrais comprendre que non. Mais détaillons. Il s’agit d’un opérateur ternaire, qui est représenté sous cette forme :
variable = condition ? valeur_si_vrai : valeur_si_faux
Dans notre cas on vérifie que triggerElement
vaut bien quelque chose, si c’est le cas on fait un calcul savant pour récupérer la valeur « top » de l’élément (le haut quoi), autrement on utilise notre valeur arbitraire de 600 pixels.
C’est tout !
Bonus : Faire apparaître le menu quand on remonte dans la page
Le deuxième petit bonus que je vous avais proposé était de ne faire apparaître le menu en sticky
que lorsque l’utilisateur décide de remonter dans la page, donc quand il scroll vers le haut.
Nous allons devoir à nouveau éditer notre code JS, mais tout ne va pas être identique au précédent. Commençons par éditer légèrement notre déclaration de variables en tout début de code.
Vous avez normalement la même chose au début que ce bloc de code, ajoutez simplement la ligne concernant le lastScroll
.
var el_html = d.documentElement,
el_body = d.getElementsByTagName('body')[0],
header = d.getElementById('header'),
lastScroll = w.pageYOffset || el_body.scrollTop,
Cela nous permet d’initialiser la valeur de cette variable. Souvent cela correspondra à 0, soit le haut de la page.
Maintenant nous allons utiliser cette variable dans la fonction onScrolling()
comme suit :
onScrolling = function() {
// on récupère la valeur du scroll maintenant
var wScrollTop = w.pageYOffset || el_body.scrollTop;
// on ajoute deux arguments, valeurs de scrolls
menuIsStuck( d.getElementById('main'), wScrollTop, lastScroll );
// on enregistre notre dernière valeur de scroll
lastScroll = wScrollTop;
};
Ici on ajoute une ligne avant et une ligne après notre appel à menuIsStuck()
pour récupérer la valeur courante du scroll, puis enregistrer cette valeur comme ancienne valeur de scroll, cela va nous permettre de savoir si on monte ou descend lorsque l’on bouge dans la page.
Notre fonction menuIsStuck()
accueille maintenant 3 paramètres : l’élément cible, la valeur de scroll et la valeur de scroll précédente. Il faut donc éditer notre fonction pour utiliser ces paramètres.
menuIsStuck = function(triggerElement, wScrollTop, lastScroll) {
Sur la ligne de la déclaration, vous ajoutez donc ces deux paramètres.
Juste en-dessous, retirez la déclaration de wScrollTop
, elle fait doublon maintenant, on l’a déjà en paramètre. (n’effacez pas le var
)
Conservez tout le reste, il nous faut juste modifier nos deux contrôles (les if
). En gros il faut que l’on ajoute les conditions « si on remonte » et « si on descend ». On va faire apparaître notre menu uniquement si on descend, et qu’on a atteint notre seuil (même seuil qu’avant), notre premier contrôle va donc se transformer en :
if ( wScrollTop > scrollValFix && !classFound && wScrollTop < lastScroll ) {
Ici wScrollTop < lastScroll
permet de dire « on remonte ».
Le second contrôle va ressembler à ça :
if ( classFound && wScrollTop > lastScroll ) {
Et voilà, notre sticky menu n’apparait désormais que lorsque l’on remonte dans la page, et disparait si l’on descend.
J’espère que ce long tutoriel vous aura plu. N’hésitez pas à commenter pour nous partager vos essais et vos démos.
Et si coder vous ennuie, il existe le bon plugin Headroom.js. (merci @IamNotCyril pour la suggestion)
Si tu veux « définir » undefined dans ta closure, je pense que tu devrais plutôt mettre :
(function(w,d,undefined){
…
}(window, document));
Houla ! Oui, bien vu 😉
Merci pour la correction.
Salut, même en effectuant uniquement des copier/coller je n’arrive pas à obtenir le résultat pour l’animation… Une idée ?
Hello.
« Même » sous-entend-t’il une autre tentative ? Copier/coller ne suffit pas, rien de mieux que de lire le contenu complet de l’article (pas que du code) et d’y ajouter un zeste de réflexion.
Peut-être que partager ton code permettrait de nous avancer 🙂
Merci.
Salut, il y’a en fait une toute petite faute qui empêche le script de s’executer.
il y’a un s a getElementsByTagName() contrairement à getElementById().
Donc au moment de la déclaration des variables, tu devras avoir el_body = document.getElementsByTagName(‘body’)[0].
J’espère que ceci t’aidera.
Happy coding 😉
Hello Lou 🙂
Merci pour ton oeil de Lynx, il est effectivement écrit deux fois avec la faute et une fois correctement. C’est corrigé !
Bonne journée.
Merci pour ce tuto 🙂
Je me pose une question pour le code JS.
J’ai lu et re lu le tuto mais je ne vois pas comment traiter la partie .JS copier/coller dans un fichier extension .js? si oui le nommer comment ?
Sinon la partie css+html c’est ok
Effectivement ce n’est pas précisé mais il faut le placer dans un fichier JS que tu nommes comme tu veux. Puis l’inclure dans ton fichier HTML avec la balise script et l’attribut SRC.
Autrement tu peux mettre le code JS directement entre balise script si c’est pour une simple page de test, de demo ou une « single page layout ».
Plus d’infos sur
http://www.alsacreations.com/astuce/lire/80-comment-intgrer-du-code-javascript-dans-une-page.html
Bonne lecture.
Bonjour,
Bravo et merci pour votre script !
Il y a t-il un moyen pour que le sticky n’apparaisse PAS par défaut quand le scroll est en haut ? Il apparaitrait uniquement lors du scroll…
Cas où le menu haut et le stycky sont différents…
Merci !
JF
Bonjour Jean-François,
Pour effectuer cela il faut adapter le code proposé en étant un peu créatif 🙂
Partez du principe que par défaut l’élément est visible, sauf quand JS dit qu’on n’est pas en haut de la page. Par rapport à mon code proposé, il y a principalement du CSS à modifier.
Je vous laisse chercher un peu, vous donner la solution ne serait pas vraiment vous aider à créer ! :p
Bonne fin de dimanche.
Merci pour votre réponse.
Je ne cherche pas la solution toute faite bien entendu, mais ne connaissant que très peu le JS, je vois que c’est possible via CSS.
Je regarde de ce coté.
Merci
Bonjour,
J’aime beaucoup le résultat, très beau travail.
Moi la seule chose que j’aimerai, c’est de pouvoir avoir le menu de départ sans Background…
Puis lorsqu’il apparait après Scroll, qu’il ait un Background.
En gros, avoir deux styles différents entre les deux.
Merci d’avance 🙂
Cordialement
Hello,
Merci pour ton retour 🙂
C’est tout à fait possible puisque le code JS propose d’ajouter une classe CSS sur HTML pour signaler quand le header est « collé » ou pas.
avec ce code tu as un header transparent, sauf quand le header devient sticky, il est alors sur fond blanc. Avec une petite transition pour crâner 🙂
Bonne journée.
Super travail… malgré tout j’ai une petite question/requête… est-il possible à partir de ton script de souligner le lien concerné par la section actuellement à l’écran ? (Je sais pas si je suis clair lol … )
Bonjour Laurent,
En combinant le script avec https://www.creativejuiz.fr/blog/tutoriels/jquery-inview-plugin-elements-visibles-a-ecran ou un équivalent non dépendant de jQuery c’est jouable oui 🙂
Bon code !
Salut,
J’ai suivi ton tuto et j’ai un « bon » résultat pour le menu (le petit trait et tout !)
En revanche l’effet sticky ne se déclenche pas et j’obtiens les deux erreurs ci-dessous provenant de mon fichier js :
– lorsque je scroll cela m’indique « Cannot read property ‘offsetHeight’ of null »
– lorsque j’arrive en haut de ma page « Cannot read property ‘scrollTop’ of undefined »
Je ne maîtrise pas assez bien le javascript pour corriger ça moi-même donc si tu as des pistes pour m’aider…
Merci d’avance !
Hello,
Peux-tu me fournir ton code en ligne ou sur CodePen pour que je puisse jeter un œil ?
Merci 🙂
Salut! J’ai exactement les 2 mêmes erreurs, le script n’arrive pas à définir le el_body. J’ai copié le script dans .js externe.
Hello,
As-tu positionné ton script dans le
<head>
ou à la fin du<body>
?Bonne journée.
Merci beaucoup pour ce code. Je galérais depuis un moment. Et après avoir ajuster ce code à SPIP, ça fonctionne nickel.
Hey !
Dans le premier contrôle à remplacer ne serait pas la variable scrollValue au lieu de scorllValFix ? 😉
« if ( wScrollTop > scrollValFix && !classFound && wScrollTop < lastScroll )"
Bonjour !
Tout d’abord, merci pour ce tuto ! il m’a était d’une grande aide, simple et efficace !
Ensuite, j’ai un petit problème ^^’ :
en effet je souhait redimensionner la taille de mon body a 75%, vient alors un effet non voulus avec le menu, il s’adapte a la largeur du body mais des que je scroll down il prend la largeur de l’écran. Je ne vois pas quoi faire pour le maintenir dans l’un ou l’autre état.
Je ne sais pas si je m’y prend de la bonne facon mais voici mon code : http://codepen.io/ArkhLink/pen/GNEJEx
Hello,
Navré pour le délai de réponse, la migration du blog m’a pris un peu de temps.
Voici ton pen modifié : http://codepen.io/CreativeJuiz/pen/RoZzXd
Pour faire simple : couleur de fond sur l’élément directement enfant de la navigation. Changement de 100% à 75% width quand la nav passe en sticky, comme la largeur du body, et a fait l’effet recherché. Je pense 🙂
Bonne continuation !
Bonjour !
Une nouvelle fois merci pour ce tuto très bien expliqué. En revanche, je rencontre un léger problème :
je rencontre cette erreur avec mon fichier JS : « Cannot read property ‘offsetHeight’ of null(…) » et je ne trouve pas de solution pour y remédier. Si jamais vous pouviez m’aiguiller 🙂
Petite précision, mon header ne commence pas en haut de ma page mais plus bas.
Bonjour,
Avec une ressource en ligne je pourrais vous aider à déboguer votre code.
Bonne soirée.
Merci Geoffrey
Même si je ne suis pas un expert en js, j’arrive à saisir les nuances des codes et comme tu dis si bien, prendre le temps de s’amener une réflexion ne fait pas de mal
Encore un gros merci pour ton travail
Ray !!! 🙂
Merci beaucoup pour ton retour 🙂
Merci pour votre tuto très bien fait !!
Une question cependant, mon contenu passe par-dessus le menu hors je n’ai pas de z-index qui semble perturber le fonctionnement…
https://www.metainnov.com/
Hey,
Je ne vois pas le code en fonctionnement sur ce site web.
As-tu essayé la nouvelle position sticky ?
https://codepen.io/CreativeJuiz/pen/YqbzRo
Dans pas mal de cas c’est finalement suffisant.
Merci bien pour le tuto ! je l’ai longtemps cherché 🙂 !
Salut je ne vois pas dans quelle balise de l’element html peut-on placer la classe nav-is-stuck. Sinon merci pour le tuto.
Bonjour,
Je ne comprends pas ta question.
La classe est placée dans l’attribut « class » de l’élément HTML, l’élément racine de ton document HTML, la balise HTML autrement dit 🙂
Bonjour,
merci pour ces explications.
je ne trouve pas comment enlever un élément au milieu du header ( un logo au centre par exemple ) pour que quand le menu réapparait il soit moins haut.
j’ai trouvé … son est stick … il y a la classe nav-is-stuck
soit
.nav-is-stuck .monobjet {display:none;}
vraiment merci pour ce tuto