Give your upcoming website a playful introduction with this pixel art launching soon template using HTML5, CSS3, and JavaScript. Inspired by block-building worlds, the design features grassy terrain, square clouds, earthy colors, and crisp pixel-style borders.
The template combines a launch headline, countdown timer, newsletter email field, and “Notify Me” CTA button in a compact, responsive layout. Its original voxel-inspired scenery suits gaming communities, creative projects, and playful product launches. Separate HTML, CSS, and JavaScript files make the content, colors, and launch date easy to customize.
What you will build
You will build a responsive coming soon page with an original block-style design. The template includes:
A customizable text brand name.
A “World Under Construction” announcement badge.
A bold launch headline and supporting message.
Pixel-style clouds, blocky hills, and grass-topped terrain.
A central panel with stepped borders and hard shadows.
A countdown showing days, hours, minutes, and seconds.
A labeled newsletter email field.
A “Notify Me” CTA with a pressed-block effect.
Email validation and clear frontend demo feedback.
A link for following launch progress.
A minimal footer with the current copyright year.
Responsive layouts and reduced-motion support.
HTML source
<!doctype html>
<html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="A new world is taking shape. Follow BLOCKFORGE as we build something awesome, one block at a time.">
<meta name="theme-color" content="#b4def0">
<title>BLOCKFORGE — Launching Soon</title>
</head>
<body>
<div class="scenery" aria-hidden="true">
<div class="sun"></div>
<div class="cloud cloud-one"></div><div class="cloud cloud-two"></div><div class="cloud cloud-three"></div>
<div class="hill hill-back"></div><div class="hill hill-front"></div>
<div class="tree tree-left"><i></i><b></b></div><div class="tree tree-right"><i></i><b></b></div>
<div class="terrain"><div class="grass"></div></div>
</div>
<header class="brand"><a href="./" aria-label="BLOCKFORGE home"><span class="brand-block" aria-hidden="true"></span>BLOCKFORGE<span class="brand-dot">.</span></a></header>
<main class="panel">
<div class="corner corner-tl" aria-hidden="true"></div><div class="corner corner-tr" aria-hidden="true"></div>
<div class="badge"><span aria-hidden="true"></span> WORLD UNDER CONSTRUCTION</div>
<div class="hero-block" aria-hidden="true"><span></span></div>
<p class="eyebrow">A LITTLE PATIENCE. A WHOLE NEW WORLD.</p>
<h1>Launching <span>Soon</span></h1>
<p class="intro">We’re building something awesome,<br class="desktop-break"> one block at a time.</p>
<section class="countdown-section" aria-label="Time until launch">
<div class="countdown" role="timer" aria-live="off" aria-label="Launch countdown">
<div class="time-block"><span id="days" class="number">--</span><span class="unit">DAYS</span></div>
<div class="time-block"><span id="hours" class="number">--</span><span class="unit">HOURS</span></div>
<div class="time-block"><span id="minutes" class="number">--</span><span class="unit">MINUTES</span></div>
<div class="time-block"><span id="seconds" class="number">--</span><span class="unit">SECONDS</span></div>
</div>
<p id="countdown-message" class="countdown-message" role="status"></p>
<noscript><p>The launch is on its way. Enable JavaScript to see the countdown. This demo form requires JavaScript.</p></noscript>
</section>
<section class="newsletter" aria-labelledby="newsletter-heading">
<h2 id="newsletter-heading">Get the launch announcement</h2>
<form id="newsletter-form" novalidate="">
<label for="email">Your email address</label>
<div class="form-row">
<input id="email" name="email" type="email" autocomplete="email" placeholder="you@example.com" required="" aria-describedby="newsletter-note form-feedback">
<button type="submit">Notify Me <span aria-hidden="true">→</span></button>
</div>
<p id="form-feedback" class="form-feedback" role="status" aria-atomic="true"></p>
</form>
<p class="note" id="newsletter-note">Just the good stuff. No spam, no creepers.<br>Demo only — email addresses are not saved.</p>
</section>
<!-- Replace this destination with your project's progress page. -->
<a class="progress-link" href="https://example.com/" target="_blank" rel="noopener noreferrer">Follow Our Progress <span aria-hidden="true">↗</span><span class="sr-only"> (opens in a new tab)</span></a>
<div class="panel-bottom" aria-hidden="true"><span>EST. 2026</span><span>BUILD SOMETHING GREAT.</span></div>
</main>
<footer>© <span id="year">2026</span> BLOCKFORGE <span aria-hidden="true">·</span> A world in the making.</footer>
</body></html>
CSS source
/* Original scenery made with crisp CSS shapes; no external assets. */
:root {
--sky: #b4def0;
--cream: #fffae9;
--ink: #302e24;
--green: #44773a;
--grass: #76a94f;
--dirt: #946341;
--stone: #76766a;
--block: 16px;
--border: 3px solid var(--ink);
--shadow: 6px 6px 0 var(--ink);
--space: 24px;
}
* { box-sizing: border-box; }
body { margin: 0; min-height: 100svh; padding: 30px 24px 22px; display: flex; flex-direction: column; align-items: center; font-family: ui-monospace, "Cascadia Code", "Segoe UI Mono", Consolas, monospace; color: var(--ink); background: var(--sky); isolation: isolate; }
a { color: inherit; }
.brand { margin-bottom: 25px; }
.brand a { display: flex; align-items: center; text-decoration: none; font-weight: 900; font-size: 24px; letter-spacing: -1px; }
.brand-dot { color: var(--green); }
.brand-block { width: 23px; height: 23px; margin-right: 10px; border: var(--border); background: var(--grass); box-shadow: inset -6px -6px 0 var(--green), 3px 3px 0 #7295a0; }
.panel { position: relative; width: min(100%, 640px); padding: 25px 44px 0; text-align: center; background: var(--cream); border: var(--border); box-shadow: var(--shadow); animation: enter 450ms steps(6, end) both; }
.panel::before,.panel::after { content: ""; position: absolute; width: 8px; height: 8px; bottom: 10px; background: #bbb6a0; }
.panel::before { left: 10px; }.panel::after { right: 10px; }
.corner { position: absolute; top: 10px; width: 6px; height: 6px; background: #bbb6a0; }.corner-tl { left: 10px; }.corner-tr { right: 10px; }
.badge { display: inline-flex; align-items: center; gap: 8px; padding: 7px 10px; background: #e8edcd; border: 1px solid #b4bd8f; font-size: 10px; font-weight: 800; letter-spacing: .5px; }
.badge span { width: 6px; height: 6px; background: var(--green); }
.hero-block { position: relative; width: 48px; height: 43px; background: var(--dirt); border: var(--border); margin: 23px auto 20px; box-shadow: 5px 5px 0 #ddd5b7, inset -11px 0 0 #754c35; }
.hero-block::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 12px; background: var(--grass); border-bottom: 4px solid #4d7b3b; }
.hero-block::after { content: ""; position: absolute; width: 6px; height: 6px; left: 8px; bottom: 8px; background: #c18a58; box-shadow: 16px -3px 0 #b98251, 7px -10px 0 #754c35; }
.eyebrow { font-size: 9px; letter-spacing: 1px; font-weight: 700; margin: 0 0 9px; color: #686750; }
h1 { margin: 0; font-size: clamp(34px, 6vw, 53px); line-height: 1.12; font-weight: 900; letter-spacing: -3px; text-shadow: 2px 3px 0 #e0d8b9; }
h1 span { color: var(--green); }
.intro { margin: 16px 0 23px; font-size: 13px; line-height: 1.75; color: #5d5a48; }
.countdown { display: grid; grid-template-columns: repeat(4,minmax(0,1fr)); gap: 12px; }
.time-block { border: 2px solid var(--ink); background: #ede9d7; box-shadow: 3px 3px 0 #b9b5a1; padding: 12px 4px 10px; border-top: 5px solid var(--green); }
.number { display: block; font-size: 33px; font-weight: 800; line-height: 1.1; font-variant-numeric: tabular-nums; }
.unit { display: block; margin-top: 6px; font-size: 9px; letter-spacing: 1px; color: #605e50; }
.countdown-message { margin: 0; font-size: 12px; line-height: 1.6; }.countdown-message:not(:empty) { margin-top: 14px; }
.newsletter { margin-top: 25px; padding-top: 21px; border-top: 2px dashed #d6cfb6; }
h2 { font-size: 15px; margin: 0 0 16px; letter-spacing: -.4px; }
label { display: block; text-align: left; font-size: 10px; font-weight: 700; margin-bottom: 7px; }
.form-row { display: flex; gap: 10px; }
input,button { font: inherit; border: 2px solid var(--ink); border-radius: 0; min-height: 46px; }
input { min-width: 0; flex: 1; padding: 11px 12px; background: #fffef7; color: var(--ink); font-size: 12px; box-shadow: inset 2px 2px 0 #e6e0cb; }
input::placeholder { color: #79766b; opacity: 1; }
button { padding: 10px 17px; background: var(--green); color: #fffced; font-weight: 800; font-size: 12px; cursor: pointer; box-shadow: 3px 3px 0 var(--ink); transition: transform 80ms, box-shadow 80ms; }
button span { margin-left: 8px; }button:hover { background: #365f2e; }button:active { transform: translate(3px,3px); box-shadow: 0 0 0 var(--ink); }
:focus-visible { outline: 3px solid #214e80; outline-offset: 5px; }
input[aria-invalid="true"] { border-color: #a13625; }
.form-feedback { font-size: 12px; line-height: 1.5; margin: 0; text-align: left; }.form-feedback:not(:empty) { margin-top: 12px; }.form-feedback.error { color: #982f20; }
.note { font-size: 9px; line-height: 1.8; color: #706d5b; margin: 12px 0 17px; }
.progress-link { display: inline-flex; align-items: center; justify-content: center; gap: 10px; min-height: 44px; font-size: 11px; font-weight: 800; text-underline-offset: 4px; }.progress-link:hover { color: var(--green); }
.panel-bottom { display: flex; justify-content: space-between; gap: 12px; margin: 13px -30px 0; padding: 12px 12px 11px; border-top: 1px solid #ded7bf; font-size: 8px; color: #797562; letter-spacing: .6px; }
footer { font-size: 9px; line-height: 1.7; text-align: center; margin-top: 23px; padding: 4px 8px; background: var(--sky); }footer > span[aria-hidden] { margin: 0 5px; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
/* Scenery is isolated behind all page content, and clipped at viewport edges. */
.scenery { position: fixed; inset: 0; z-index: -1; overflow: hidden; pointer-events: none; }
.sun { position: absolute; width: 68px; height: 68px; top: 12%; right: 13%; background: #fff1b3; box-shadow: 0 0 0 12px #cbe4df; }
.cloud { position: absolute; width: 120px; height: 24px; background: #edf7f6; box-shadow: 12px 8px 0 #97c8da; animation: drift 28s steps(24,end) infinite alternate; }
.cloud::before,.cloud::after { content: ""; position: absolute; background: inherit; }.cloud::before { width: 44px; height: 22px; left: 20px; top: -22px; }.cloud::after { width: 35px; height: 12px; left: 64px; top: -12px; }
.cloud-one { top: 21%; left: 7%; }.cloud-two { top: 36%; right: 4%; width: 150px; animation-delay: -14s; }.cloud-three { top: 8%; left: 27%; transform: scale(.6); animation-delay: -8s; }
.hill { position: absolute; bottom: 65px; width: 52%; background: #88b3a0; clip-path: polygon(0 45%,10% 45%,10% 25%,23% 25%,23% 0,43% 0,43% 20%,58% 20%,58% 45%,76% 45%,76% 70%,100% 70%,100% 100%,0 100%); height: 220px; }
.hill-back { left: -5%; }.hill-front { right: -8%; height: 170px; background: #6d9c79; transform: scaleX(-1); }
.terrain { position: absolute; bottom: 0; height: 69px; width: 100%; border-top: 4px solid #3b6032; background-color: var(--dirt); background-image: repeating-linear-gradient(90deg,transparent 0 29px,#7d533a 29px 32px),repeating-linear-gradient(0deg,transparent 0 29px,#7d533a 29px 32px); }
.grass { height: 17px; background: var(--grass); border-bottom: 5px solid #4e7739; background-image: repeating-linear-gradient(90deg,transparent 0 24px,#8cbb60 24px 32px); }
.tree { position: absolute; bottom: 69px; width: 100px; height: 156px; }.tree-left { left: 8%; }.tree-right { right: 8%; transform: scale(.75); transform-origin: bottom; }.tree b { position: absolute; bottom: 0; left: 42px; width: 20px; height: 80px; background: #795439; border-right: 6px solid #61442f; }.tree i { position: absolute; top: 0; left: 0; z-index: 1; width: 100px; height: 93px; background: #4f7e42; clip-path: polygon(20% 0,80% 0,80% 20%,100% 20%,100% 80%,80% 80%,80% 100%,0 100%,0 25%,20% 25%); box-shadow: inset -20px -20px 0 #406d37; }
@keyframes drift { from { translate: -10px 0; } to { translate: 25px 0; } }
@keyframes enter { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@media (min-height: 850px) { body { justify-content: center; } }
@media (max-width: 600px) { body { padding: 23px 20px 20px; }.panel { padding: 24px 23px 0; }.brand { margin-bottom: 22px; }.tree-left { left: -35px; }.tree-right { right: -30px; }.panel-bottom { margin-left: -12px; margin-right: -12px; font-size: 7px; }.cloud-one { left: -45px; }.sun { right: 5%; } }
@media (max-width: 390px) { .countdown { grid-template-columns: repeat(2,minmax(0,1fr)); gap: 10px; }.form-row { flex-direction: column; }button { width: 100%; }.badge { font-size: 8px; padding: 7px; }.eyebrow { font-size: 8px; letter-spacing: .2px; }h1 { font-size: 34px; letter-spacing: -2px; }.hero-block { margin: 20px auto; }.panel { padding-inline: 20px; }.desktop-break { display: none; } }
@media (prefers-reduced-motion: reduce) { *,*::before,*::after { animation: none !important; transition: none !important; } }
/* Stack the signup controls on mobile while retaining four timer columns
until the viewport becomes narrow enough to need two rows. */
@media (max-width: 600px) {
.form-row { flex-direction: column; }
button { width: 100%; }
}
JavaScript source
"use strict";
// EDIT THIS CONSTANT: launch date in ISO 8601 format, including its timezone offset.
const LAUNCH_DATE = "2027-06-01T09:00:00+05:30";
const launchTimestamp = Date.parse(LAUNCH_DATE);
const countdownMessage = document.getElementById("countdown-message");
const units = ["days", "hours", "minutes", "seconds"].map((id) => document.getElementById(id));
let countdownInterval;
function updateCountdown() {
const remaining = Math.max(0, launchTimestamp - Date.now());
const totalSeconds = Math.floor(remaining / 1000);
const values = [
Math.floor(totalSeconds / 86400),
Math.floor(totalSeconds / 3600) % 24,
Math.floor(totalSeconds / 60) % 60,
totalSeconds % 60,
];
units.forEach((element, index) => { element.textContent = String(values[index]).padStart(2, "0"); });
if (remaining === 0) {
clearInterval(countdownInterval);
countdownMessage.textContent = "The countdown is complete. Watch for our launch announcement!";
}
}
if (Number.isFinite(launchTimestamp)) {
updateCountdown();
if (launchTimestamp > Date.now()) countdownInterval = setInterval(updateCountdown, 1000);
} else {
units.forEach((element) => { element.textContent = "--"; });
countdownMessage.textContent = "Our launch date is being finalized. Watch for our launch announcement!";
}
document.getElementById("year").textContent = new Date().getFullYear();
const form = document.getElementById("newsletter-form");
const email = document.getElementById("email");
const feedback = document.getElementById("form-feedback");
form.addEventListener("submit", (event) => {
event.preventDefault();
email.value = email.value.trim();
if (!email.validity.valid) {
email.setAttribute("aria-invalid", "true");
feedback.classList.add("error");
feedback.textContent = email.validity.valueMissing ? "Enter your email address to try the demo." : "Enter a valid email address, such as you@example.com.";
email.focus();
return;
}
email.removeAttribute("aria-invalid");
feedback.classList.remove("error");
// INTEGRATION POINT: send email.value to your backend endpoint or newsletter
// provider here. Await its response before showing actual subscription success.
// This demo makes no network request and never stores email addresses.
feedback.textContent = "Demo complete! No subscription has been created, and your email has not been saved.";
form.reset();
});
email.addEventListener("input", () => {
if (email.hasAttribute("aria-invalid")) {
email.removeAttribute("aria-invalid");
feedback.textContent = "";
feedback.classList.remove("error");
}
});
How it works
The project uses index.html for the page structure, style.css for the pixel scenery and responsive design, and script.js for the countdown and email validation. Collecting newsletter subscriptions requires connecting the form to an email service or backend.
Try a change
Choose Edit code, make a small change, then press Run to preview it.
Use the source Copy buttons, choose Edit code to open the editor, or Download ZIP to save the project after a six-second countdown.





.webp)

Discussion (0)
Leave a comment