form
Associates a form control with a form element by ID, even when the control is outside the form's DOM tree. Enables complex layouts without nesting constraints.
Overview
The form attribute associates a form control with a <form> element by referencing the form's id. The control does not need to be a descendant of the form — it can be anywhere in the document. When the form is submitted, all associated controls (both nested and remote) are included in the form data.
This solves a real layout problem: sometimes the visual design requires form controls to be placed outside the form's DOM tree. Sticky footers, sidebar filters, dialog-based settings, and split-panel editors all benefit from this attribute.
Applies to: <input>, <select>, <textarea>, <button>, <output>, <fieldset>
Values
| Attribute | Value | Effect |
|---|---|---|
form="form-id" | The id of a <form> | Associates the control with that form |
(no form attribute) | — | Control belongs to its nearest ancestor <form> |
Basic Association
Place a control anywhere on the page and point it at a form with the form attribute. The value must exactly match the form's id.
<form id="checkout" action="/checkout" method="post" class="stacked"> <label for="item">Item</label> <input type="text" id="item" name="item" /> <label for="qty">Quantity</label> <input type="number" id="qty" name="qty" min="1" value="1" /> <button type="submit">Purchase</button></form> <!-- This input is outside the form's DOM tree but belongs to it --><label for="promo">Promo Code</label><input type="text" id="promo" name="promo_code" form="checkout" />
Sticky Footer Buttons
A common layout: the form is in the content area and the submit/action buttons are in a sticky footer outside the form. The form attribute on the buttons connects them to the form.
<!-- Form in the main content area --><form id="editor" action="/save" method="post" class="stacked"> <label for="title">Title</label> <input type="text" id="title" name="title" required /> <label for="content">Content</label> <textarea id="content" name="content" rows="10" required></textarea></form> <!-- Sticky footer is outside the form --><footer style="position: sticky; bottom: 0; background: var(--color-surface-raised); padding: 1rem;"> <button type="submit" form="editor">Save</button> <button type="submit" form="editor" formaction="/preview" formmethod="get"> Preview </button></footer>
The formaction and formmethod attributes work on remote buttons just as they do on nested buttons. See novalidate for the formnovalidate pattern.
Multiple Forms on One Page
When a page has multiple forms, the form attribute lets you assign shared controls to the correct form without nesting them.
<!-- Two forms on the same page --><form id="search-form" action="/search" method="get"> <label for="q">Search</label> <input type="search" id="q" name="q" /> <button type="submit">Search</button></form> <form id="filter-form" action="/search" method="get"> <fieldset> <legend>Filters</legend> <label><input type="checkbox" name="type" value="article" /> Articles</label> <label><input type="checkbox" name="type" value="video" /> Videos</label> </fieldset> <button type="submit">Apply Filters</button></form> <!-- This field submits with the search form, not the filter form --><label for="sort">Sort by</label><select id="sort" name="sort" form="search-form"> <option value="relevance">Relevance</option> <option value="date">Date</option> <option value="title">Title</option></select>
Supported Elements
The form attribute works on every form-associated element.
<!-- All these element types support the form attribute --><form id="profile" action="/profile" method="post"> <button type="submit">Save Profile</button></form> <!-- input --><input type="text" name="display_name" form="profile" /> <!-- select --><select name="timezone" form="profile"> <option value="UTC">UTC</option> <option value="EST">Eastern</option> <option value="PST">Pacific</option></select> <!-- textarea --><textarea name="bio" rows="3" form="profile"></textarea> <!-- button --><button type="reset" form="profile">Reset</button> <!-- output --><output name="char_count" form="profile">0</output> <!-- fieldset (associates all its children) --><fieldset form="profile"> <legend>Notifications</legend> <label><input type="checkbox" name="notify_email" /> Email</label> <label><input type="checkbox" name="notify_sms" /> SMS</label></fieldset>
Dialog Pattern
When advanced settings live inside a <dialog>, the fields are in a separate DOM subtree. The form attribute lets them contribute to the main form's submission data.
<form id="settings" action="/settings" method="post" class="stacked"> <label for="name">Display Name</label> <input type="text" id="name" name="name" /> <button type="submit">Save</button></form> <!-- Dialog is a separate DOM subtree, but controls belong to the form --><dialog id="advanced-dialog"> <h2>Advanced Settings</h2> <label for="api-key">API Key</label> <input type="text" id="api-key" name="api_key" form="settings" /> <label for="webhook">Webhook URL</label> <input type="url" id="webhook" name="webhook_url" form="settings" /> <button onclick="this.closest('dialog').close()">Done</button></dialog> <button onclick="document.querySelector('#advanced-dialog').showModal()"> Advanced Settings</button>
JavaScript API
The .form property on form controls returns the associated <form> element, whether the association is via nesting or the form attribute. FormData automatically includes remote controls.
Accessibility<ul> <li>Screen readers associate controls with their form regardless of DOM position when the <code>form</code> attribute is used. The accessibility tree respects the attribute.</li> <li>Tab order follows DOM order, not form association. If a remote control is far from the form in the DOM, it may be reached much earlier or later during keyboard navigation. Place associated controls near the form when possible.</li> <li>Ensure remote controls are visually connected to their form through layout and proximity. Users should understand which form a control belongs to without inspecting the HTML.</li></ul> <h2>Limitations</h2><ul> <li>The <code>form</code> attribute value must be an <code>id</code>, not a selector. It must exactly match the <code>id</code> attribute of a <code><form></code> element on the page.</li> <li>A control can only be associated with one form. If it has a <code>form</code> attribute and is also nested inside a different <code><form></code>, the <code>form</code> attribute wins.</li> <li>Constraint validation applies to remote controls just like nested ones. A remote <a href="/docs/attributes/required/"><code>required</code></a> field will block submission if empty.</li> <li>The <code>form</code> attribute does not work across documents. The form and the control must be in the same document (not in different iframes).</li> <li>Some older JavaScript form libraries may not account for remote controls. If you use <code>form.elements</code> or <code>new FormData(form)</code>, remote controls are included — but manual DOM traversal (e.g., <code>form.querySelectorAll('input')</code>) will miss them.</li></ul> <section> <h2>See Also</h2> <ul> <li><a href="/docs/attributes/novalidate/"><code>novalidate</code> / <code>formnovalidate</code></a> — validation bypass on remote buttons</li> <li><a class="active" href="/docs/elements/native/form/"><code><form></code></a> element reference</li> <li><a href="/docs/elements/native/fieldset/"><code><fieldset></code></a> — group controls (also supports the <code>form</code> attribute)</li> <li><a href="/docs/elements/native/dialog/"><code><dialog></code></a> — modal dialogs where remote controls are useful</li> </ul></section>