Component Library

← Back to gallery

Settings layout

Category: Layout · Tags: settings, preferences, form, two-column, responsive

Profile

Used for reminder emails and due dates.

Email me about

How to use it

Use for account or app preference pages with several sections, each edited as its own short form. Below 640px the section list stacks above the form. Replace the hrefs, labels and ids; the demo's Save is type="button" so the gallery does not reload, so change it to type="submit" and give the form an action or a submit handler in your app.

Accessibility

A <nav aria-label="Settings sections"> lists the sections with aria-current="page" on the active one (also shown by a left bar and bold weight), followed by a form named by its heading through aria-labelledby. Every input and the select has a <label for>, the notification choices sit in a <fieldset> with a <legend>, and all controls show a 2px focus outline. Text is #0f172a on #ffffff (17.85:1), section links #334155 on #f8fafc (9.90:1), the current link #1e3a8a on #eff6ff (9.52:1), hint text #475569 on #ffffff (7.58:1) and the button #ffffff on #1d4ed8 (6.70:1).

Source (copy-ready)

<div class="dcl-settings-layout">
  <nav class="dcl-settings-layout__nav" aria-label="Settings sections">
    <ul class="dcl-settings-layout__navlist">
      <li><a class="dcl-settings-layout__navlink" href="../index.html" aria-current="page">Profile</a></li>
      <li><a class="dcl-settings-layout__navlink" href="../index.html">Notifications</a></li>
      <li><a class="dcl-settings-layout__navlink" href="../about.html">Security</a></li>
    </ul>
  </nav>
  <form class="dcl-settings-layout__panel" aria-labelledby="dcl-settings-layout-title">
    <h2 class="dcl-settings-layout__title" id="dcl-settings-layout-title">Profile</h2>
    <div class="dcl-settings-layout__field">
      <label class="dcl-settings-layout__label" for="dcl-settings-layout-name">Display name</label>
      <input class="dcl-settings-layout__input" id="dcl-settings-layout-name" name="display-name" type="text" autocomplete="nickname" value="Sam Okafor">
    </div>
    <div class="dcl-settings-layout__field">
      <label class="dcl-settings-layout__label" for="dcl-settings-layout-tz">Time zone</label>
      <select class="dcl-settings-layout__input" id="dcl-settings-layout-tz" name="time-zone">
        <option>UTC</option>
        <option selected>Europe/Lisbon</option>
        <option>Asia/Tokyo</option>
      </select>
      <p class="dcl-settings-layout__hint">Used for reminder emails and due dates.</p>
    </div>
    <fieldset class="dcl-settings-layout__fieldset">
      <legend class="dcl-settings-layout__legend">Email me about</legend>
      <label class="dcl-settings-layout__check"><input type="checkbox" name="email-comments" checked> Replies to my comments</label>
      <label class="dcl-settings-layout__check"><input type="checkbox" name="email-digest"> Weekly digest</label>
    </fieldset>
    <button type="button" class="dcl-settings-layout__save">Save changes</button>
  </form>
</div>
<style>
.dcl-settings-layout { display: grid; grid-template-columns: 12rem minmax(0, 1fr); gap: 1.5rem; max-width: 48rem; font: inherit; color: #0f172a; background-color: #ffffff; }
.dcl-settings-layout__nav { min-width: 0; padding: 0.5rem 0; border-radius: 0.5rem; color: #0f172a; background-color: #f8fafc; }
.dcl-settings-layout__navlist { margin: 0; padding: 0; list-style: none; }
.dcl-settings-layout__navlink { display: block; padding: 0.5rem 0.75rem; border-left: 4px solid #f8fafc; text-decoration: none; color: #334155; background-color: #f8fafc; }
.dcl-settings-layout__navlink:hover { text-decoration: underline; color: #0f172a; background-color: #f1f5f9; }
.dcl-settings-layout__navlink:focus-visible { outline: 2px solid #1d4ed8; outline-offset: -2px; }
.dcl-settings-layout__navlink[aria-current="page"] { font-weight: 700; border-left-color: #1d4ed8; color: #1e3a8a; background-color: #eff6ff; }
.dcl-settings-layout__panel { min-width: 0; display: flex; flex-direction: column; gap: 1rem; }
.dcl-settings-layout__title { margin: 0; font-size: 1.25rem; color: #0f172a; background-color: #ffffff; }
.dcl-settings-layout__field { display: flex; flex-direction: column; gap: 0.375rem; }
.dcl-settings-layout__label { font-weight: 600; color: #0f172a; background-color: #ffffff; }
.dcl-settings-layout__input { box-sizing: border-box; width: 100%; max-width: 20rem; min-height: 2.5rem; padding: 0.375rem 0.625rem; border: 1px solid #64748b; border-radius: 0.375rem; font: inherit; color: #0f172a; background-color: #ffffff; }
.dcl-settings-layout__input:focus-visible { outline: 2px solid #1d4ed8; outline-offset: 2px; }
.dcl-settings-layout__hint { margin: 0; font-size: 0.875rem; color: #475569; background-color: #ffffff; }
.dcl-settings-layout__fieldset { margin: 0; padding: 0.75rem 1rem; border: 1px solid #cbd5e1; border-radius: 0.375rem; }
.dcl-settings-layout__legend { padding: 0 0.25rem; font-weight: 600; color: #0f172a; background-color: #ffffff; }
.dcl-settings-layout__check { display: flex; align-items: center; gap: 0.5rem; margin: 0.25rem 0; color: #0f172a; background-color: #ffffff; }
.dcl-settings-layout__save { align-self: flex-start; min-height: 2.75rem; padding: 0.5rem 1.25rem; border: none; border-radius: 0.375rem; font: inherit; font-weight: 600; cursor: pointer; color: #ffffff; background-color: #1d4ed8; }
.dcl-settings-layout__save:hover { color: #ffffff; background-color: #1e40af; }
.dcl-settings-layout__save:focus-visible { outline: 2px solid #1d4ed8; outline-offset: 2px; }
@media (max-width: 640px) {
  .dcl-settings-layout { grid-template-columns: minmax(0, 1fr); }
}
</style>

Was this useful? Send feedback.