★ LIVE DEMO
This is how the final result will look on your webpage. Click the box to see your fortune!
★ DAILY
FORTUNE ★
Learn how to create an interactive box that reveals a random fortune message
This is how the final result will look on your webpage. Click the box to see your fortune!
The whole thing is one card: a title on top, the mailbox image in the middle (this is the clickable part), and a pink question/answer box at the bottom. We need four pieces: the fortune-card (the outer frame), the fortune-title, the fortune-box holding the mailbox image, and the fortune-result where the text is shown.
fortune-card: The outer bordered frame that holds everything.fortune-title: The "★ DAILY FORTUNE ★" heading, in the site's pixel font.fortune-box: The clickable area wrapping the mailbox image.fortune-result: The pink box with the question (before clicking) or the fortune (after clicking).<div class="fortune-card">
<h3 class="fortune-title">
<span class="pixel-star">★</span> DAILY<br>
FORTUNE <span class="pixel-star">★</span>
</h3>
<div class="fortune-box" id="fortuneBox" onclick="revealFortune()">
<img src="img/cute-mail.gif" alt="Fortune mailbox" class="fortune-icon">
</div>
<div class="fortune-result" id="fortuneResult">
What does destiny have in store for you today?
</div>
</div>
Swap img/cute-mail.gif for whatever image or gif you're using for the mailbox/box art on your own site.
The fortune-card is a white rounded card with a thick pink border — the frame that holds everything and gives it that "postcard" feel. The title uses the pixel font in dark pink. The mailbox image sits centered with a little hover/click feedback so it reads as clickable even without a button around it. The result box keeps the filled pink background with a dashed border from before, so the phrase always sits inside its own little card instead of floating as plain text.
/* Outer card / frame */
.fortune-card {
background: #ffffff;
border: 4px solid #e55c8a;
border-radius: 28px;
padding: 30px 24px;
max-width: 300px;
margin: 0 auto;
text-align: center;
}
/* "★ DAILY FORTUNE ★" title */
.fortune-title {
font-family: 'Silkscreen', cursive;
color: #e55c8a;
font-size: 20px;
line-height: 1.5;
letter-spacing: 1px;
margin: 0 0 20px;
}
/* Clickable area around the mailbox image */
.fortune-box {
width: 140px;
margin: 0 auto 24px;
cursor: pointer;
transition: transform .2s ease;
}
.fortune-box:hover {
transform: scale(1.05);
}
.fortune-box:active {
transform: scale(0.95);
}
/* The mailbox image itself */
.fortune-icon {
width: 100%;
height: auto;
image-rendering: pixelated; /* Keeps pixel art crisp */
display: block;
}
/* Pink box with the question / the fortune */
.fortune-result {
background: #ffcfe1;
border: 2px dashed #e55c8a;
border-radius: 18px;
padding: 18px 16px;
color: #6d2f44;
font-size: 14px;
line-height: 1.5;
}
We store all the phrases in an array and, on click, pick a random position with Math.random(). If you want the phrase to change only once per day (instead of every click), use today's date as a "seed" and save it in localStorage, so the visitor always sees the same message even if they reload the page.
// List of fortune phrases
const fortunes = [
"✦ Today is a good day to start something new ✦",
"✦ An unexpected smile will brighten your afternoon ✦",
"✦ The patience you have today will be tomorrow's victory ✦",
"✦ Someone is thinking of you fondly ✦",
"✦ Trust your instinct, it won't fail you ✦",
"✦ Today is a perfect day to rest without guilt ✦",
"✦ A small surprise is on its way ✦"
];
function revealFortune() {
const resultBox = document.getElementById("fortuneResult");
// Different phrase every click:
const random = Math.floor(Math.random() * fortunes.length);
resultBox.innerText = fortunes[random];
}
// --- "ONE PHRASE PER DAY" VERSION ---
function revealDailyFortune() {
const resultBox = document.getElementById("fortuneResult");
const today = new Date().toISOString().slice(0, 10); // e.g. "2026-08-08"
const savedDate = localStorage.getItem("fortuneDate");
let savedFortune = localStorage.getItem("fortuneText");
if (savedDate !== today || !savedFortune) {
// If it's a new day, pick a new phrase and save it
const random = Math.floor(Math.random() * fortunes.length);
savedFortune = fortunes[random];
localStorage.setItem("fortuneDate", today);
localStorage.setItem("fortuneText", savedFortune);
}
resultBox.innerText = savedFortune;
}
onclick="revealFortune()" with onclick="revealDailyFortune()" in the HTML, and also call revealDailyFortune() as soon as the page loads with window.onload so it shows up without needing a click..fortune-result.show {
animation: pop .3s ease;
}
@keyframes pop {
0% { transform: scale(0.8); opacity: 0; }
100% { transform: scale(1); opacity: 1; }
}
resultBox.classList.add("show") inside the function.
img/cute-mail.gif for any other pixel art or gif — an envelope, a fortune cookie, a red packet — as long as it's roughly square it'll fit the frame.