webdevpuneet.com

Settings Panel — Free HTML CSS JS Snippet

Settings Panel · Layouts · Plain HTML, CSS & JS · Live preview

CategoryLayouts

Copy & paste

Source Code

<div class="wrap">
  <div class="panel">
    <div class="sidebar">
      <div class="sidebar-title">Settings</div>
      <nav class="sidebar-nav">
        <button class="nav-item active" onclick="showTab(this,'profile')">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>
          Profile
        </button>
        <button class="nav-item" onclick="showTab(this,'notifications')">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
          Notifications
        </button>
        <button class="nav-item" onclick="showTab(this,'privacy')">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
          Privacy
        </button>
        <button class="nav-item" onclick="showTab(this,'appearance')">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="3"/><path d="M19.07 4.93a10 10 0 1 1-14.14 0"/></svg>
          Appearance
        </button>
      </nav>
      <div class="sidebar-footer">
        <button class="danger-btn">
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="9 10 4 15 9 20"/><path d="M20 4v7a4 4 0 0 1-4 4H4"/></svg>
          Sign Out
        </button>
      </div>
    </div>
    <div class="content">
      <div class="tab active" id="tab-profile">
        <div class="tab-header"><h2>Profile</h2><p>Manage your public profile and personal information.</p></div>
        <div class="avatar-row">
          <div class="avatar">JS</div>
          <div>
            <button class="btn-sec">Change Photo</button>
            <div class="hint">JPG, PNG or GIF. Max 2MB.</div>
          </div>
        </div>
        <div class="form-grid">
          <div class="field">
            <label class="field-label">First Name</label>
            <input class="field-input" type="text" value="Jordan">
          </div>
          <div class="field">
            <label class="field-label">Last Name</label>
            <input class="field-input" type="text" value="Smith">
          </div>
          <div class="field full">
            <label class="field-label">Email</label>
            <input class="field-input" type="email" value="[email protected]">
          </div>
          <div class="field full">
            <label class="field-label">Bio</label>
            <textarea class="field-input" rows="3" placeholder="Tell us about yourself...">Frontend developer. Coffee enthusiast. Building things on the web.</textarea>
          </div>
        </div>
        <div class="tab-actions">
          <button class="btn-save">Save Changes</button>
          <button class="btn-cancel">Cancel</button>
        </div>
      </div>
      <div class="tab" id="tab-notifications">
        <div class="tab-header"><h2>Notifications</h2><p>Choose what you want to be notified about.</p></div>
        <div class="toggle-list">
          <div class="toggle-row">
            <div class="toggle-info"><div class="toggle-title">Email Notifications</div><div class="toggle-desc">Receive important updates by email</div></div>
            <label class="toggle"><input type="checkbox" checked onchange="toggleSwitch(this)"><span class="track"></span></label>
          </div>
          <div class="toggle-row">
            <div class="toggle-info"><div class="toggle-title">Push Notifications</div><div class="toggle-desc">Browser push alerts for real-time activity</div></div>
            <label class="toggle"><input type="checkbox" checked onchange="toggleSwitch(this)"><span class="track"></span></label>
          </div>
          <div class="toggle-row">
            <div class="toggle-info"><div class="toggle-title">Weekly Digest</div><div class="toggle-desc">A summary of your activity every Monday</div></div>
            <label class="toggle"><input type="checkbox" onchange="toggleSwitch(this)"><span class="track"></span></label>
          </div>
          <div class="toggle-row">
            <div class="toggle-info"><div class="toggle-title">Marketing Emails</div><div class="toggle-desc">Product updates, tips, and announcements</div></div>
            <label class="toggle"><input type="checkbox" onchange="toggleSwitch(this)"><span class="track"></span></label>
          </div>
          <div class="toggle-row">
            <div class="toggle-info"><div class="toggle-title">Security Alerts</div><div class="toggle-desc">Logins from new devices or locations</div></div>
            <label class="toggle"><input type="checkbox" checked onchange="toggleSwitch(this)"><span class="track"></span></label>
          </div>
        </div>
      </div>
      <div class="tab" id="tab-privacy">
        <div class="tab-header"><h2>Privacy</h2><p>Control your data and visibility settings.</p></div>
        <div class="toggle-list">
          <div class="toggle-row">
            <div class="toggle-info"><div class="toggle-title">Public Profile</div><div class="toggle-desc">Let others find and view your profile</div></div>
            <label class="toggle"><input type="checkbox" checked onchange="toggleSwitch(this)"><span class="track"></span></label>
          </div>
          <div class="toggle-row">
            <div class="toggle-info"><div class="toggle-title">Show Activity Status</div><div class="toggle-desc">Let others see when you were last active</div></div>
            <label class="toggle"><input type="checkbox" onchange="toggleSwitch(this)"><span class="track"></span></label>
          </div>
          <div class="toggle-row">
            <div class="toggle-info"><div class="toggle-title">Analytics Tracking</div><div class="toggle-desc">Help improve the product with usage data</div></div>
            <label class="toggle"><input type="checkbox" checked onchange="toggleSwitch(this)"><span class="track"></span></label>
          </div>
        </div>
        <div class="danger-zone">
          <div class="dz-title">Danger Zone</div>
          <div class="dz-row"><div><div class="dz-label">Delete Account</div><div class="dz-desc">Permanently remove your account and all data.</div></div><button class="btn-danger">Delete</button></div>
        </div>
      </div>
      <div class="tab" id="tab-appearance">
        <div class="tab-header"><h2>Appearance</h2><p>Customise how the app looks and feels.</p></div>
        <div class="field">
          <label class="field-label">Theme</label>
          <div class="theme-btns">
            <button class="theme-btn active" onclick="setTheme(this,'system')">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
              System
            </button>
            <button class="theme-btn" onclick="setTheme(this,'light')">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg>
              Light
            </button>
            <button class="theme-btn" onclick="setTheme(this,'dark')">
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
              Dark
            </button>
          </div>
        </div>
        <div class="field">
          <label class="field-label">Accent Color</label>
          <div class="color-btns">
            <button class="color-btn active" style="background:#6366f1" onclick="setColor(this)" title="Indigo"></button>
            <button class="color-btn" style="background:#0ea5e9" onclick="setColor(this)" title="Sky"></button>
            <button class="color-btn" style="background:#10b981" onclick="setColor(this)" title="Emerald"></button>
            <button class="color-btn" style="background:#f59e0b" onclick="setColor(this)" title="Amber"></button>
            <button class="color-btn" style="background:#ef4444" onclick="setColor(this)" title="Red"></button>
            <button class="color-btn" style="background:#ec4899" onclick="setColor(this)" title="Pink"></button>
          </div>
        </div>
        <div class="field">
          <label class="field-label">Font Size</label>
          <div class="size-row">
            <span class="size-label">A</span>
            <input type="range" min="12" max="20" value="14" class="size-slider" id="fontSize" oninput="document.getElementById('fontVal').textContent=this.value+'px'">
            <span class="size-label lg">A</span>
            <span class="size-val" id="fontVal">14px</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Two-panel flex layout: fixed sidebar + flex-1 scrollable content area
showTab() tab switching: display:none/block toggle via .active class
CSS toggle switch: input:checked + .track pseudo-element sliding animation
Profile form: 2-column CSS Grid with full-width Bio and avatar row
Theme picker: 3-button group with .active border highlight
Accent color picker: circle buttons with active border + white outline ring
Font size slider: native range input with accent-color CSS tint
Danger zone: red border section with delete account CTA

About this UI Snippet

Settings Panel — Sidebar Nav, Profile Form, Notification Toggles & Appearance Controls

Screenshot of the Settings Panel snippet rendered live

A settings panel is a fundamental page in any web application — it centralises user preferences, account management, privacy controls, and appearance customisation. This snippet delivers a complete settings page layout with a left sidebar navigation, four content tabs (Profile, Notifications, Privacy, Appearance), a profile form with avatar, notification toggles, a privacy section with a danger zone, and an appearance tab with theme, accent color, and font size controls.

The two-panel layout

The .panel container uses display: flex with a fixed-width .sidebar (220px) and a flex: 1 .content area. The sidebar has position: relative with border-right separator. The content area uses overflow-y: auto so tall tab content scrolls without the sidebar scrolling. On mobile, this can be adapted to a stacked layout by setting flex-direction: column and giving the sidebar a horizontal scrollable nav row.

Tab switching without a framework

showTab(btn, id) removes .active from all .nav-item and .tab elements, then adds .active to the clicked button and the corresponding tab panel (by ID: tab-profile, tab-notifications, etc.). All tabs are in the DOM simultaneously — only the .active one has display: block via CSS. This keeps tab content persistent between switches, preserving any unsaved form input.

The CSS toggle switch

The notification and privacy toggles use the same CSS-only toggle switch pattern: a hidden checkbox input overlaid by a .track span. When the checkbox is checked, input:checked + .track changes background to indigo, and the ::after pseudo-element (the white circle) translates 20px to the right. The transition on both the background and transform creates the sliding animation.

The appearance controls

The theme selector uses three buttons with .active toggling (setTheme). The accent color picker uses circular buttons; the active one gets a border and an outline ring (outline: 2px solid white, outline-offset: 1px). The font size slider uses a native range input with accent-color: #6366f1 for cross-browser tinted track/thumb styling.

Applying appearance changes to the whole page

To make the accent color and font size controls apply globally, define CSS custom properties on :root: --accent: #6366f1 and --font-size: 14px. In the color picker's onclick handler, call document.documentElement.style.setProperty("--accent", chosenColor). In the font size slider oninput, call document.documentElement.style.setProperty("--font-size", value + "px"). All component CSS that references var(--accent) updates immediately across the page without a reload. Persist the chosen values to localStorage so they survive navigation: localStorage.setItem("accent", color) and localStorage.setItem("fontSize", value). On DOMContentLoaded, read these stored values and apply them before the page renders to avoid a flash of default styles.

Step by step

How to Use

  1. 1
    Click the sidebar nav items to switch tabsClick Profile, Notifications, Privacy, or Appearance in the sidebar to switch the content panel. The active item is highlighted in blue.
  2. 2
    Edit the profile formUpdate name, email, and bio fields. Click Save Changes to trigger a save action. The form uses a 2-column CSS Grid with a full-width row for the bio textarea.
  3. 3
    Toggle notifications and privacy settingsClick any toggle switch in the Notifications or Privacy tabs to toggle the setting on or off. Add API calls in the toggleSwitch() function to persist changes to the server.
  4. 4
    Change theme, accent color, and font sizeIn the Appearance tab, click System/Light/Dark theme buttons, choose an accent color circle, or drag the font size slider. Wire these to a CSS custom property (--accent-color) to apply changes site-wide.
  5. 5
    Wire Save Changes to an APIIn the tab-actions Save button click handler, collect form values with FormData or individual input reads, then POST to /api/user/profile. Show a success toast on resolve.
  6. 6
    Export for your frameworkClick "JSX" for a React component with useState for the active tab and toggle states. Click "Vue" for a Vue 3 SFC with ref-based tab switching.

Real-world uses

Common Use Cases

SaaS application user account settings page
The most common use case. Wire each tab to a separate API endpoint: PATCH /api/profile for profile, PUT /api/notifications for notification prefs, DELETE /api/account for the danger zone. Show a toast notification after each successful save.
Dashboard admin panel user management settings
Repurpose the sidebar for admin sections: General, Team Members, Billing, Integrations, API Keys. Each tab becomes an admin control panel. The same two-panel layout scales to 10+ sidebar items with a scrollable nav.
Mobile app settings page on a responsive web view
On small screens, collapse the sidebar into a horizontal tab bar at the top (flex-direction: column on .panel, then row direction on sidebar). The content panel scrolls vertically below the tabs.
Persist settings to localStorage or a REST API
Read all toggle states and form values in a saveSettings() function. Store in localStorage for client-only persistence: localStorage.setItem("settings", JSON.stringify(settings)). For multi-device sync, POST to an API endpoint on every change.
Study the CSS toggle switch implementation
The notification toggle uses no JavaScript for its visual state — just input:checked + .track CSS selector and a ::after pseudo-element transform. This is the standard accessible toggle pattern: the hidden checkbox carries the semantic state, the visible track is purely presentational.
Developer tool or IDE settings/preferences panel
Adapt for a code editor settings page: Appearance tab for theme/font/indentation, Keybindings tab, Extensions tab. The sidebar nav cleanly organises 8–12 settings sections without visual clutter.

Got questions?

Frequently Asked Questions

showTab(btn, id) removes .active from all .nav-item and .tab elements (querySelectorAll + forEach), then adds .active to the clicked nav button and the tab div with id="tab-" + id. In CSS, .tab { display: none } and .tab.active { display: block }. All tab content stays in the DOM, so unsaved form values are preserved when switching between tabs.

The toggle is a label containing a hidden checkbox and a .track span. The checkbox handles the checked state natively. The CSS rule input:checked + .track changes background to indigo. The .track::after pseudo-element is the white circle, positioned left: 3px by default. input:checked + .track::after uses transform: translateX(20px) to slide it right. The transition on both properties creates the animation.

Define CSS custom properties on :root: --accent: #6366f1; --font-size: 14px. In setColor(), read the button's background color and set document.documentElement.style.setProperty("--accent", color). In the font size slider oninput, set document.documentElement.style.setProperty("--font-size", value + "px"). Reference these in all component CSS.

In React, manage the active tab with const [tab, setTab] = useState("profile"). Render each tab section conditionally: {tab === "profile" && <ProfileTab />}. For toggle switches, use const [prefs, setPrefs] = useState({ analytics: true, marketing: false }) and pass values/setters as props. In Vue 3, use ref("profile") for the active tab and a reactive() object for toggle states. The sidebar nav items call setTab / tab.value on click. For URL-based tab persistence (so the back button works and links to specific tabs are shareable), sync the active tab with the URL hash: on mount, read window.location.hash to set the initial tab; in setTab(), update window.location.hash = tab so the URL reflects the current section. Listen to the hashchange event to handle browser back/forward navigation between tabs without a full route change.