Pages :
Modérateur
(reprise du message précédent)

Bonjour,

À noter qu'on peut remplacer la balise <div> par la balise <footer> dans laquelle peut se trouver raisonnablement le lien <a> vers le haut de page, mais au prix de quelques acrobaties que je n'ai pas su rendre passe-partout pour l'instant.

Amicalement,
C'est mieux parce que l'on peut changer le font-size sur le HTML sans que cela ne pose plus problème. Par contre, la flèche a tendance à s' "envoler" avec main lorsque l'on définie un font-size plus important que 1rem (c'est le cas avec ta définition de 5rem actuelle sur <main>). Je ne l'avais pas signalé mais c'était déjà le cas dans le code précédent. C'est embêtant ce couplage fort entre deux composants.

Attention : il manque la fermeture de tes parenthèses pour certains calc().
Modifié par Olivier C (09 Mar 2024 - 13:00)
Modérateur
Bonjour,

Olivier C a écrit :
Par contre, la flèche a tendance à s' "envoler" avec main lorsque l'on définie un font-size plus important que 1rem (c'est le cas avec ta définition de 5rem actuelle sur &lt;main&gt;).
Étonnant, je n'observe pas ça. Dans quelles conditions exactement ? (machine, navigateur, largeur de la fenêtre, zoom, police par défaut du navigateur, dev tools ouvert ?). Il faut faire gaffe au dev tools de Chrome quand il y a du sticky. J'observe des trucs bizarres de temps en temps.

Olivier C a écrit :
Attention : il manque la fermeture de tes parenthèses pour certains calc().
Effectivement (erreur de copier-coller lors de l'édition du post). Merci ! J'ai corrigé dans le post.

Amicalement,
Oui un dev tools ouvert, mais sur un côté, ça ne devrait pas influer. Après j'ai peut être fait une erreur de recopiage. Le problème c'est que j'ai déjà détruit l'exemple test...
Modifié par Olivier C (10 Mar 2024 - 00:08)
Modérateur
Bonjour,

Si c'est avec un dev tool ouvert, il est probable que ce soit un bug du dev tool (EDIT: ou un problème de mobilisation de ressources quand le dev tool est ouvert ?).

J'ai eu le cas en particulier en ayant sélectionné des devices de type mobile. Des problèmes d'affichage inexplicables survenait au scroll. En attendant un peu avant de rafraîchir la page, ou en changeant de device puis en revenant au device précédant, les problèmes d'affichage disparaissaient.

Amicalement,
Modifié par parsimonhi (09 Mar 2024 - 14:54)
Modérateur
en passant entre deux,
Dernière mise à jour sur l'idée du grid , du float et des container queries et enfin display pour cacher le lien retour lorsque devenu inutile. Plus de barre de scroll qui gache et CSS var() pour la valeur de hauteur d'apparition du lien retour.
https://codepen.io/gc-nomade/pen/dyLGgYg

Vos exemples sont aussi excellent, désolé de rester scotcher sur mon idée.

Cdt
Franchement, cet excursus sur les scroll top aurait mérité son propre sujet.

Un pseudo-élément... Et ça marche dans tous les cas sans qu'il y ait d'effets de bord apparents. Bravo gcyrillus, là franchement chapeaux. Ça va être difficile de faire mieux en attendant le support des règles avant-gardistes utilisées par Raphaël que j'ai mentionné plus haut.
Modérateur
Bonjour,

gcyrillus a écrit :
Dernière mise à jour sur l'idée du grid , du float et des container queries et enfin display pour cacher le lien retour lorsque devenu inutile. Plus de barre de scroll qui gache et CSS var() pour la valeur de hauteur d'apparition du lien retour.
C'est machiavélique. Et c'est vrai que cette barre de scroll, elle gâchait (bien que je sois sur Mac et qu'en conséquence je ne la voyais guère sauf à insister lourdement pour qu'elle apparaisse).
gcyrillus a écrit :
...désolé de rester scotcher sur mon idée.
Tu as eu raison d'insister.

Olivier C a écrit :
Franchement, cet excursus sur les scroll top aurait mérité son propre sujet.
J'étais à peu près sûr que ça allait t'intéresser. Mais là, cela va au delà de mes espérances ! Smiley cligne

Il ne reste plus qu'à faire en sorte qu'on puisse se servir du footer aussi comme d'un footer si on a par exemple le html ci-dessous (il pourrait y avoir plusieurs autres balises à la place ou à la suite des <p>, on n'en connait pas à l'avance les dimensions, et si en plus l'ensemble de ces balises n'ont pas besoin d'être dans un wrapper intermédiaire, ce serait la perfection Smiley cligne ) :
<footer>
  <p>Qu'il est beau, mon joli footer !</p>
  <p>Oh oui, qu'il est beau !</p>
  <a href="#">Haut</a>
</footer>

Amicalement,
Modérateur
Bonjour,

Cette affaire est pleine de rebondissements.

J'ai essayé la solution de gcyrillus sur un "vrai" site déjà en production. Malheureusement, le display:grid sur le body y a des conséquences facheuses.

J'ai donc cherché une alternative, tout en conservant les autres idées de la solution. À un moment, je me suis aperçu que le simple fait d'avoir une propriété "container" sur le parent du "bouton" scrollTop (la div de ma solution précédente, ou le footer de la solution de gcyrillus) suffisait à faire disparaitre la scrollbar quand le contenu était moins haut que la fenêtre du navigateur.

J'ai fait le lien avec la notion de "containment" et je suis arrivé à la conclusion qu'il suffisait de rajouter quelque chose du genre "contain:layout" à la div de ma solution pour faire disparaitre la scrollbar quand elle n'est pas nécessaire. Au passage j'ai remplacé la div par une nav. Voici où j'en suis :
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Sticky to top button</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
html {scroll-behavior:smooth;}
body
{
	position:relative;
	margin:0;
	overflow-wrap:break-word;
}
main
{
	font-size:5rem;
}
nav
{
	contain:layout;
	position:absolute;
	top:100vh;
	left:0;
	right:0;
	height:calc(100% - 100vh);
	pointer-events:none;
}
a
{
	--m:min(10vmin,1rem);
	--d:calc(4 * var(--m));
	font-size:var(--m);
	position:sticky;
	top:calc(100vh - var(--d) - var(--m));
	margin:0 var(--m) 0 auto;
	display:flex;
	justify-content:center;
	align-items:center;
	height:var(--d);
	width:var(--d);
	border-radius:50%;
	background-color:#0007;
	color:#fff;
	pointer-events:auto;
}
</style>
</head>
<body>
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>
<nav>
<a href="#">Haut</a>
</nav>
</body>
</html>

Il reste tout de même un détail que je n'ai pas encore réglé (je pense que ça devrait pouvoir se faire cependant, mais sans en être sûr à 100%). Lorsque la fenêtre a une hauteur légèrement inférieure à celle du contenu, de quelques pixels et au plus d'une hauteur égale à la hauteur du "bouton" de scrollTop (marges et padding éventuels compris, à voir dans le détail), il n'est pas possible de faire apparaitre en entier ce "bouton" de scrollTop. Il est tronqué tant que le scroll possible sur le contenu n'est pas supérieur à la hauteur de ce "bouton" (ce qui est normal, puisque ce "bouton" ne compte plus pour le scroll du fait qu'on a mis une propriété css contain à son parent si j'ai bien compris cette histoire de containment : n'hésitez pas à me dire si j'ai tort car pour l'instant, je n'y comprends pas grand chose), et l'utilisateur ne pourra le faire apparaitre en entier qu'en diminuant la fenêtre en hauteur. Ce n'est pas spécialement génant car le bouton est alors assez inutile dans cette circonstance, mais ce petit détail visuel pourrait gêner un puriste (et ce n'est pas ça qui manque ici Smiley biggol ).

Peut-être saurez-vous régler ça ?

Amicalement,
Modifié par parsimonhi (11 Mar 2024 - 11:24)
Modérateur
Bonjour,

Eureka !
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Sticky to top button</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
html {scroll-behavior:smooth;}
body
{
	position:relative; /* nécessaire pour faire fonctionner la solution */
	margin:0;
	overflow-wrap:break-word;
}
main
{
	font-size:3em;
}
nav
{
	/* toutes les lignes ici sont importantes pour faire fonctionner la solution */
	container:scrollTop/size;
	position:absolute;
	left:0;
	right:0;
	/* la valeur de --horizon doit être supérieure ou égale à 100vh */
	/* on peut l'augmenter si on veut que le bouton n'apparaisse pas dès qu'on scrolle */
	--horizon:100vh;
	top:var(--horizon);
	height:calc(100% - var(--horizon));
	pointer-events:none;
}
a
{
	--m:1rem;
	--d:calc(4 * var(--m));
	font-size:var(--m);
	/* les 4 lignes qui suivent sont importantes, le reste est cosmétique */
	position:sticky;
	top:calc(100vh - var(--d) - var(--m));
	margin:0 var(--m) 0 auto;
	pointer-events:auto;
	/* fin des lignes importantes pour faire fonctionner la solution */
	display:flex;
	justify-content:center;
	align-items:center;
	height:var(--d);
	width:var(--d);
	border-radius:50%;
	background-color:#0007;
	color:#fff;
	transition:opacity 1s;
	pointer:cursor;
}
/* la valeur de comparaison au max-height doit être supérieure ou égale à --d */
/* on peut l'augmenter si on souhaite que le bouton n'apparaisse */
/* que quand le contenu est sensiblement plus grand que la fenêtre */
@container scrollTop (max-height:4rem)
{
	a {opacity:0;visible:hidden;}
}
</style>
</head>
<body>
<main>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</main>
<nav>
<a href="#">Haut</a>
</nav>
</body>
</html>
EDIT: modifications cosmétiques pour expliquer comment paramétrer le déclenchement de l'apparition du bouton.

Amicalement,
Modifié par parsimonhi (11 Mar 2024 - 20:42)
Bon, alors comme vous avez tous les deux bien travaillés et qu'au final je n'ai pas bien eu le temps de m'y pencher dessus ce WE (et que le peu de temps qui me reste je le passe surtout sur le back), je me suis contenté de faire un petit custom de la solution de Raphaël avec mon intuition de départ évoquée plus haut : CodePen, Scroll top.

:root {
  --colorW: #fff;
  --color2: tomato;
  --color5: orange;
}

.scroll-top {
  position: fixed;
  z-index: 4000; /* Il faut que la flèche puisse prendre le pas sur pratiquement tout, il faut penser par exemple aux maps (Leaflet, etc) */
  right: 0;
  bottom: 0; /* fallback */
  bottom: env(safe-area-inset-bottom, 0); /* ça, c'est l'ajout de la solution pour les boutons de navigateurs sur la page dont nous avons parlé plus haut */
  display: grid;
  place-content: center;
  width: 1.5em;
  aspect-ratio: 1/1; /* ça, c'est cosmétique, c'est juste pour le sortir de temps en temps... */
  font-size: 2em;
  color: var(--colorW);
  background: var(--color2);
  text-decoration: none;
  border-radius: 50%;
  box-shadow: 0 0 .5rem hsla(0, 0%, 0%, 0.5);
  animation: scroll-top auto linear forwards;
  animation-timeline: scroll(root); /* définition d'un pourcentage de progression sur tout le document */
  animation-range: 0 100dvh; /* Définition d'une plage en lien avec les pourcentages de l'animation */
  
  &:where(:focus-visible, :hover) {
    color: var(--colorW);
    background: var(--color5);
    outline: none;
  }
}

@keyframes scroll-top {
  0%, 99% {
    transform: scale(0); /* pas de `display:none` sur une animation, du coup voilà mon actuce */
  }

  100% {
    transform: scale(1);
  }
}

Axe d'amélioration : faire un fondu enchaîné avec `opacity` avant l'apparition ou la disparition de l'icône.

Par défaut, si pas de prise en charge (comme actuellement sous Firefox ou Safari), la flèche est présente. C'est une solution pas totalement satisfaisante pour l'instant en raison de son support actuel, mais ce sera le top à l'avenir. Et comme de mon côté j'ai codé un front qui ne sera pas en service avant au moins un an, ce devrait être bon pour moi.
Modérateur
Bonjour,

Olivier C a écrit :
Je me suis contenté de faire un petit custom de la solution de Raphaël avec mon intuition de départ évoquée plus haut : CodePen, Scroll top.

Amusant, j'étais justement en train d'essayer de faire marcher cette solution moi aussi.

Reste à faire disparaitre la scroll-bar quand le contenu est moins haut que la fenêtre, non ? Smiley lol

Amicalement,
Fut une époque, j'aurais sauté sur mon ordinateur au réveil pour régler le problème ; aujourd'hui je vais devoir attendre 22h00. Faites des gosses...
Je pense que le problème vient de là :
animation-timeline: scroll(root);

Il y a d'autres valeurs que root, sinon peut-être trouver quelque chose avec calc()... Je verrai donc ce soir.
En fait le code fonctionne sans problème : c'était mon layout de démo qui était bidon, je viens de faire une MAJ (sur mon temps de travail, pas bien !) et c'est OK.
Modérateur
Bonjour,

Olivier C a écrit :
En fait le code fonctionne sans problème

Si je mets for (let i = 0; i < 1; i++) dans le code source (pour obtenir un contenu court), le bouton est visible en bas à droite de l'écran (alors qu'il ne devrait pas s'il n'y a pas de scrollbar affichée).

J'en suis exactement au même point en fait. Il manque quelque chose pour que ça fonctionne vraiment quand le contenu est trop court pour générer une scrollbar.

Amicalement,
Modifié par parsimonhi (12 Mar 2024 - 17:27)
Damned, mais tu as vu juste !
J'ai effectivement mal évalué.
Je viens de tenter plusieurs approches, mais je n'arrive pas à passer cette limitation...