my goal is to set the sticky div initially to visibility: hidden. After scrolling more than 200px, the button should appear with visibility: visible. Is there a workaround to achieve this only with CSS, without JavaScript? In pure CSS, there doesn’t seem to be a way to detect exact scroll distances like 200px. Any suggestions?
This is my example:
body {
margin: 0;
padding: 0;
}
header {
height: 150px;
background-color: black;
}
.container {
height: 1500px;
background-color: azure;
}
footer {
height: 500px;
background-color: grey;
}
.sticky {
display: flex;
justify-content: flex-end;
position: sticky;
bottom: 10px;
margin: 10px;
}
.sticky a {
background-color: black;
color: #fff;
padding: 5px;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<header></header>
<div class="container"></div>
<div class="sticky">
<a href="#top">ScrollToTop</a>
</div>
<footer></footer>
</body>
</html>
I tried many things like a sticky spacer, semi-sticky with multiple elements, and so on. Unfortunately, nothing worked.
You can also use a grid-layout, container query (to toggle an hide/show) and float/clear-both to show & push down a sticky link if needed only: example from my earlier comment with your HTML:
body {
margin: 0;
padding: 0;
}
header {
height: 100px;
background-color: black;
color: white;
}
.container {
background-color: azure;
}
footer {
height: 100px;
background-color: grey;
}
html {
scroll-behavior: smooth;
}
body {
--d: 4rem;
--m: 1rem;
--showScrollTopAt: calc(100vh + 150px); /* valeur a reporter en dur le container querie, la variable ne passe pas */
display: grid;
grid-template-columns: 1fr ;
overflow: auto;
max-height: 100vh;
margin: 0;
padding: 0;
}
header ,
.container,
footer {
grid-column:1;
}
header,footer {
display:grid;
place-content:center;
font-size:5vw
}
.container:has(p #show:checked) {
height:1500px;
}
/* container cell to query */
.sticky {
container-type: size;
container-name: divTopLink;
grid-column: 2;
grid-row:1/4;
overflow: visible;
}
/* pushing floatting pseudo */
.sticky::before {
content: "";
float: left;
height: var(--showScrollTopAt);
max-height: 100cqh;
}
.sticky a {
clear: both;
position: sticky;
top: calc(100vh - var(--d) - 1rem);
margin: 0 1rem 0 auto;
display: flex;
justify-content: center;
align-items: center;
height: var(--d);
width: var(--d);
border-radius: 50%;
background-color: #0007;
color: #fff;
text-shadow:1px 1px 1px black;
margin-left: calc(var(--d) * -1 - 1rem);
z-index: 1;
}
/* ************* container Querie ******************
max-height must be equal to var(--showScrollTopAt) !!
*/
@container divTopLink (max-height : calc(100vh + 150px)) {
.sticky::before,
.sticky a {
display: none;
}
}
/* ***************** fin container Querie ********************* */
<header id="top">header</header>
<div class="container">container
<p><label>Check to make me 1500px tall <input type="checkbox" id="show"> to reveal the top link</label></p>
</div>
<div class="sticky">
<a href="#top">ScrollToTop</a>
</div>
<footer>footer</footer>