Home / Snippets / Layout /

List reset

A utility class that strips default bullets and indentation from <ul> and <ol> elements — preserves semantic HTML while letting you add custom styling.

Default

  • Dashboard
  • Settings
  • Profile
  • Logout

Reset + custom

  • Dashboard
  • Settings
  • Profile
  • Logout
Widely Supported
layoutresetno-js

Quick implementation

/* List reset utility — apply to any ul or ol */
.list-reset {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* Navigation list — horizontal flex */
.list-reset.list--inline {
  display: flex;
  gap: 1rem;
  flex-wrap: wrap;
}

/* Custom bullet using ::before */
.list-custom li {
  list-style: none;
  padding-left: 1.25rem;
  position: relative;
}

.list-custom li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.6em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.5;
}

/* NOTE: list-style: none removes role="list" in VoiceOver/Safari.
   Add role="list" to the HTML element to restore list semantics. */

Prompt this to your LLM

Includes role, constraints, framework variants, and edge cases.

You are a senior frontend engineer writing a CSS list reset utility.

Goal: Create a utility class that strips browser default list styling
(bullets, padding, margin) from ul and ol elements, with variants
for common patterns.

Include:
- .list-reset: bare reset (list-style none, margin 0, padding 0)
- .list-reset.list--inline: horizontal navigation list using flexbox
- .list-custom: custom bullet using ::before pseudo-element
- A note about the VoiceOver/Safari bug where list-style: none
  removes list semantics — solution is role="list" on the HTML element

Accessibility constraint: Never apply list-style: none globally
(e.g. on ul, ol directly) — only on opt-in classes, so article
and prose content retains its visible list markers.

Show a practical nav menu example using .list-reset.list--inline
with hover underline on links.

Return only the CSS and HTML with inline comments.

The VoiceOver accessibility caveat

Safari's VoiceOver screen reader treats list-style: none as a signal that the element is no longer a list and stops announcing it as one. This is a deliberate browser decision to avoid navigation menus (which are marked up as lists but are not read as "list of 5 items") being announced as lists. The fix is to add role="list" to the <ul> or <ol> element — this overrides Safari's heuristic and preserves list semantics. For navigation landmarks, use <nav> instead of relying on the list role.

Why not reset lists globally

Applying list-style: none to all ul and ol elements in a reset causes problems in rich text content — blog posts, documentation, and marketing copy expect bullets and numbers. A targeted utility class (.list-reset) or scope-based reset (inside .nav, .card, etc.) lets prose content keep its default appearance while UI components remain unstyled.