A Button That Links to a Random Post in HTML & CSS Only – Master.dev Blog
/ BLOG
BloggingCSSflexboxrandom()
A Button That Links to a Random Post in HTML & CSS Only
Chris Coyier<br>on<br>July 29, 2026
I was reading a post by Jim Nielsen where he was Making a Shuffle Button. It was for a static site, so there was no server-side code to hit to redirect to a random post. PHP, for instance, could query for all posts and select one pseudo-randomly, and redirect there. But no such language on a static site.
Take One
Instead, Jim did this (at first):
button id="js-shuffle">Shufflebutton>
script><br>// All 974 note IDs injected by my SSG<br>const noteIds = ['id-1', 'id-2', id-3', 'id-4', '...'];<br>document.querySelector("#js-shuffle")<br>.addEventListener('click', () => {<br>// randomly grab an item in `noteIds`<br>const randomId = '...';<br>window.location.href = `/n/${randomId}/`<br>})<br>script>Code language: HTML, XML (xml)
The issue with this approach is that Jim inlined it on every single HTML page and thus every page had to be re-built during deployment if a new post was published. I do feel like saying JIM THIS COULD HAVE BEEN A WEB COMPONENT and built as a single file and imported, but I’ll refrain.
Then Jim went through 3-4 other techniques that also worked, each with its ups and downs. I like the technique Jim landed on, which was making a single page that handled the job and redirected away. Basically like the solution above, just at a shuffle.html page and ran automatically.
I’m afraid I don’t have an improvement for Jim, per se, but it made me think of another potential solution.
What if it depended on where you clicked the random button?
I mean, we’re talking about a physical button here, right? So I’m talking literally what pixel you clicked on on the button would determine which random post you go to.
We could get these coordinates in JavaScript, but I don’t think we need to. We can just fill the area with links that go to the posts. So it’s not a single button, it’s just a button-like shape full of tiny buttons (links, actually).
To this, we could do like:
div class="random-button"><br>a href="/post/1">Post 1a><br>a href="/post/2">Post 2a><br>a href="/post/3">Post 3a><br>...<br>span>Random Postspan><br>div>Code language: HTML, XML (xml)
Then we just let the links lay out naturally within the button space:
.random-button {<br>display: flex;<br>flex-wrap: wrap;<br>align-content: stretch;<br>position: relative;<br>overflow: hidden;
/* make it look like a button */<br>inline-size: 300px;<br>border-radius: 14px;
> a {<br>/* whatever sizing works */<br>flex: 1 1 30px;
> span {<br>pointer-events: none;<br>position: absolute;<br>inset: 0;<br>display: grid;<br>place-items: center;<br>}Code language: CSS (css)
This flexbox setup, with the stretchy alignment and flex-grow allowance, should fill the space nicely.
See how the last row always fills the space there no matter how many links there are? A "button" should probably respond no matter where it is clicked, and now we can do that.
If you want this implementation to be a secret, you could set opacity: 0; on the links, and the behavior will be the same and the whole thing will just look like a single button.
Gettin’ More Random
With one line, we can make this all a bit more random. I’d say it’s still pretty random without this, as where you click exactly will essentially be random. But this is better.
And check it out, it’s a one liner…
.random-button {<br>...<br>reading-flow: flex-visual;
> a {<br>order: random(1, 9999);
Flexbox supports the order property. Sometimes it’s a finger-waggle thing because you’re messing with the visual tabbing order when you use it, which can be an accessibility issue. But…
These are kinda hidden secret links so maybe it doesn’t matter?
We can fix it with reading-flow: flex-visual; on the button anyway.
Now, with CSS alone, the link placement is random. That random() function works in Safari and Chrome-with-flag, so I did up some colors with it too to make it clearer.
That’s client-side randomization. Every page load will be different.
Demo
The demo has some bonus stuff like setting the font-size with container units so things kinda fit nicely in the space. Maybe you’d do some fancy build-time math to size things based on how many links there are. I’d think this would scale up into the thousands if you’re down to like 1px × 1px links.
CodePen Embed Fallback
I’d tell Jim to give it a shot, but I think the route he landed on, where a single link does the randomization, is probably a little more useful in his case.
Wanna learn modern CSS layout?
Laying out designs on the web with CSS has gotten a lot more powerful in recent years. CSS grid, flexbox, and container queries are incredibly powerful tools for that, and we have a complete learning course on them from Jen Kramer. Access 300+ courses with a Master.dev subscription and get 20% off today!
Personalized Learning
Industry-Leading Experts
24 Learning Paths
Live Interactive Workshops
20% Off
Start Learning Today →
Leave a...