A settings screen is several unrelated forms on one page. Each one saves on its own: every actions row here submits just the form it belongs to, and the forms do not share state.
Profile
Ordinary fields with their values prefilled. Nothing is marked required; the server already had this once, and an empty bio is not an error.
Profile
<div class="card center" style="--center-max: 40rem">
<div class="flow">
<h2>Profile</h2>
<form class="stack">
<div class="stack is-tight">
<label for="profile-avatar">Avatar</label>
<input id="profile-avatar" type="file" class="input" accept="image/*" />
</div>
<div class="stack is-tight">
<label for="profile-name">Display name</label>
<input
id="profile-name"
type="text"
class="input"
value="Patrick Ward"
autocomplete="name"
/>
</div>
<div class="stack is-tight">
<label for="profile-email">Email</label>
<input
id="profile-email"
type="email"
class="input"
value="patrick@example.com"
autocomplete="email"
/>
</div>
<div>
<div class="stack is-tight">
<label for="profile-bio">Bio</label>
<textarea
id="profile-bio"
class="input"
rows="3"
aria-describedby="profile-bio-help"
>
Developer working across the stack.</textarea
>
<p id="profile-bio-help" class="text-muted text--1">
A short description shown on your public profile.
</p>
</div>
</div>
<div class="cluster is-end">
<button class="button is-ghost" type="button">Cancel</button>
<button class="button" type="submit">Save changes</button>
</div>
</form>
</div>
</div>
Notifications
Switches grouped in fieldsets, one channel per group. The label wraps its switch and the
cluster.is-between pushes the control to the trailing edge, so the whole
row is the click target.
Notifications
<div class="card center" style="--center-max: 40rem">
<div class="flow">
<h2>Notifications</h2>
<form class="stack">
<fieldset class="stack">
<legend class="text-semibold">Email</legend>
<hr class="divider is-tight" />
<label class="cluster is-between">
<span>Product updates</span>
<input type="checkbox" role="switch" checked class="input" />
</label>
<label class="cluster is-between">
<span>Weekly digest</span>
<input type="checkbox" role="switch" class="input" />
</label>
<label class="cluster is-between">
<span>Security alerts</span>
<input type="checkbox" role="switch" checked class="input" />
</label>
</fieldset>
<fieldset class="stack is-snug">
<legend class="text-semibold">Push</legend>
<hr class="divider is-tight" />
<label class="cluster is-between">
<span>Direct mentions</span>
<input type="checkbox" role="switch" checked class="input" />
</label>
<label class="cluster is-between">
<span>Team activity</span>
<input type="checkbox" role="switch" class="input" />
</label>
</fieldset>
<div class="cluster is-end">
<button class="button is-ghost" type="button">Reset</button>
<button class="button" type="submit">Save preferences</button>
</div>
</form>
</div>
</div>
Change password
Current password first, then the new one with its rule as help text, then the confirmation. The autocomplete values are what let a password manager offer to fill the new one.
Change password
<div class="card center" style="--center-max: 40rem">
<div class="flow">
<h2>Change password</h2>
<form class="stack">
<div class="stack is-tight">
<label for="pwd-current">Current password</label>
<input
id="pwd-current"
type="password"
class="input"
required
autocomplete="current-password"
/>
</div>
<div>
<div class="stack is-tight">
<label for="pwd-new">New password</label>
<input
id="pwd-new"
type="password"
class="input"
required
minlength="8"
autocomplete="new-password"
aria-describedby="pwd-new-help"
/>
<p id="pwd-new-help" class="text-muted text--1">
At least 8 characters.
</p>
</div>
</div>
<div class="stack is-tight">
<label for="pwd-confirm">Confirm new password</label>
<input
id="pwd-confirm"
type="password"
class="input"
required
autocomplete="new-password"
/>
</div>
<div class="cluster is-end">
<button class="button is-ghost" type="button">Cancel</button>
<button class="button" type="submit">Update password</button>
</div>
</form>
</div>
</div>
Danger zone
Destructive actions, each described by the thing it will do, with the button apart from
anything else. The card's border tint is the one override:
--card-border-color inline, no new CSS.
Danger zone
Move this project to another account or organization.
Remove the project and all its data. This cannot be undone.
<div
class="card center"
style="--center-max: 40rem; --card-border-color: var(--color-danger-border)"
>
<div class="flow">
<h2 class="text-danger">Danger zone</h2>
<div class="stack">
<div class="cluster is-between">
<div>
<div class="flow flow-space-3xs">
<strong>Transfer ownership</strong>
<p class="text-muted text--1">
Move this project to another account or organization.
</p>
</div>
</div>
<button class="button is-outlined" type="button">Transfer</button>
</div>
<div class="cluster is-between">
<div>
<div class="flow flow-space-3xs">
<strong>Delete project</strong>
<p class="text-muted text--1">
Remove the project and all its data. This cannot be undone.
</p>
</div>
</div>
<button class="button is-danger" type="button">Delete</button>
</div>
</div>
</div>
</div>