The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
Choose an unordered marker.features { list-style-type: square; }View examples
Choose an ordered style.chapters { list-style-type: upper-roman; }View examples
Keep markers outside.checklist { list-style-position: outside; }View examples
Style marker text.checklist > li::marker { color: #0f766e; font-weight: 700; }View examples
Provide an image fallback.links { list-style: circle outside url("arrow.svg"); }View examples
Disable marker images.plain { list-style-image: none; }View examples
Use a short string marker.steps { list-style-type: "→ "; }View examples
Define a cyclic style@counter-style status-dot { system: cyclic; symbols: "●"; suffix: " "; fallback: disc; }View examples
Define fixed symbols@counter-style circled-step { system: fixed; symbols: "①" "②" "③"; suffix: " "; fallback: decimal; }View examples
Apply a named style.milestones { list-style-type: circled-step; }View examples
Create an anonymous style.tags { list-style-type: symbols(cyclic "◆" "◇"); }View examples
Set a list-item value.resume-at-five { counter-set: list-item 4; }View examples
Differentiate nested lists.outline ul ul { list-style-type: circle; }View examples
Feature-query ::marker@supports selector(li::marker) { li::marker { color: #0f766e; }; }View examples
Keep real list markup<ol><li>Download</li><li>Verify</li><li>Install</li></ol>View examples

List styling works best when CSS changes the presentation of genuine ol, ul, and li elements instead of rebuilding list semantics. Native list-item counters adapt automatically when items are inserted, removed, nested, reversed, or assigned explicit HTML values. Use ::marker for focused typographic changes, @counter-style for reusable numbering systems, and an ordinary list-style-type as the fallback whenever an image, symbol, or newer feature is unavailable.

Step by step

Detailed examples

01

Start with native markers and style ::marker selectively

list-style-type selects a built-in counter style or bullet, and list-style-position decides whether the marker participates in the first inline line or sits outside the principal list-item box. Outside is normally easier to scan when text wraps. The ::marker pseudo-element exposes the actual marker box, but its supported property set is intentionally narrower than a normal element. Prefer inheritable text properties such as color, font family, font size, and font weight; verify any more ambitious treatment in target browsers.

Readable native bullets and ordinals
.features {
  list-style-type: square;
  list-style-position: outside;
  padding-inline-start: 1.5rem;
}

.chapters { list-style-type: upper-roman; }

.features > li::marker {
  color: #0f766e;
  font-weight: 700;
}

.features > li + li { margin-block-start: 0.5rem; }

Note: Logical padding keeps outside markers visible in both left-to-right and right-to-left writing directions.

Back to quick reference ↑
02

Layer image and string markers over portable fallbacks

When list-style-image resolves to a usable image, it takes precedence over list-style-type; if the image cannot be used, the type remains the fallback. The list-style shorthand can declare image, type, and position together, but remember that every shorthand resets omitted longhands. Literal string marker values and generated images are less universally established than basic keywords, so put a widely supported declaration first. Keep network marker assets small: one cached SVG is cheaper and more stable than many unique images, but a native bullet avoids the request entirely.

Progressively enhance a reliable circle marker
.resource-links {
  list-style-type: circle;
  list-style-position: outside;
  list-style-image: url("/icons/arrow-marker.svg");
}

.release-steps {
  list-style-type: decimal;
  list-style-type: "→  ";
}

.resource-links.no-images { list-style-image: none; }

Note: Do not put unique state or instructions only in a marker image; its download and accessibility exposure are not guaranteed.

Back to quick reference ↑
03

Define bounded, reusable counter styles with explicit fallback

@counter-style separates a numbering algorithm from the lists that consume it. The system descriptor determines how symbols are combined; suffix supplies punctuation after each representation, and fallback names the style used when the requested value cannot be represented. A fixed system naturally has a finite range, so decimal is a safe fallback beyond its symbols. The symbols() function is compact for local cyclic or symbolic markers, but a named rule is clearer when multiple components share the design. Unsupported at-rules are ignored, which makes a prior built-in list-style-type declaration essential.

Named fixed and cyclic marker systems
@counter-style circled-step {
  system: fixed;
  symbols: "①" "②" "③";
  suffix: "  ";
  fallback: decimal;
}

@counter-style status-dot {
  system: cyclic;
  symbols: "●";
  suffix: "  ";
  fallback: disc;
}

.milestones {
  list-style-type: decimal;
  list-style-type: circled-step;
}

.tags {
  list-style-type: disc;
  list-style-type: symbols(cyclic "◆" "◇");
}

Note: Keep symbol sets short and bounded. Pathological custom representations can consume unnecessary rendering memory for large counter values.

Back to quick reference ↑
04

Preserve numbering continuity and nested hierarchy

Every list item participates in the implicit list-item counter, so native ordered lists already handle inserted items, reversed lists, and HTML start or value attributes. Use those HTML attributes when an ordinal is part of the content, because the number then survives missing styles and non-CSS formats. counter-set can make a presentational sequence resume at a chosen point, but it sets the value before the list item's normal increment. Descendant selectors can give each nesting level a distinct marker without changing the list tree.

Semantic starts plus a CSS-only continuation
<ol class="procedure" start="5">
  <li>Deploy the canary
    <ul>
      <li>Check error rate</li>
      <li>Check latency</li>
    </ul>
  </li>
  <li>Expand traffic</li>
</ol>
Style nested markers and a presentational resume point
.procedure { list-style-type: decimal; }
.procedure ul { list-style-type: square; }
.procedure ul ul { list-style-type: circle; }

.resume-at-five { counter-set: list-item 4; }

Note: Prefer start="5" or value="5" when five is meaningful data rather than a visual effect.

Back to quick reference ↑
05

Treat marker design as progressive, nonessential presentation

An ol or ul with li children supplies durable list semantics before CSS loads and when custom marker support differs. Do not remove markers unless another visible treatment still makes every item boundary obvious, and do not rely on decorative symbols to communicate completed, failed, or required state. Marker pronunciation can vary across browser and assistive-technology combinations; although Counter Styles defines speak-as, support is still evolving, so real text must carry essential meaning. Feature queries can isolate ::marker enhancements, while the base list style remains usable. For long lists, native markers and shared rules also avoid extra DOM nodes and repeated image work.

A semantic checklist with an optional marker enhancement
<h2 id="release-title">Release checklist</h2>
<ol class="release-list" aria-labelledby="release-title">
  <li><strong>Complete:</strong> tests passed</li>
  <li><strong>Pending:</strong> production approval</li>
</ol>
Feature-query the decorative marker layer
.release-list {
  list-style-type: decimal;
  padding-inline-start: 1.75rem;
}

@supports selector(li::marker) {
  .release-list > li::marker {
    color: #0f766e;
    font-weight: 700;
  }
}

Note: The words Complete and Pending communicate state even if marker styling is absent or not announced.

Back to quick reference ↑

Local code tester

Try resilient list marker systems

Edit native, custom, and nested markers while the underlying semantic list remains intact.

Runs in your browser
Preview

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. World Wide Web ConsortiumCSS Lists and Counters Module Level 3w3.org
  2. World Wide Web ConsortiumCSS Counter Styles Level 3w3.org
  3. World Wide Web ConsortiumCSS Generated Content Module Level 3w3.org
  4. World Wide Web ConsortiumCSS Conditional Rules Module Level 3w3.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback