The short version
- A waitlist page should fit on one screen: one line about the outcome, one labelled email field, one button and a sentence about what happens next.
- Ask only for an email address on the page, and save any extra questions for the confirmation screen.
- An accessible waitlist form uses a visible label, type email with autocomplete, targets at least 44 px tall, text errors linked with aria-describedby and a status message on success.
- Text on the page's gradient ground needs at least 4.5:1 contrast against the lightest part behind it, or 3:1 for large headings.
- Use the same ground and the same line in the 1200 × 630 share image and the launch posts so every link looks like the same product.
On this page
Good waitlist page design is one screen that does one job: earn an email address. The page needs a single line that says what you are making and for whom, one email field with a visible label, a button that names the action, one short sentence about what happens next, and a confirmation state that tells people they are in. Put it all on a ground that already looks like your brand, so the page, the share image and the launch post read as the same product from day one.
What a waitlist page needs, and nothing else
A waitlist page is a landing page with the argument cut down to its first screen. Nobody can try the product yet. What converts is clarity: who it is for, what changes for them, and how little they have to give to hear more.
Avoid
- A headline about the company instead of the reader
- Name, company, role and team size fields
- A button that says Submit
- Navigation, a blog link and five social icons
- A stock photo of people pointing at a laptop
- Silence after the click
Do
- One line about the outcome: Invoices that chase themselves.
- One field: email, with a visible label
- A button that says what happens: Join the waitlist
- A logo and nothing else to click away to
- Your brand ground filling the whole screen
- A clear confirmation and one next step
Write the one line first
The headline carries the whole page, so write it before you choose a colour. Lead with the result your reader wants, in their words, in under ten words. Then add one supporting sentence that names who it is for or how it works.
Stronger line
Why
Stronger line
Why
Stronger line
Why
Design the form so everyone can use it
The form is the only interactive part of the page, so it has to work for keyboards, screen readers and thumbs.
- 1
Give the field a real label
A visible
<label for>tied to the input, never placeholder text alone. Placeholders vanish as people type and are often too faint to read. See WebAIM on accessible forms. - 2
Use the right input type
type="email"brings up the email keyboard on phones andautocomplete="email"lets browsers fill it in one tap. Keep the input text at 16 px or larger so mobile browsers do not zoom in on focus. - 3
Make targets big enough to hit
Give the field and button at least 44 px of height. WCAG's minimum target size is 24 px, but a thumb on a phone is happier at 44 or more.
- 4
Write errors people can act on
Show the error as text next to the field, start it with the word Error, connect it with
aria-describedbyand setaria-invalidon the input. Colour alone is not an error message. - 5
Announce the result
When the email is accepted, replace the form with a message in a
role="status"region and move focus to it, so screen reader users hear that it worked. - 6
Check contrast on the ground
Body text needs at least 4.5:1 against the lightest part of the background behind it, large headings 3:1, and the field and button edges 3:1. MDN explains the contrast rules.
A minimal accessible waitlist hero you can copy
This hero is plain HTML and CSS: a full screen gradient ground, one line, one labelled field and a hint that says what happens next. Text sits in white and pale lilac on a ground that never gets lighter than #6d28d9, so white text clears 7:1 and the lilac #e9d5ff clears 5:1 at the brightest corner. A solid background-color sits under the gradient as a fallback.
<main class="waitlist">
<p class="eyebrow">Tidewell · opening this spring</p>
<h1>Invoices that chase themselves.</h1>
<p class="lede">Tidewell sends the polite reminder so you never have to.</p>
<form class="join" action="/api/waitlist" method="post" novalidate>
<label for="email">Work email</label>
<div class="row">
<input id="email" name="email" type="email" autocomplete="email"
required aria-describedby="email-hint email-error">
<button type="submit">Join the waitlist</button>
</div>
<p id="email-hint" class="hint">One email when we open. No newsletter.</p>
<p id="email-error" class="error"></p>
</form>
<p class="done" role="status" tabindex="-1"></p>
</main>
<style>
.waitlist {
min-height: 100svh;
display: grid;
align-content: center;
gap: 1rem;
padding: 2rem max(1.25rem, calc(50% - 17rem));
color: #ffffff;
background-color: #3b0f78;
background-image: linear-gradient(160deg, #1e0b3d 0%, #3b0f78 55%, #6d28d9 100%);
font: 1rem/1.5 system-ui, sans-serif;
}
.waitlist h1 { font-size: clamp(2rem, 7vw, 3.5rem); line-height: 1.05; margin: 0; }
.eyebrow, .lede, .hint { color: #e9d5ff; margin: 0; }
.join label { display: block; font-weight: 600; margin-bottom: .375rem; }
.row { display: flex; flex-wrap: wrap; gap: .5rem; }
.row input {
flex: 1 1 14rem;
min-height: 3rem;
padding: 0 .875rem;
font: inherit; /* 16px: no zoom on focus */
color: #1e0b3d;
background: #ffffff;
border: 2px solid #ffffff;
border-radius: .5rem;
}
.row input[aria-invalid="true"] { border-color: #fecaca; }
.row button {
min-height: 3rem;
padding: 0 1.25rem;
font: inherit;
font-weight: 700;
color: #3b0f78;
background: #ffffff;
border: 0;
border-radius: .5rem;
cursor: pointer;
}
.error { color: #fecaca; font-weight: 600; margin: 0; }
.waitlist :focus-visible { outline: 3px solid #fde68a; outline-offset: 3px; }
@media (max-width: 30rem) { .row button { flex: 1 1 100%; } }
</style>The confirmation state is half the page
Most waitlist pages stop at the click. The moment after is when people are most interested, so use it. Tell them they are in, tell them exactly what happens next, and give them one thing to do: confirm the email, or share the page.
const form = document.querySelector('.join')
const email = form.elements.email
const error = document.getElementById('email-error')
const done = document.querySelector('.done')
form.addEventListener('submit', async (event) => {
event.preventDefault()
if (!email.validity.valid) {
error.textContent = 'Error: enter an email like name@studio.com'
email.setAttribute('aria-invalid', 'true')
email.focus()
return
}
const res = await fetch(form.action, { method: 'POST', body: new FormData(form) })
if (!res.ok) {
error.textContent = 'Error: that did not go through. Please try again.'
return
}
form.hidden = true
done.textContent = 'You are on the list. Check your inbox to confirm your email.'
done.focus()
})- Say what happens next. One email when you open, a confirmation link now, or both. Then do exactly that.
- Send the confirmation email straight away and make its header match the page, so people recognise it in a crowded inbox.
- Offer one share action, such as copying the page link. A confirmed fan is your best channel before launch.
Make the share image match the page
Every waitlist link gets pasted into chats, posts and DMs, and the preview card is often the first thing people see. Give the page a 1200 × 630 Open Graph image with the same ground and the same line as the hero. Open Graph image size covers the tags, and if the card comes out bare, OG image not showing walks through the fixes.
Page hero
1920 × 1080
Share image
1200 × 630
X post
1600 × 900
Story
1080 × 1920
The waitlist hero at 1920 × 1080: the ground fills the screen and the line sits in its calmest area.
The same ground and line as a 1080 × 1920 story, so the post and the page feel like one thing.
This is where a Mark helps. A Mark is a living gradient ground that renders behind your words and keeps them readable, so the hero, the share image and the launch post can all wear the same one. Claim a Mark and nobody else can design with it, which means no other waitlist ends up looking like yours. If you want to see your name on a few grounds before deciding, Try on your brand shows your brand on a site, an X header and more in a minute, with no account.
Choose a brand ground that lets the line win
The ground does the work a photo would do on a normal landing page, without competing with the words. Pick one with a calm, darker region where the headline sits and keep the busiest colour away from the field. Text on a gradient goes deeper on keeping type readable.
Keep it fast on a phone
Most people open a waitlist link from a social app on their phone, so design at 390 px wide first and widen later. Speed is part of the design: a CSS gradient ground needs no download, the form needs no framework, and the whole page can paint in one round trip. Aim for a Largest Contentful Paint under 2.5 seconds, the threshold web.dev calls good. If the ground moves, keep it slow and honour reduced motion. CSS gradient performance explains why gradients are cheap and when a large image or video is not.
Questions people ask
What should a waitlist page include?
A headline about the outcome, one supporting sentence, an email field with a visible label, a button that names the action, a line about what happens next and a confirmation state. Everything else can wait until launch.
Should a waitlist form ask for a name?
Usually not. Each extra field gives people a reason to leave, so ask only for email and put any optional question on the confirmation screen.
How do I make a waitlist form accessible?
Use a real label, type="email" with autocomplete="email", targets at least 44 px tall, text errors linked with aria-describedby, and announce success in a role="status" region.
Can I use a gradient background on a waitlist page?
Yes. A CSS gradient needs no download and fills any screen. Keep text above 4.5:1 contrast against the lightest stop behind it and set a solid background colour as a fallback.
What size should the waitlist share image be?
Use 1200 × 630 for the Open Graph image, with the same ground and headline as the page, so links look the same in every chat and feed.
Written by Gradiently
The team behind Gradiently, a design tool built around Marks: living gradients that make everything you design look like yours.
See our profile