Skip to content

Instantly share code, notes, and snippets.

@kyrylo
Last active November 15, 2024 12:50
Show Gist options
  • Save kyrylo/be06337ff28226bc91bcbe3f20d1542f to your computer and use it in GitHub Desktop.
Save kyrylo/be06337ff28226bc91bcbe3f20d1542f to your computer and use it in GitHub Desktop.
Got inspired by the "signup peekaboos" on Hey and Basecamp, and I love the concept! https://x.com/kyrylosilin/status/1856648149038686626
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Signup peekaboo 👻</title>
<script type="module">
import { Application, Controller } from "https://cdn.jsdelivr.net/npm/@hotwired/[email protected]/+esm";
const application = Application.start()
class SignupPeekabooController extends Controller {
static values = {
topOffset: { type: Number, default: 100 },
bottomOffset: { type: Number, default: 0 },
};
static classes = ["visible", "hidden"];
isVisible = false;
connect() {
this.scroll();
}
scroll() {
const shouldShow = this.shouldShowButton();
if (shouldShow === this.isVisible) {
return;
}
this.isVisible = shouldShow;
this.element.classList.toggle(this.visibleClass, shouldShow);
this.element.classList.toggle(this.hiddenClass, !shouldShow);
}
shouldShowButton() {
const scrollPosition = window.scrollY;
const pageHeight = document.documentElement.scrollHeight;
const windowHeight = window.innerHeight;
return (
scrollPosition > this.topOffsetValue &&
scrollPosition + windowHeight < pageHeight - this.bottomOffsetValue
);
}
}
application.register("signup-peekaboo", SignupPeekabooController)
</script>
<style>
body {
font-family: "Lucida Grande";
margin: 0;
}
.mt-40 {
margin-top: 10rem;
}
.translate-y-0 {
transform: translate(-50%, 0);
}
.translate-y-32 {
transform: translate(-50%, 8rem);
}
.container {
width: min(360px, 100%);
margin: 0 auto;
padding: 1rem;
}
.footer {
margin-top: 150rem;
padding: 10rem;
font-weight: 700;
font-size: 1.5rem;
text-align: center;
background-color: silver;
}
.signup-peekaboo {
position: fixed;
bottom: 1rem;
left: 50%;
transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1);
}
.signup-peekaboo__button {
padding: 1rem 2rem;
font-size: 1.5rem;
}
</style>
</head>
<body>
<div
data-controller="signup-peekaboo"
data-action="scroll@window->signup-peekaboo#scroll"
data-signup-peekaboo-top-offset-value="100"
data-signup-peekaboo-bottom-offset-value="400"
data-signup-peekaboo-visible-class="translate-y-0"
data-signup-peekaboo-hidden-class="translate-y-32"
class="signup-peekaboo translate-y-32"
>
<button class="signup-peekaboo__button">
Peekaboo 👻
</button>
</div>
<div class="mt-40">
<div class="container">
<h1>Signup peekaboo 👻</h1>
<ol>
<li>Scroll down to see the signup CTA</li>
<li>Scroll up to hide the signup CTA</li>
</ol>
</div>
</div>
<footer class="footer">
Footer!
</footer>
</body>
</html>
@kyrylo
Copy link
Author

kyrylo commented Nov 13, 2024

Got inspired by the "signup peekaboos" on Hey and Basecamp, and I love the concept! 👻

With Stimulus and some CSS, it's a breeze to set up:

  1. Scroll down, and a floating CTA slides in.
  2. Optionally, hide the peekaboo if there's a static CTA in view.

https://x.com/kyrylosilin/status/1856648149038686626

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment