Simple Contact Form
A centred name, email and message form with inline validation and no chrome.
3 frameworksBeginner
A contact form followed by a row of social icon links.
<!--
Each social link is an <a> with an aria-label ("Follow us on X"): the glyph is
aria-hidden, so a screen reader announces a named link, not a lone SVG. Targets
are 40px so they clear the touch minimum.
-->
<section class="mx-auto w-full max-w-lg px-4 py-12 sm:py-16">
<h2 class="text-2xl font-bold tracking-tight text-gray-900 sm:text-3xl dark:text-gray-100">Say hello</h2>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-400">Fill in the form, or reach us on your platform of choice.</p>
<form class="mt-6 space-y-4">
<div>
<label for="cso-name" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Name</label>
<input id="cso-name" name="name" type="text" autocomplete="name" required class="mt-1.5 block w-full rounded-lg border border-gray-300 bg-white px-3.5 py-2.5 text-sm text-gray-900 focus-visible:border-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:focus-visible:ring-blue-400" />
</div>
<div>
<label for="cso-email" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Email</label>
<input id="cso-email" name="email" type="email" autocomplete="email" required class="mt-1.5 block w-full rounded-lg border border-gray-300 bg-white px-3.5 py-2.5 text-sm text-gray-900 focus-visible:border-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:focus-visible:ring-blue-400" />
</div>
<div>
<label for="cso-message" class="block text-sm font-medium text-gray-700 dark:text-gray-300">Message</label>
<textarea id="cso-message" name="message" rows="4" required class="mt-1.5 block w-full resize-y rounded-lg border border-gray-300 bg-white px-3.5 py-2.5 text-sm text-gray-900 focus-visible:border-transparent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-100 dark:focus-visible:ring-blue-400"></textarea>
</div>
<button type="submit" class="inline-flex w-full items-center justify-center rounded-lg bg-blue-600 px-5 py-2.5 text-sm font-semibold text-white transition-colors hover:bg-blue-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 focus-visible:ring-offset-2 focus-visible:ring-offset-white motion-reduce:transition-none dark:focus-visible:ring-blue-400 dark:focus-visible:ring-offset-gray-900">Send message</button>
</form>
<div class="mt-6 flex items-center gap-3">
<span class="text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">Or find us</span>
<span class="h-px flex-1 bg-gray-200 dark:bg-gray-800"></span>
</div>
<div class="mt-4 flex gap-2">
<a href="#" aria-label="Follow us on X" class="flex h-10 w-10 items-center justify-center rounded-lg border border-gray-200 text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 motion-reduce:transition-none dark:border-gray-800 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-100">
<svg viewBox="0 0 24 24" fill="currentColor" class="h-4 w-4" aria-hidden="true"><path d="M18.9 1.2h3.7l-8 9.1 9.4 12.5h-7.4l-5.8-7.6-6.6 7.6H.5l8.6-9.8L0 1.2h7.6l5.2 6.9 6.1-6.9Zm-1.3 19.5h2L6.5 3.3H4.4l13.2 17.4Z" /></svg>
</a>
<a href="#" aria-label="Follow us on GitHub" class="flex h-10 w-10 items-center justify-center rounded-lg border border-gray-200 text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 motion-reduce:transition-none dark:border-gray-800 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-100">
<svg viewBox="0 0 24 24" fill="currentColor" class="h-4 w-4" aria-hidden="true"><path d="M12 .5a12 12 0 0 0-3.8 23.4c.6.1.8-.3.8-.6v-2c-3.3.7-4-1.6-4-1.6-.6-1.4-1.3-1.8-1.3-1.8-1.1-.7 0-.7 0-.7 1.2.1 1.8 1.2 1.8 1.2 1.1 1.8 2.8 1.3 3.5 1 .1-.8.4-1.3.8-1.6-2.7-.3-5.5-1.3-5.5-5.9 0-1.3.5-2.4 1.2-3.2 0-.4-.5-1.6.2-3.2 0 0 1-.3 3.3 1.2a11.5 11.5 0 0 1 6 0c2.3-1.5 3.3-1.2 3.3-1.2.7 1.6.2 2.8.1 3.2.8.8 1.2 1.9 1.2 3.2 0 4.6-2.8 5.6-5.5 5.9.4.4.8 1.1.8 2.2v3.3c0 .3.2.7.8.6A12 12 0 0 0 12 .5Z" /></svg>
</a>
<a href="#" aria-label="Follow us on LinkedIn" class="flex h-10 w-10 items-center justify-center rounded-lg border border-gray-200 text-gray-600 transition-colors hover:bg-gray-100 hover:text-gray-900 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 motion-reduce:transition-none dark:border-gray-800 dark:text-gray-400 dark:hover:bg-gray-800 dark:hover:text-gray-100">
<svg viewBox="0 0 24 24" fill="currentColor" class="h-4 w-4" aria-hidden="true"><path d="M4.98 3.5A2.5 2.5 0 1 1 0 3.5a2.5 2.5 0 0 1 4.98 0ZM.24 8.2H4.7V24H.24V8.2Zm7.4 0h4.27v2.16h.06c.6-1.13 2.06-2.32 4.24-2.32 4.54 0 5.38 2.99 5.38 6.87V24h-4.46v-7.24c0-1.73-.03-3.95-2.4-3.95-2.4 0-2.77 1.88-2.77 3.82V24H7.64V8.2Z" /></svg>
</a>
</div>
</section>| Prop | Type | Default | Description |
|---|---|---|---|
title | string | 'Say hello' | Heading text for the card. |
description | string | - | Description |
socials | SocialLink[] | - | Social profile links rendered as icons. |
submitLabel | string | 'Send message' | Submit label |
onSubmit | (values: ContactFormValues) => void | - | Called with the form's values when it is submitted. |
className | string | - | Additional classes merged onto the root element. |
Each social link is an `<a>` with an `aria-label` while the glyph is `aria-hidden`, so screen readers announce a named link rather than a lone SVG; the icons are inline SVG (X, GitHub, LinkedIn) and the targets are 40px to clear the touch minimum. Swap the `socials` prop for your own handles.