Keyboard Navigation
SmarkForm adds keyboard navigation to supported fields. The exact behavior also depends on the form’s markup, native controls, browser, and enabled features.
Enter / Shift+Enter Navigation
Press Enter to move forward to the next field, and Shift+Enter to move backward. This field-navigation shortcut skips buttons and other non-field components. Use Tab and Shift+Tab for the browser’s normal sequential focus order; disabled controls and the form’s authored markup affect that order.
Tab-Flow Exclusion for Hotkey-Equipped Buttons
Hotkey-equipped addItem and removeItem triggers inside their list context are removed from sequential Tab order, so a long list does not require tabbing through every row action. Hotkey-equipped controls outside that list context remain in Tab order, including an outer Add button.
- Inner buttons (inside list context): Removed from
Tabflow — users can activate them via their hotkey instead. - Outer buttons (siblings of the list): Kept in
Tabflow — withmin_items: 0, the only way to create the first item is via the outer add button, which must remain keyboard-accessible.
This tab-order behavior is limited to list
addItem/removeItemtriggers with hotkeys in their list context. SmarkForm setstabindex="-1"when the trigger has no authoredtabindex; an explicit authored value is preserved. If an action is essential, provide a visible control that remains in the normal keyboard order; do not rely on a CSS-generated hotkey hint as its only description.
Hold
Ctrlto discover available hotkeys — each trigger button with a hotkey can show a visual hint when the form includes the corresponding CSS.
Alt+Enter for Collapsed Sections
When navigating with Enter / Shift+Enter, fields inside a closed <details> element are skipped. To navigate into them, hold Alt while pressing Enter — SmarkForm automatically opens any closed <details> ancestors along the path. When moving forward from a <textarea>, keep Ctrl held as well (Ctrl+Alt+Enter); plain Enter inserts a newline there. For backward navigation into a preceding closed section, use Alt+Shift+Enter.
This allows you to keep optional sections collapsed by default while still being able to navigate into them when you need to fill data.
Sequential Enter navigation follows SmarkForm fields, not the browser’s native <summary> focus stop. Each address row below is a SmarkForm form in the list, with a field in its summary. A bare summary can still toggle the native disclosure, but focus there is not a field in SmarkForm’s navigation tree; the next Enter cannot continue from that point into the section’s fields.
Using <details> as List Items
A powerful design pattern is to wrap each list item in a <details> element with the item’s key identifying field placed inside the <summary>. This way, even when collapsed, the key information remains visible so the user can quickly scan the list, while the full details expand on click.
SmarkForm fields inside the <details> work exactly as they would anywhere else — the browser handles the show/hide toggle natively. Shift+Space on a field inside a <summary> toggles its <details> section; on a field in the open body it folds the section and returns focus within its summary (to its first focusable child, or to the summary itself). Alt+Enter provides a separate way to navigate into a collapsed section. Use semantic markup and test focus and announcements with your target assistive technology.
The contacts example below preserves the key field inside each collapsed summary. Its co-located test checks Space/Shift+Space, forward/backward list navigation, and Alt+Enter / Alt+Shift+Enter into hidden fields.
<div id="myForm">
<div data-smark='{"name":"contacts","type":"list","min_items":1,"export_empties":false}'>
<details>
<summary>
<input data-smark type="text" name="fullname" placeholder="Full name">
</summary>
<div class="contact-details">
<input data-smark type="email" name="email" placeholder="Email">
<input data-smark type="tel" name="phone" placeholder="Phone">
<button data-smark='{"action":"removeItem","failback":"clear","hotkey":"Delete"}' title="Remove">🗑</button>
</div>
</details>
</div>
<button data-smark='{"action":"addItem","context":"contacts","hotkey":"+"}'>➕ Add contact</button>
<textarea data-smark name="notes" placeholder="Notes about this contact list"></textarea>
</div>
#myForm {
font-family: sans-serif;
}
#myForm details {
border: 1px solid #ccc;
border-radius: 4px;
margin-bottom: 6px;
padding: 4px 8px;
}
#myForm summary {
display: flex;
align-items: center;
gap: 6px;
cursor: pointer;
list-style: none;
user-select: none;
}
#myForm summary::before {
content: "▶";
font-size: .75em;
transition: transform .15s;
flex-shrink: 0;
}
#myForm details[open] > summary::before {
transform: rotate(90deg);
}
#myForm summary input {
flex: 1;
min-width: 0;
font-weight: bold;
border: none;
background: transparent;
outline: none;
}
#myForm .contact-details {
display: flex;
flex-wrap: wrap;
gap: 6px;
padding: 6px 0 2px 1.2em;
}
#myForm .contact-details input {
flex: 1;
min-width: 120px;
}
#myForm .contact-details button {
margin-left: auto;
}
#myForm textarea[name="notes"] {
display: block;
width: 100%;
min-height: 60px;
margin-top: 8px;
padding: 6px 8px;
border: 1px solid #ccc;
border-radius: 4px;
font-family: inherit;
box-sizing: border-box;
resize: vertical;
}
/* Hold Ctrl to reveal hotkey hints. */
#myForm [data-hotkey] { position: relative; }
#myForm [data-hotkey]::after {
content: "Ctrl+" attr(data-hotkey);
position: absolute; top: 0.75em; left: 0;
font-size: .7em; background: #333; color: #fff;
padding: 1px 4px; border-radius: 3px; white-space: nowrap;
}
const myForm = new SmarkForm(document.getElementById("myForm"), {
"value": {
"contacts": [
{"fullname":"Alice Smith","email":"alice@example.com","phone":"+1 555 100 0001"},
{"fullname":"Bob Jones","email":"bob@example.com","phone":"+1 555 100 0002"},
{"fullname":"Carol White","email":"carol@example.com","phone":"+1 555 100 0003"}
],
"notes": ""
}
});// Native details plus SmarkForm keyboard navigation; no custom JS is needed.
Maintain a contact list with expandable details
Try it: Edit a contact name in the summary, expand its details, and use Enter, Shift+Enter, Alt+Enter, and Alt+Shift+Enter to test forward/backward navigation across collapsed list items.
The shared JSON editor is disabled because its controls would add extra fields and tab stops to this keyboard-navigation example.