Designer view

Login Form

The canonical credentials surface — a `<form>` with an identifier field (email or username), a password field with a visibility toggle, a primary submit button, and secondary affordances (forgot-password link, sign-up link). Composes TextInput twice, Button, and Link. Single-page variant is canonical; split-page ("email first, password on next screen") is documented as a decision rather than a separate pattern.

Composition

  1. Text Input identifier field (email or username)

    Use `type="email"` with `autocomplete="email"` for the contemporary canonical login. For dual identifier flows (email or username accepted), use `type="text"` with `autocomplete="username"` and accept any string. Initial focus lands here unless the page is loaded with the field pre-filled by autofill.

  2. Text Input password field

    Use `type="password"` with `autocomplete="current-password"` for the login flow specifically (signup uses `new-password`). The trailing-icon slot hosts the visibility toggle as a real `<button type="button">` — never the password input itself with `type` flipping. The `required` attribute pairs with a visible required indicator.

  3. Button primary action (submit)

    Use `variant="primary"` and `type="submit"`. The button label names the action ("Sign in", "Log in") — never generic "Submit" or "OK". The button must be inside the `<form>` so Enter on either field submits.

  4. Link forgot-password recovery

    Use `variant="inline"` placed near the password field (above it or to the right). Routes to the password-recovery flow. Distinguished from the sign-up link by position and by the verb of its text ("Forgot your password?").

  5. Link alternate-flow link (sign up / register)

    Use `variant="inline"` placed near the submit button (typically below it). Routes to the registration flow when the user has no account. Optional — omit if the product has no public sign-up (B2B SaaS with admin-provisioned accounts).

When to use

Use
For account-based products where the user authenticates with a credential the system can verify. The canonical entry point when the auth model is "the user has previously created an account and is now returning". Single-page variant for the common case; split-page for products with passwordless or federated-identity flows where the email determines the next step.
Avoid
For unauthenticated browsing — gate only what genuinely requires identity. For machine-to-machine auth — that is API keys, not a login form. For one-off email-magic-link flows — that pattern (single email field plus Send button) is a distinct passwordless-login pattern. For role-elevated re-authentication ("confirm your password to delete account") use a `Confirmation Flow` with a password TextInput inside, not a full Login Form.

Canonical decisions

  1. Single-page (email + password together) or split-page (email first, password on next screen)?

    Single-page is the canonical default; split-page is a product decision tied to passwordless / federated flows.

    Single-page is faster for users with stored credentials in a password manager (one form, one autofill, one submit). Split-page only pays off when the email determines the flow (federated-SSO redirect, passwordless magic-link, MFA-only-account). Google, Microsoft, Apple use split-page because email selects the auth provider; most other products do not have that fork. Default to single-page; split when the email-routes-to-different-flow constraint is real.

  2. Show "wrong email" and "wrong password" as separate errors, or as a single combined error?

    Single combined error — "Wrong email or password" — for production; never disclose which one was wrong.

    Specific errors leak account-existence information. An attacker enumerating addresses can probe the form: a "wrong password" response confirms the email is registered; a "wrong email" response confirms it is not. The combined message removes the enumeration oracle. Pair with rate-limiting and CAPTCHA-on-failure for the complete defence; the message text alone is necessary not sufficient. OWASP ASVS 2.1, NIST SP 800-63B, and the Auth0 / Okta security guides all converge on this rule.

  3. Should the password field have a visibility toggle?

    Yes — recommended for all login forms.

    The visibility toggle reduces typo-driven failed-login attempts (especially on mobile, where touch keyboards hide the typed character after a brief reveal). The security objection — "shoulder-surfing in public spaces" — is mitigated by the toggle defaulting to hidden and requiring an explicit press. The accessibility benefit to users with motor or vision differences is large. NIST SP 800-63B explicitly recommends allowing password reveal. The toggle button is a real `<button>` with an accessible label that updates ("Show password" / "Hide password").

  4. Where does initial focus land?

    The first empty field — usually the email input, unless browser autofill has populated it, in which case focus the password.

    Auto-focusing the page on load forces a scroll on mobile (the on-screen keyboard pops up immediately and shifts the layout). The trade is between "fast for keyboard users" and "jarring for mobile users". Canonical resolution: do focus the email field on `DOMContentLoaded` for desktop (`@media (hover: hover) and (pointer: fine)`) and skip the autofocus on touch devices. Or simpler: do not auto-focus at all and rely on the user's tap or Tab. The "no autofocus" rule is the more conservative canon; document both choices.

  5. What `autocomplete` tokens go on each field?

    Email field: `autocomplete="email"` (or `username` if the identifier is not strictly an email). Password field: `autocomplete="current-password"`. Sign-up flows use `new-password` instead.

    The autocomplete tokens are how browsers and password managers recognise the form. `current-password` tells the manager "this is the field where the existing stored password should fill in"; `new-password` tells it "this is a registration form, suggest a strong new password". Mixing them — using `new-password` on a login form — breaks autofill and forces the user to type the password manually every time. The HTML spec lists the full token set; getting these right is the difference between a form that works with 1Password and one that does not.

  6. Is the email field required?

    Yes — both fields are required. Pair the visible required indicator with the `required` HTML attribute on each input.

    Browser-native validation surfaces the empty-required message at the right moment (form submit). Server-side validation must still run; client-side `required` is for UX, not security. The visible indicator (asterisk or "(required)") tells users before they try to submit; the attribute tells the browser and assistive tech.

Notes

This is the second canonical pattern after Confirmation Flow. Triangulated against APG (textbox + button patterns), HTML spec on `autocomplete`, NIST SP 800-63B (password guidance + reveal- is-allowed), OWASP ASVS 2.1 (authentication), Polaris Account pattern, Material 3 Sign-in Form, and the auth0 / Okta / WorkOS engineering blogs on enumeration-resistant login forms. Library APIs and security guidance evolve; re-validate against current docs and threat-modelling discipline before citing in production reviews. Sign-up Form, Password Recovery Flow, and Magic-Link Login are sibling patterns deferred to follow-up work.