Contact us page example
A contact form is not a contact page. This one puts the form next to the things people came looking for — an address, a phone number, and when you are actually open — because a good share of visitors were never going to fill anything in.
Replace YOUR_FORM_ID with a form of your own and this sends to your inbox.
<main class="contact-page">
<section class="details">
<h1>Contact us</h1>
<p class="lede">Questions about pricing, a project, or something that broke? Pick whichever is easiest.</p>
<dl>
<dt>Email</dt>
<dd><a href="mailto:hello@example.com">hello@example.com</a></dd>
<dt>Phone</dt>
<dd><a href="tel:+15550100">+1 (555) 010-0</a></dd>
<dt>Office</dt>
<dd>19 Kingsway<br>London WC2B 6UN</dd>
<dt>Hours</dt>
<dd>Mon–Fri, 9am–6pm</dd>
</dl>
</section>
<form class="enquiry" action="https://submit.formpost.ai/YOUR_FORM_ID" method="POST">
<h2>Send us a message</h2>
<label for="name">Name</label>
<input id="name" type="text" name="name" required>
<label for="email">Email</label>
<input id="email" type="email" name="email" required>
<label for="topic">What is it about?</label>
<select id="topic" name="topic">
<option>General enquiry</option>
<option>Sales</option>
<option>Support</option>
<option>Press</option>
</select>
<label for="message">Message</label>
<textarea id="message" name="message" rows="4" required></textarea>
<button type="submit">Send message</button>
</form>
</main>body {
margin: 0;
padding: 32px 16px;
background: #fff;
font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
color: #111827;
}
.contact-page {
display: grid;
gap: 40px;
max-width: 880px;
margin: 0 auto;
grid-template-columns: 1fr;
}
.details h1 {
margin: 0;
font-size: 30px;
letter-spacing: -0.02em;
}
.lede {
margin: 12px 0 28px;
max-width: 34ch;
line-height: 1.6;
color: #6b7280;
}
.details dl {
margin: 0;
}
.details dt {
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #9ca3af;
}
.details dd {
margin: 4px 0 18px;
line-height: 1.5;
}
.details a {
color: #111827;
}
.enquiry {
display: flex;
flex-direction: column;
padding: 28px;
background: #f9fafb;
border: 1px solid #f3f4f6;
border-radius: 16px;
}
.enquiry h2 {
margin: 0 0 20px;
font-size: 18px;
}
.enquiry label {
margin-bottom: 6px;
font-size: 13px;
font-weight: 600;
color: #374151;
}
.enquiry input,
.enquiry select,
.enquiry textarea {
font: inherit;
margin-bottom: 16px;
padding: 10px 12px;
color: #111827;
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 8px;
}
.enquiry input:focus,
.enquiry select:focus,
.enquiry textarea:focus {
border-color: #111827;
outline: 2px solid rgba(17, 24, 39, 0.1);
}
.enquiry textarea {
resize: vertical;
}
.enquiry button {
padding: 12px 16px;
font: inherit;
font-weight: 600;
color: #fff;
background: #111827;
border: 0;
border-radius: 8px;
cursor: pointer;
}
/* 700px is where this layout actually fits: two ~300px columns, a 64px gap
and the page padding. It is not a tablet width copied from somewhere. */
@media (min-width: 700px) {
.contact-page {
grid-template-columns: 1fr 1fr;
gap: 64px;
padding-top: 24px;
}
}Why the details come first in the markup
In the source, the address block is before the form. On a wide screen they sit side by side so the order is invisible; on a phone the details stack on top. That is the right way round — somebody on a phone looking for your number should not have to scroll past a five-field form to reach it.
It also gives the page a single h1 that describes the page, with the form carrying an h2. A form is a component on the page, not the page itself.
Make the details actionable
- Wrap the email in a mailto: link and the phone in a tel: link. On a phone the number becomes tappable, which is the single highest-intent action on the whole page.
- Use a description list. The dt/dd pairing is what this content is, and it gives you the label styling for free.
- State opening hours with a timezone if you sell across borders. Mon–Fri 9am–6pm means nothing to somebody eight hours away.
- If you have a physical address, write it out as text rather than only embedding a map — text is copyable, indexable and works without loading a third-party script.
The topic dropdown earns its place
It is the one extra field worth having on a contact page, because it is the difference between one inbox that everyone ignores and a message that reaches the right person. Feed it into the subject line from your form settings:
[{{topic}}] Message from {{name}}With that in place, sales and support enquiries are filterable in any mail client without anybody having to read them first.
What to leave off
An embedded map costs several hundred kilobytes and a third-party cookie to show something a static image and a link would say better. A required phone number turns away people who only wanted to send an email. And a captcha on a page this small is usually solving a problem you do not have yet — start with the honeypot, which is invisible and stops most bots.
Questions about this contact form
- What should a contact us page include?
- A form, an email address, and at least one thing that proves you are real — a phone number, a postal address, or opening hours. Visitors who are checking whether you are a legitimate business need those details, and they are never going to fill the form in to ask.
- Should the form or the details come first?
- In the markup, the details. Visually, either. Source order is what a phone and a screen reader follow, and both are better served reaching a phone number before a textarea.
- How do I route enquiries to different departments?
- Add a select and fold its value into the notification subject, so everything stays filterable. If departments need genuinely separate inboxes, create one form per department instead — forms are unlimited on every plan.
- Do I need a map on the contact page?
- Only if people physically visit you. An embedded map is one of the heaviest things you can put on a page and it usually loads third-party cookies; a written address with a link to directions does the same job for nothing.
Related examples
Responsive contact form
Two columns on desktop, one on a phone. CSS grid and a single media query.
Simple contact form
Three fields, a button, and about forty lines of CSS. The one to start from.
Contact form with captcha
Turnstile, hCaptcha or reCAPTCHA — plus the honeypot that does most of the work.
Or go back to all 21 contact form examples.
Give this form an endpoint
Formpost takes the submission, emails it to you and keeps a searchable copy. Free for 250 messages a month, with unlimited forms and no card.