18 CSS Settings Pages

18 Light JSPublished

18 CSS settings pages for SaaS account dashboards, billing admin, and developer API consoles — spanning section-nav layouts, usage meters, invoice tables, roles matrices, two-factor screens, notification preferences, and a delete-account danger zone. Scoped under .csp-NN for no-collision pasting, prefers-reduced-motion guarded, framework-agnostic.

Related17 CSS Dashboard Layouts30 CSS Sidebar Layouts18 CSS Forms13 CSS Tables18 Tailwind CSS Settings Pages

Premium template pickPartner: Cruip

Affiliate link

Building the whole admin app, not just this settings page?

You just browsed 18 settings pages. Mosaic by Cruip is a complete Tailwind CSS admin template in HTML, React, Next.js, Vue and Laravel. Its settings area has account, notifications, connected apps, plans and billing & invoices pages, among 90 pages in all. It costs $69.

View Mosaic dashboard

Mosaic by Cruip. We may earn a commission, at no extra cost to you.

01. Account Settings Page with Section Nav (opens in a new tab)

Published

Light JS
A complete SaaS account settings page with a sticky sidebar section nav that highlights the section you're reading (scroll-spy), grouped Profile, Email & login, Preferences and Privacy cards, native :user-invalid validation, iOS-style switches built from real checkboxes, and a floating 'unsaved changes' bar that slides up the moment the form is edited. On narrow containers the sidebar collapses into a horizontal, swipeable tab strip via a container query.

02. Billing and Plan Settings Page (opens in a new tab)

Published

Light JS
A premium SaaS billing page in pure CSS: a current-plan summary with seat math and a billing-period progress bar, a Monthly / Annual segmented toggle with a sliding thumb that swaps every price on the page, selectable plan cards with a 'Current' badge, and a confirmation strip that appears only when you pick a different plan. Every interaction is driven by native radio inputs and the :has() selector — zero JavaScript.

03. Usage and Limits Page with Quota Meters (opens in a new tab)

Published

Light JS
A usage dashboard that makes plan limits instantly legible: a hero conic-gradient ring for API requests, linear quota bars for seats, storage, bandwidth, build minutes and AI credits, and automatic healthy / warning / over-limit colour states. Meters animate from zero on load with @property, numbers count up with tabular figures, and an upgrade banner appears via :has() the moment any quota goes critical.

04. Invoice History Table with Downloads (opens in a new tab)

Published

Light JS
A polished billing-history table with status filter chips (pure CSS via :has), row selection with a live 'N selected' count from CSS counters, a select-all checkbox with a true indeterminate state, and per-row PDF download buttons that animate through idle → preparing → downloaded. Under 640px the table reflows into stacked invoice cards with a container query — no duplicate markup.

05. Payment Method Settings Card (opens in a new tab)

Published

Light JS
A premium payment-methods panel: a glossy 3D card preview that mirrors the add-card form as you type and flips to show the CVC when that field is focused, auto-formatted card number and expiry with brand detection (Visa, Mastercard, Amex), saved methods as radio rows where :has() highlights the default, and an 'expires soon' warning. Uses the right autocomplete tokens so browsers and password managers can autofill.

06. Team Members Page with Roles (opens in a new tab)

Published

Light JS
A team management page that scales from 5 to 500 people: seat usage at a glance, instant search across names and emails, a role filter, colour-coded role selects per member (Owner is locked), pending-invite rows with resend, and a remove action that collapses the row smoothly with an undo toast. The list reflows to a compact stacked layout via container queries.
Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

07. Invite Teammates Form with Role Picker (opens in a new tab)

Published

Light JS
A fast, forgiving invite flow: paste a whole list of emails or type them one by one and they become validated chips (invalid ones turn red and are skipped), pick a role from descriptive radio cards that explain exactly what each role can do, add an optional personal note, and send. The primary button counts invites live, a seat warning appears when you'd exceed your plan, and a shareable invite link has one-click copy.

08. Roles and Permissions Matrix (opens in a new tab)

Published

Light JS
A clear RBAC permissions matrix: permissions grouped by area down the side, roles across the top, custom checkbox cells, a locked Owner column, crosshair row + column highlighting on hover powered entirely by :has(), per-role 'x of y' counters, a sticky first column for horizontal scrolling on small screens, and an unsaved-changes footer that tracks exactly how many permissions you've changed.

09. API Keys Management Page (opens in a new tab)

Published

Light JS
A developer-grade API keys page: masked secret keys with copy-to-clipboard, scope and environment badges, created / last-used metadata, a safe two-step revoke, and a native <dialog> to create new keys with name, permission level and expiry. The new secret is shown exactly once in a highlighted reveal panel with copy and a clear 'you won't see this again' warning — the pattern used by every serious API platform.

10. Two-Factor Authentication Setup (opens in a new tab)

Published

Light JS
A guided, three-step 2FA enrolment wizard: choose authenticator app or SMS, scan a QR code (with a copyable manual setup key fallback), enter a 6-digit code in a premium OTP input that auto-advances, supports paste and backspace, and shakes on error — then save recovery codes with copy and download before finishing. A progress stepper with aria-current keeps users oriented.

11. Active Sessions and Devices Page (opens in a new tab)

Published

Light JS
A security-first sessions page that answers 'where am I signed in?' at a glance: the current device pinned at the top with a live pulse, every other session listed with device type, browser, OS, approximate location and last activity, an 'unrecognised sign-in' flag with a direct path to secure the account, per-device sign-out with a smooth collapse, and a 'Sign out all other sessions' action with a confirm step and empty state.

12. Notification Preferences Matrix (opens in a new tab)

Published

Light JS
A notification settings matrix that respects people's attention: event types grouped by category down the side, Email / Push / In-app channels across the top, compact switch cells, column 'select all' toggles with true indeterminate states, locked security alerts that can't be turned off, a pause-all switch that dims the matrix via :has(), quiet hours, and a digest-frequency segmented control.

13. Connected Apps and Integrations Page (opens in a new tab)

Published

Light JS
An integrations marketplace-style settings page: category tabs that filter cards in pure CSS with :has(), instant search, monogram app tiles, clear connected / not-connected status, a connect button that runs through an OAuth-style 'Connecting…' state before flipping to Connected, a Manage / Disconnect pair for connected apps, and a live connected-count badge. The card grid fluidly reflows with auto-fill and minmax.

14. Appearance and Theme Settings (opens in a new tab)

Published

Light JS
A live appearance panel with zero JavaScript: pick Light, Dark or System theme from mini window previews and the entire page re-themes instantly with the CSS light-dark() function; choose an accent colour, interface density, text size and corner style, or switch on high contrast — every change applies to a live preview app beside the controls. All state is native radios and checkboxes read by :has().
Newsletter

Enjoying these demos? Get new ones by email.

A short email when a new collection ships. Unsubscribe any time.

at

Almost there: check your inbox to confirm.Manage

15. Data Export Request Page (opens in a new tab)

Published

Light JS
A transparent, GDPR- and CCPA-friendly data export page: choose exactly which data to include from checkbox cards with size estimates, pick JSON or CSV and a date range, see a live summary of the estimated archive size, then request the export and watch a job card progress from Queued to Preparing to Ready with a download link and expiry. Previous exports are listed with their status.

16. Audit Log Activity Page (opens in a new tab)

Published

Light JS
An enterprise-grade audit log with zero JavaScript: category filter chips (Auth, Members, Billing, API) powered by :has(), events grouped by day, each row showing actor, action, target, IP and time, severity markers for risky events, and expandable rows built on native <details> that reveal full metadata and a before/after diff. A CSS counter prints the number of matching events live as you filter.

17. Webhooks Settings Page (opens in a new tab)

Published

Light JS
A complete webhook endpoint manager: an endpoint list with health indicators and success-rate bars, a detail view with the endpoint URL, an enable switch, subscribed-event chips, a masked signing secret with reveal / copy / roll, and a recent deliveries log with colour-coded HTTP status, latency and one-click retry. 'Send test event' fires a simulated delivery that slides into the log in real time.

18. Danger Zone Delete Account Section (opens in a new tab)

Published

Light JS
A responsible danger zone: clearly separated destructive actions (transfer ownership, archive workspace, delete account) in a red-accented section, and a delete flow in a native <dialog> that spells out exactly what will be lost, offers a data export first, requires typing the workspace name to enable the button, then confirms with a 30-day grace period and an Undo. Built to prevent accidents without feeling hostile.
FAQ

Frequently asked questions

How does the sticky sidebar section nav highlight the section you're currently reading?
The sidebar itself is pure CSS — the nav column is position: sticky with a top offset so it stays in view while the settings content scrolls past it. The active highlight is the part that needs care. Clicking a nav link jumps to a section via its id, and you can style the landing target with :target for a pure-CSS highlight. But :target only updates on click, not as you scroll. For a true scroll-spy that re-highlights while the reader scrolls, add a small IntersectionObserver that toggles an aria-current attribute on the matching link — roughly fifteen lines, no library. Keep the sticky column shorter than the viewport, or position: sticky silently stops sticking because there is no room left to offset into, which is the single most common reason a sticky nav 'doesn't work'.
How do the filter chips on the invoice table and audit log filter rows with no JavaScript?
Each chip is a radio input in one named group, and the visible chip is its <label>. The container reads the checked radio with :has() and hides non-matching rows — something like .table:has(#filter-failed:checked) .row:not(.failed) { display: none; }. Because the radios share a name, only one is active at a time, so the filters are mutually exclusive for free. The common bug: people place the radios after the rows and expect a sibling selector to reach backward — it can't. With :has() the radios can live anywhere inside the scoped container, since :has() evaluates from the ancestor downward. But keep the hidden radios as real, focusable inputs — visually hidden, never display: none — so keyboard users can still tab between chips and screen readers announce the active filter.
Can the Light / Dark / System theme switch really work with zero JavaScript, and what breaks?
Yes — demo 14 drives it with three radio inputs (Light, Dark, System) and :has(). The panel declares light custom properties by default and overrides them with .panel:has(#dark:checked). The trap is the System option: it has to follow the OS, so you wrap the OS-driven values in @media (prefers-color-scheme: dark) scoped to :has(#system:checked). The bug that bites everyone is the one-way toggle — on a visitor whose OS is already dark, the manual Dark rule and the System rule resolve to identical values, so clicking Dark produces no visible change. The fix is a mirror flip-back: inside @media (prefers-color-scheme: dark) you must also restore the light values for :has(#light:checked), and restore every custom property the theme sets, not just the background colour, or half the palette stays stale.
How do I make the roles-and-permissions matrix accessible to keyboard and screen-reader users?
The matrices in demos 08 and 12 are grids of checkboxes where area or event rows meet role or category columns. Build the grid as a real <table> with <th> headers on both the top row and the leading cell of each body row, and give column headers scope="col" and row headers scope="row". Then a checkbox cell is announced as 'Billing, Admin, checked' instead of a bare, contextless checkbox. Every <input> still needs a programmatic name — pair it with a visually hidden <label> or an aria-label that repeats the row and column, because sighted users infer context from position but a screen reader lands on the control with none. Don't rebuild the grid from <div> elements with role attributes; a native table gives you header association and arrow-key cell reading for free, and it survives being pasted into a project that strips your JS.
Does the copy-to-clipboard button on the API keys page need JavaScript?
Yes. Masking the secret is pure CSS — the key renders as dots via -webkit-text-security: disc, revealed by a :has(:checked) toggle — but reading a value and writing it to the clipboard is a privileged action no CSS selector can perform. Demo 09 uses navigator.clipboard.writeText() inside a click handler, which the browser only honours during a genuine user gesture, so wire it to the button's click event, never a timer or page-load hook. Give the button an aria-label like 'Copy API key' because it is icon-only, and after a successful copy flip that label or an aria-live region to 'Copied' so screen-reader users get the same confirmation the visual checkmark gives everyone else. Never pre-select or auto-copy the key on load — it fails silently outside a user gesture and leaks the secret into focus unexpectedly.
How should the Danger Zone delete-account section confirm a destructive action safely?
Demo 18 separates destructive actions visually, but visual separation is not a safeguard. For irreversible actions — delete account, archive workspace — gate the button behind a typed confirmation: keep it disabled until the user types the exact workspace name into an <input>, which you can enforce roughly with :has() against a pattern or, more reliably, in a few lines of JS. Keep the confirm control a real <button> with type="button" so it never submits a surrounding form by accident. Give the destructive styling meaning beyond colour — an icon plus the literal word 'Delete' — so it still reads for colour-blind users. When not to use an inline danger zone at all: if the action cascades to other members' data, move it into a modal that restates the blast radius, because an inline button is far too easy to hit while scrolling the page.
How is the circular quota ring on the usage page drawn, and can I animate it to a percentage?
The ring in demo 03 is a single element with a conic-gradient background — the accent colour sweeps from zero to the used percentage, a track colour fills the remainder, and a smaller circle (a pseudo-element or a radial-gradient mask) punches the centre so it reads as a ring, not a pie. Drive the sweep from one custom property: background: conic-gradient(var(--accent) calc(var(--pct) * 1%), var(--track) 0). To animate it smoothly you must register that property with @property and declare syntax: "<percentage>", because the browser cannot interpolate an unregistered custom property — without it the ring jumps straight to the final value instead of sweeping. Wrap the transition in @media (prefers-reduced-motion: reduce) so users who ask for less motion get the final state with no animation.
Which of these settings pages are pure CSS, and when should I reach for JavaScript instead?
The filtering, tab-switching, theme, and card-flip demos are genuinely pure CSS, built on :has(), :checked, and :target — paste them as-is with no script. The ones that touch the outside world need JS: copy-to-clipboard on the API keys page, the live card preview that mirrors typed input in demo 05, paste-and-validate email parsing in the invite flow, and any real scroll-spy on the account nav. A useful rule: if the state lives entirely in the DOM — which chip is active, which row is selected — CSS can hold it; if you must read a value, write to the clipboard, call an API, or react to scroll position, that is JavaScript. And don't push a :has() state machine to do something stateful across reloads — it resets on refresh, so persisting a chosen theme or a saved preference still needs a line of script plus localStorage.

Related collections

15 CSS Aspect Ratio Demos preview

15 CSS Aspect Ratio Demos

15 hand-coded CSS aspect-ratio demos for video embeds, product galleries, IAB ad slots, native dialogs, and CLS-safe placeholders: 16:9 iframe YouTube embed with click-to-load facade + up-next rail, 21:9 full-screen hero video with min-height/max-height:100svh guardrails + Ken Burns drift, 1:1 Instagram-style square grid with 2×2 feature tile, 4:3 magazine card image cover, 9:16 vertical stories rail (TikTok/Reels/Shorts pattern) with scroll-snap + segment bars, 4:5 apparel product image gallery with radio-driven state + 1:1 thumbnails, 1:1 zoom thumbnail carousel with pointer-tracked --zx/--zy magnifier, prevent-layout-shift placeholder with live PerformanceObserver CLS meter (before/after side-by-side lab), dynamic content fallback with three policies (bend/strict/auto) via :has() toggle, IAB ad banner slots (728×90 leaderboard, 300×250 medium rectangle, 300×600 half-page, 320×50 mobile) with skeletons + container-query mobile swap, responsive modal dialog sized min(92vw, 88svh×16/9, 1080px) with @starting-style animation, responsive OpenStreetMap iframe wrapper with 16:9 → 1:1 container-query narrow swap, media query orientation live HUD + resize:both container-ratio playground, object-fit logo cloud with contain/cover/fill switcher via :has(), and side-by-side padding-top hack (height:0 + padding-top:56.25%) → modern aspect-ratio migration comparison with live ratio picker. 11 truly Pure CSS + 4 with a tiny optional vanilla JS snippet (facade swap, pointer magnifier, CLS meter, native dialog). Every demo is scoped under a unique .car-NN prefix so it drops into any project without CSS collisions, ships prefers-reduced-motion guards, and is framework-agnostic (works as-is in React, Vue, Svelte, Astro, Next.js, Remix, or plain HTML).

6 CSS Bento Grid Layouts preview

6 CSS Bento Grid Layouts

6 production CSS bento grid layouts with 12 hand-coded designs — Apple-style product showcase, SaaS feature value-prop matrix, analytics dashboard overview, creative portfolio, e-commerce category hub, and link-in-bio social hub. Each topic ships 2 sub-variants side-by-side so visitors see both a keynote aesthetic and a paper-doc variant at once. Container queries, CSS Grid, zero dependencies, copy-paste ready.

20 CSS Blog Layouts preview

20 CSS Blog Layouts

20 hand-coded CSS blog and editorial layouts for magazine homepages, news sites, personal archives, newsletter back-issues, recipe and podcast blogs, developer tutorials, and long-form journalism. Covers a magazine homepage with hero plus editor-picks rail, a news homepage with breaking-news ticker, blog archives with sticky year separators, Substack-style issue-numbered archives, recipe card grids with prep-time badges, podcast episode lists with waveforms, long-form articles with scroll-driven reading progress, drop caps and floated pull quotes via first-letter, Medium-style 65ch centred reader layouts, dev tutorials with a sticky code panel beside prose, interview transcripts with alternating speakers, case-study pages with stat counters, video blogs with an episode rail, full-bleed photo essays, news articles with sticky related-stories sidebars, documentation pages with prev/next chapter nav, a standalone blog post card, a scroll-snap category filter bar, an inline newsletter callout that breaks out of the prose column, and a horizontal featured-post rail. 12 are pure CSS with zero JavaScript. Every layout is scoped under a .bl-NN prefix for no-collision pasting, guards prefers-reduced-motion, and ports unchanged to React, Vue, Svelte, Astro, Next.js and Tailwind.

Search CodeFronts

Loading…