Forms and controls
Auth card
The one centred column of an account page: a bordered card with the heading, the form and the help line, and one quiet line under it.
- Block
.hs-auth- CSS
components/auth.css(in/brand.css)- JS
components/password.js: load it only on a page with this component- Status
- Decided
- Decided in
- Components round 4
- Markdown
- /components/auth-card.md
What it is
A column at most 35rem (560px) wide, centred in the container on the white band. Inside it, .hs-auth__card: white, 1px line border, 8px radius, no shadow, padding 20px (32px from 576px). The card opens with .hs-auth__head (optional eyebrow, the heading, the intro). Under the card, .hs-auth__alt holds one centred line with one quiet link. The heading has no gold rule and every route is a quiet Form link: the full-width gold button is the one gold element.
When to use
- Every account page: sign in (
/user/login), reset password (/user/password), the one-time login page, change password and change email. - A page that asks the visitor to sign in first: the 403 “Sign in to continue” state.
- The “Check your email” state after a reset request, with the Confirmation panel in the card.
When not to use
- Registration and the member application (
/join,/member/induction): they are conversion pages with a page head and bands. - A profile edit or a short form over a page: use a Dialog.
- A form inside a content band, such as a contact form on a utility page: use the Form in the band’s container.
Rules
- Markup:
<section class="hs-band" data-section="…">,.hs-container,.hs-auth, then.hs-auth__cardand an optionalp.hs-auth__alt. The band is white. - On an account page the card heading is the page
h1with the size classhs-heading--h2. The template prints no page head. Write the heading as the task: “Reset your password”, “Change email”. - Where the page already has an
h1(a dialog, a band on a member page), the card heading is anh2with the same class, and the eyebrow may name the area (“Account”). - Put no
hs-heading--ruleon the card heading. - Card order: head, an optional notice or form alert, the form, then
.hs-form-dividerand.hs-form-note. The form ends with one.hs-button.hs-button--block. - Give every route in and under the card
.hs-form-link. Put “Forgot your password?” in the password field’s hint slot. - Use
.hs-auth__altfor one secondary route only, such as “New to Honor Society? Join now”. It never holds a button. - Signed-in notice: a
.hs-callout.hs-callout--inforight under the head. Its title names the account inspan.hs-auth__account(“You are signed in as …”); its text holds theSign outlink, which returns to the same page. - Give every field its
autocomplete:usernameon the sign-in email,emailon any other email field,current-passwordandnew-passwordon passwords. Email fields taketype="email".
Accessibility
- Contrast on white: heading navy 12.4:1, intro slate 6.2:1, card border line (decorative; the fields carry their own 3.7:1 borders).
- One
h1per page. The card and the band name the same thing: label the band witharia-labelledbythe headingid. - The card works without JavaScript.
password.jsonly shows the eye toggle; without it the password field is a plain password input. - At 320px the card is 296px wide with 20px padding; a long email address in the intro or a notice breaks anywhere (
overflow-wrap: anywhere). - After a failed submit, put the form alert under the head and move focus to it.
- The column needs no motion.
Variants
Sign-in card
The full card on the white band, with the copy for /user/login. Type a password and press the eye to show it.
Full-width preview: the snippet sets its own ground
<section class="hs-band" data-section="sign-in" aria-labelledby="ac-signin-h">
<div class="hs-container">
<div class="hs-auth">
<div class="hs-auth__card">
<header class="hs-auth__head">
<h1 class="hs-heading hs-heading--h2" id="ac-signin-h">Honor Society® login</h1>
<p class="hs-auth__intro">Welcome back. Sign in to your account.</p>
</header>
<form class="hs-form" action="/user/login" method="post">
<div class="hs-field">
<label class="hs-label" for="ac-email">Email address</label>
<input class="hs-control" id="ac-email" name="name" type="email" autocomplete="username" spellcheck="false" required>
</div>
<div class="hs-field hs-password">
<label class="hs-label" for="ac-pass">Password</label>
<div class="hs-password__input">
<input class="hs-control" id="ac-pass" name="pass" type="password" autocomplete="current-password" required>
<button class="hs-password__toggle" type="button" aria-label="Show password" aria-pressed="false" aria-controls="ac-pass" hidden>
<svg class="hs-password__icon hs-password__icon--show" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></svg><svg class="hs-password__icon hs-password__icon--hide" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M10.6 5.1A10.4 10.4 0 0 1 12 5c6.4 0 10 7 10 7a17.6 17.6 0 0 1-2.6 3.5M6.6 6.6C3.7 8.5 2 12 2 12s3.6 7 10 7a9.9 9.9 0 0 0 5.4-1.6"/><path d="M9.9 9.9a3 3 0 0 0 4.2 4.2"/><path d="M3 3l18 18"/></svg>
</button>
</div>
<p class="hs-hint"><a class="hs-form-link" href="/user/password" data-ph-capture-attribute-cta="reset-password" data-ph-capture-attribute-cta-loc="sign-in">Forgot your password?</a></p>
</div>
<button class="hs-button hs-button--block" type="submit" data-ph-capture-attribute-cta="sign-in" data-ph-capture-attribute-cta-loc="sign-in">Sign in</button>
</form>
<hr class="hs-form-divider">
<p class="hs-form-note"><strong>Need help signing in?</strong> Visit our <a class="hs-form-link" href="https://support.honorsociety.org/hc/en-us" data-ph-capture-attribute-cta="help-center" data-ph-capture-attribute-cta-loc="sign-in">Help Center</a> or <a class="hs-form-link" href="https://support.honorsociety.org/hc/en-us/requests/new" data-ph-capture-attribute-cta="support-request" data-ph-capture-attribute-cta-loc="sign-in">contact Honor Society support</a>.</p>
</div>
<p class="hs-auth__alt">New to Honor Society? <a class="hs-form-link" href="/join" data-ph-capture-attribute-cta="join" data-ph-capture-attribute-cta-loc="sign-in">Join now</a></p>
</div>
</div>
</section>Heading block with an eyebrow and an H2
The card inside a page that already has its h1. The eyebrow names the area; the heading is an h2 at the same size.
Full-width preview: the snippet sets its own ground
<section class="hs-band hs-band--soft" data-section="account" aria-labelledby="ac-email-h">
<div class="hs-container">
<div class="hs-auth">
<div class="hs-auth__card">
<header class="hs-auth__head">
<p class="hs-eyebrow">Account</p>
<h2 class="hs-heading hs-heading--h2" id="ac-email-h">Change email</h2>
<p class="hs-auth__intro">Your email address is <strong>avery.example@example.com</strong>. It is also how you sign in.</p>
</header>
</div>
</div>
</div>
</section>Signed-in notice
A signed-in member on /user/password. The info callout names the account and offers Sign out; the form sends the link to that address.
Full-width preview: the snippet sets its own ground
<section class="hs-band" data-section="reset-password" aria-labelledby="ac-reset-h">
<div class="hs-container">
<div class="hs-auth">
<div class="hs-auth__card">
<header class="hs-auth__head">
<h1 class="hs-heading hs-heading--h2" id="ac-reset-h">Reset your password</h1>
<p class="hs-auth__intro">We will email you a link to set a new password. The link works once.</p>
</header>
<aside class="hs-callout hs-callout--info">
<svg class="hs-callout__icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="9"/><path d="M12 11v5.5"/><path d="M12 7.6v.1"/></svg>
<div class="hs-callout__body">
<p class="hs-callout__title">You are signed in as <span class="hs-auth__account">avery.example@example.com</span>.</p>
<p><a class="hs-form-link" href="/user/logout?destination=user/password" data-ph-capture-attribute-cta="sign-out" data-ph-capture-attribute-cta-loc="reset-password">Sign out</a> to reset another account.</p>
</div>
</aside>
<form class="hs-form" action="/user/password" method="post">
<button class="hs-button hs-button--block" type="submit" data-ph-capture-attribute-cta="reset-email" data-ph-capture-attribute-cta-loc="reset-password">Email me a reset link</button>
</form>
</div>
</div>
</div>
</section>