CSS Lists and Counters Module Level 3
CSS Lists and Counters Module Level 3
Editor’s Draft
6 March 2026
More details about this document
This version:
Latest published version:
Previous Versions:
Feedback:
CSSWG Issues Repository
Inline In Spec
Editors:
Elika J. Etemad / fantasai
Apple
Tab Atkins
Google
Former Editors:
Ian Hickson
Google
Tantek Çelik
Formerly of Microsoft
Suggest an Edit for this Spec:
GitHub Editor
Contributors:
Simon Montagu, AOL-TW/Netscape,
smontagu@netscape.com
Daniel Yacob,
yacob@geez.org
Christopher Hoess,
choess@stwing.upenn.edu
Daniel Glazman, AOL-TW/Netscape,
glazman@netscape.com
World Wide Web Consortium
W3C
liability
trademark
and
permissive document license
rules apply.
Abstract
This module contains CSS features related to list counters: styling them, positioning them, and manipulating their value.
CSS
is a language for describing the rendering of structured documents
(such as HTML and XML)
on screen, on paper, etc.
Status of this document
This is a public copy of the editors’ draft.
It is provided for discussion only and may change at any moment.
Its publication here does not imply endorsement of its contents by W3C.
Don’t cite this document other than as work in progress.
Please send feedback
by
filing issues in GitHub
(preferred),
including the spec code “css-lists” in the title, like this:
“[css-lists]
…summary of comment…
”.
All issues and comments are
archived
Alternately, feedback can be sent to the (
archived
) public mailing list
www-style@w3.org
This document is governed by the
18 August 2025 W3C Process Document
1.
Introduction
This specification defines the
::marker
pseudo-element,
the
list-item
display type
that generates markers,
and several properties controlling the placement and styling of markers.
It also defines
counters
which are special numerical objects
often used to generate the default contents of markers.
For instance, the following example illustrates
how markers can be used to add parentheses around each numbered list item:
style
li
::
marker
content
"("
counter
list-item
lower-roman
")"
li
display
list-item
style
ol
li
This is the first item.
li
This is the second item.
li
This is the third item.
ol
It should produce something like this:
(i) This is the first item.
(ii) This is the second item.
(iii) This is the third item.
Note:
Note that this example is far more verbose than is usually needed in HTML,
as the UA default style sheet takes care of most of the necessary styling.
With descendant selectors and child selectors,
it’s possible to specify different marker types depending on the depth of embedded lists.
1.1.
Value Definitions
This specification follows the
CSS property definition conventions
from
[CSS2]
using the
value definition syntax
from
[CSS-VALUES-3]
Value types not defined in this specification are defined in CSS Values & Units
[CSS-VALUES-3]
Combination with other CSS modules may expand the definitions of these value types.
In addition to the property-specific values listed in their definitions,
all properties defined in this specification
also accept the
CSS-wide keywords
as their property value.
For readability they have not been repeated explicitly.
2.
Declaring a List Item
list item
is any element with its
display
property set to
list-item
List items
generate
::marker
pseudo-elements;
no other elements do.
Additionally,
list items
automatically increment an implied
list-item
counter
(see
§ 4.6 The Implicit list-item Counter
).
3.
Markers
The defining feature of the
list item
display type
is its
marker
a symbol or ordinal that helps denote the beginning of each
list item
in a list.
In the CSS layout model,
list item
markers
are represented by
marker box
associated with each
list item
The contents of this
marker
can be controlled with
the
list-style-type
and
list-style-image
properties on the
list item
and by assigning properties to its
::marker
pseudo-element.
3.1.
The
::marker
Pseudo-Element
The
marker box
is generated by
the
::marker
pseudo-element of a
list item
as the
list item’s
first child,
before the
::before
pseudo-element
(if it exists on the element).
It is filled with content
as defined in
§ 3.2 Generating Marker Contents
In this example, markers are used to number paragraphs that are designated as "notes":
style
margin-left
12
em
note
display
list-item
counter-increment
note-counter
note
::
marker
content
"Note "
counter
note
-counter
":"
style
This is the first paragraph in this document.
class
"note"
This is a very short document.
This is the end.
It should render something like this:
This is the first paragraph
in this document.
Note 1: This is a very short
document.
This is the end.
By using the
::marker
pseudo-element,
a list’s markers can be styled
independently from the text of the list item itself:
style
margin-left
em
/* Make space for counters */
li
list-style-type
lower-roman
li
::
marker
color
blue
font-weight
bold
style
This is a long preceding paragraph ...
ol
li
This is the first item.
li
This is the second item.
li
This is the third item.
ol
This is a long following paragraph ...
The preceding document should render something like this:
This is a long preceding
paragraph ...
i.
This is the first item.
ii.
This is the second item.
iii.
This is the third item.
This is a long following
paragraph ...
Previously the only way to style a marker was through inheritance;
one had to put the desired marker styling on the list item,
and then revert that on a wrapper element around the list item’s actual contents.
Marker boxes
only exist for
list items
on any other element,
the
::marker
pseudo-element’s
content
property must compute to
none
which suppresses its creation.
3.1.1.
Properties Applying to
::marker
All properties can be set on a
::marker
pseudo-element
and will have a
computed value
which will then inherit to its text content.
Inheritable properties that apply to text
can be set on the
::marker
pseudo-element:
these will inherit to and take effect on its text contents.
Some examples of such properties include:
text-transform
letter-spacing
word-spacing
(see
[CSS-TEXT-3]
all the font properties (see
[CSS-FONTS-3]
and its successors)
the
color
property (see
[CSS-COLOR-3]
However,
only the following CSS properties
actually apply to a
marker box
the
text-combine-upright
unicode-bidi
, and
direction
properties (see
[CSS-WRITING-MODES-3]
the
content
property (see
§ 3.2 Generating Marker Contents
, below)
all animation and transition properties (see
[CSS-ANIMATIONS-1]
and
[CSS-TRANSITIONS-1]
Other properties should not have an effect on the
marker box
when declared directly on
::marker
in the
author
or
user origin
of the
cascade
UAs may either treat such properties as not applying,
or enforce their value or inheritance from the
originating element
by setting a
user-agent origin
!important
rule.
NOTE:
It is expected that future specifications will extend this list of properties
and relax the restriction on which properties can take effect.
However at the moment outside marker box layout is not fully defined,
so to avoid future compatibility problems only these properties are allowed.
Additionally,
UAs must add the following rule to their default style sheet:
::marker, ::before::marker, ::after::marker {
unicode-bidi: isolate;
font-variant-numeric: tabular-nums;
white-space: pre;
text-transform: none;
white-space: pre
doesn’t have quite the right behavior;
white-space-collapse: preserve-spaces
white-space-trim: discard-after
might be closer to what’s needed here.
See discussion in
Issue 4448
and
Issue 4891
Note:
Although the
::marker
pseudo-element can represent
the
marker box
of a
::before
or
::after
pseudo-element,
the
compound selector
::marker
which expands to
*::marker
[SELECTORS-4]
will not select these markers—an
originating element
that is a
pseudo-element
needs to be explicitly specified in the
selector
e.g.
::before::marker
3.2.
Generating Marker Contents
The contents of a
marker box
are determined by the first of these conditions that is true:
content
on the
::marker
itself is not
normal
The contents of the
marker box
are determined as defined by the
content
property,
exactly as for
::before
list-style-image
on the
originating element
defines a
marker image
The
marker box
contains
an
anonymous
inline
replaced element
representing the specified
marker image
followed by a
text sequence
consisting of a single space (U+0020 SPACE).
list-style-type
on the
originating element
defines a
marker string
The
marker box
contains
text sequence
consisting of the specified
marker string
otherwise
The
marker box
has no contents
and
::marker
does not generate a box.
Additionally, the UA may transform into spaces or discard
any preserved
forced line breaks
3.3.
Image Markers: the
list-style-image
property
Name:
list-style-image
Value:
none
Initial:
none
Applies to:
list items
Inherited:
yes
Percentages:
n/a
Computed value:
the keyword
none
or the computed
Canonical order:
per grammar
Animation type:
discrete
Specifies the
marker image
which is used to fill the
list item’s
marker
when its
content
is
normal
The values are as follows:
If the
represents a
valid image
specifies the element’s
marker image
as the
Otherwise,
the element has no
marker image
none
The element has no
marker image
The
marker image
is sized
using the
default sizing algorithm
[css-images-3]
with no
specified size
and a
default object size
of 1em square.
The following example sets the marker at the beginning of each list item to
be the image "ellipse.png".
li
list-style-image
url
"http://www.example.com/ellipse.png"
3.4.
Text-based Markers: the
list-style-type
property
Name:
list-style-type
Value:
none
Initial:
disc
Applies to:
list items
Inherited:
yes
Percentages:
n/a
Computed value:
specified value
Canonical order:
per grammar
Animation type:
discrete
Specifies the
marker string
which is used to fill the
list item
’s
marker
when its
content
value is
normal
and there is no
marker image
The values are as follows:
Specifies the element’s
marker string
as
the value of the
list-item
counter
represented using the specified
Specifically,
the
marker string
is
the result of
generating a counter representation
of the
list-item
counter value
using the specified
prefixed by the
prefix
of the
and followed by the
suffix
of the
If the specified
does not exist,
decimal
is assumed.
The element’s
marker string
is the specified
none
The element has no
marker string
The following examples illustrate how to set markers to various values:
ul
list-style-type
"★"
/* Sets the marker to a "star" character */
p.note
display
list-item
list-style-type
"Note: "
list-style-position
inside
/* Gives note paragraphs a marker consisting of the string "Note: " */
ol
list-style-type
upper-roman
/* Sets all ordered lists to use the upper-roman counter-style
(defined in the Counter Styles specification [[CSS-COUNTER-STYLES]]) */
ul
list-style-type
symbols
cyclic
'○'
'●'
);
/* Sets all unordered list items to alternate between empty and
filled circles for their markers. */
ul
list-style-type
none
/* Suppresses the marker entirely, unless list-style-image is specified
with a valid image. */
3.5.
Positioning Markers: The
list-style-position
property
Name:
list-style-position
Value:
inside
outside
Initial:
outside
Applies to:
list items
Inherited:
yes
Percentages:
n/a
Computed value:
keyword, but see prose
Canonical order:
per grammar
Animation type:
discrete
This property dictates whether the
::marker
is rendered inline,
or positioned just outside of the
list item
The values are as follows:
inside
No special effect.
(The
::marker
is an inline element at the start of the
list item’s
contents.)
outside
If the
list item
is a
block container
the marker box is a
block container
and is placed outside the
principal block box
however, the position of the list-item marker adjacent to floats is undefined.
CSS does not specify the precise location of the marker box
or its position in the painting order,
but does require that it be placed on the
inline-start
side of the box,
using the
writing mode
of the box indicated by
marker-side
The marker box is fixed with respect to the principal block box’s border
and does not scroll with the principal box’s content.
A UA may hide the marker if the element’s
overflow
is other than
visible
(This allowance may change in the future.)
The size or contents of the marker box may affect
the height of the principal block box
and/or the height of its first line box,
and in some cases may cause the creation of a new line box;
this interaction is also not defined.
This is handwavey nonsense from CSS2, and needs a real definition.
If the
list item
is an
inline box
this value is equivalent to
inside
Alternatively,
outside
could lay out the marker as a previous sibling of the principal inline box.
For example:
The above example may be formatted as:
* first "inside" list
item comes first
* second "inside" list
item comes second
========================
* first "outside" list
item comes first
* second "outside" list
item comes second
3.6.
Styling Markers: the
list-style
shorthand property
Name:
list-style
Value:
<'list-style-position'>
||
<'list-style-image'>
||
<'list-style-type'>
Initial:
see individual properties
Applies to:
list items
Inherited:
see individual properties
Percentages:
see individual properties
Computed value:
see individual properties
Animation type:
see individual properties
Canonical order:
per grammar
The
list-style
property is a shorthand notation
for setting the three properties
list-style-type
list-style-image
, and
list-style-position
at the same place in the style sheet.
For example:
ul
list-style
upper-roman inside
/* Any UL */
ul ul
list-style
circle outside
/* Any UL child of a UL */
Using a value of
none
in the shorthand is potentially ambiguous,
as
none
is a valid value for both
list-style-image
and
list-style-type
To resolve this ambiguity,
a value of
none
in the shorthand must be applied to whichever of the two properties aren’t otherwise set by the shorthand.
list-style
none disc
/* Sets the image to "none" and the type to "disc". */
list-style: none
url
bullet.png
);
/* Sets the image to "url(bullet.png)" and the type to "none". */
list-style: none
/* Sets both image and type to "none". */
list-style: none disc
url
bullet.png
);
/* Syntax error */
Note:
The
values of
list-style-type
can also create grammatical ambiguities.
As such values are ultimately
values,
the parsing rules in
[CSS-VALUES-3]
apply.
Although authors may specify
list-style
information directly on list item elements
(e.g.,
li
in HTML),
they should do so with care.
Consider the following rules:
ol.alpha li
list-style
lower-alpha
ul li
list-style
disc
The above won’t work as expected.
If you nest a
ul
into an
ol class=alpha
the first rule’s specificity will make the
ul
’s list items use the lower-alpha style.
ol.alpha > li
list-style
lower-alpha
ul > li
list-style
disc
These work as intended.
ol.alpha
list-style
lower-alpha
ul
list-style
disc
These are even better,
since inheritance will transfer the
list-style
value to the list items.
3.7.
The
marker-side
property
Name:
marker-side
Value:
match-self
match-parent
Initial:
match-self
Applies to:
list items
Inherited:
yes
Percentages:
n/a
Computed value:
specified keyword
Canonical order:
per grammar
Animation type:
discrete
The
marker-side
property specifies
whether an
outside
marker box
is positioned
based on the directionality of the list item itself (i.e. its
originating element
or the directionality of the list container (i.e. the
originating element
’s parent).
In the first case, the position of the marker can vary across items in the same list,
based on the directionality assigned to each list item individually;
in the second case they will all align on the same side,
as determined by the directionality assigned to the list as a whole.
match-self
The
marker box
is positioned
using the directionality of the
::marker
’s
originating element
match-parent
The
marker box
is positioned
using the directionality of the
::marker
’s
originating element’s
parent element.
By default, elements or
::marker
pseudo-elements
position themselves according to their list item’s directionality.
However, if the list item is grouped with several other list items which may have different directionality
(for example, multiple in HTML),
it is sometimes more useful to have all the markers line up on one side,
so the author can specify a single "gutter" on that side
and be assured that all the markers will lie in that gutter and be visible.
Both of the following example renderings are generated from the following HTML,
with the only difference being the value of
marker-side
on the list:
ul
li
english one
li
dir
rtl
OWT WERBEH
li
english three
li
dir
rtl
RUOF WERBEH
ul
match-self
match-parent
* english one
OWT WERBEH *
* english three
RUOF WERBEH *
* english one
* OWT WERBEH
* english three
* RUOF WERBEH
For this order punctuation inside the marker correctly,
it would also need to take the
direction
value of the parent.
[Issue #4202]
There are issues open on
renaming the keywords
and on
merging with
list-style-position
4.
Automatic Numbering With Counters
counter
is a special numeric tracker
used, among other things, to automatically number list items in CSS.
Every element has a collection of zero or more counters,
which are inherited through the document tree in a way similar to inherited property values.
Counters
have a
name
and
creator
which identify the counter,
a boolean
reversed
(false by default),
and an integer
value
(optional when the counter is
reversed
).
They are created and manipulated with
the
counter properties
counter-increment
counter-set
and
counter-reset
and used with the
counter()
and
counters()
functional notations
Counters are referred to in CSS syntax
using the
type,
which represents their name as a
name cannot match the keyword
none
such an identifier is
invalid
as a
reversed
counter is created with the
reversed()
functional notation
which is defined as follows:
= reversed(
Resolving
counter
values on a given element is a multi-step process:
Existing counters are
inherited
from previous elements.
New counters are
instantiated
counter-reset
).
Counter values are incremented (
counter-increment
).
Counter values are explicitly set (
counter-set
).
Counter values are used (
counter()
counters()
).
UAs may have implementation-specific limits
on the maximum or minimum value of a counter.
If a counter reset, set, or increment
would push the value outside of that range,
the value must be clamped to that range.
4.1.
Creating Counters: the
counter-reset
property
Name:
counter-reset
Value:
none
Initial:
none
Applies to:
all elements
Inherited:
no
Percentages:
n/a
Computed value:
the keyword
none
or a list, each item an identifier or a
reversed()
function paired with an integer
Canonical order:
per grammar
Animation type:
by computed value type
User agents are expected to support this property on all media, including non-visual ones.
The
counter-reset
property
instantiates
new
counters
on an element
and sets them to the specified integer values.
Its values are defined as follows:
none
This element does not create any new counters.
Instantiates
a counter of the given
with a starting value of the given
defaulting to
Instantiates
reversed
counter of the given
with a starting value of the given
or no starting value if not given.
Note that counter properties follow the
cascading
rules as normal.
Thus, due to cascading, the following style sheet:
h1
counter-reset
section
-1
h1
counter-reset
imagenum
99
will only reset
imagenum
To reset both counters,
they have to be specified together:
H1
counter-reset
section
-1
imagenum
99
The same principles apply to the
counter-set
and
counter-increment
properties.
See
[css-cascade-4]
If multiple instances of the same
occur in the property value,
only the last one is honored.
4.2.
Manipulating Counter Values: the
counter-increment
and
counter-set
properties
Name:
counter-increment
Value:
none
Initial:
none
Applies to:
all elements
Inherited:
no
Percentages:
n/a
Computed value:
the keyword
none
or a list, each item an identifier paired with an integer
Canonical order:
per grammar
Animation type:
by computed value type
User agents are expected to support this property on all media, including non-visual ones.
Name:
counter-set
Value:
none
Initial:
none
Applies to:
all elements
Inherited:
no
Percentages:
n/a
Computed value:
the keyword
none
or a list, each item an identifier paired with an integer
Canonical order:
per grammar
Animation type:
by computed value type
User agents are expected to support this property on all media, including non-visual ones.
The
counter-increment
and
counter-set
properties
manipulate the value of existing
counters
They only
instantiate
new counters
if there is no counter of the given name on the element yet.
Their values are defined as follows:
none
This element does not alter the value of any counters.
Sets (for
counter-set
) or increments (for
counter-increment
the value of the named counter on the element
to/by the specified
If the
is omitted,
it defaults to
(for
counter-increment
or
(for
counter-set
).
If there is not currently a counter of the given name on the element,
the element
instantiates
a new counter of the given name
with a starting value of
before setting or incrementing its value.
This example shows a way to number chapters and sections with "Chapter 1", "1.1", "1.2", etc.
h1
:before
content
"Chapter "
counter
chapter
". "
counter-increment
chapter
/* Add 1 to chapter */
counter-reset: section
/* Set section to 0 */
h2::before
content
counter
chapter
"."
counter
section
" "
counter-increment
section
If multiple instances of the same
occur in the property value,
they are all processed, in order.
Thus increments will compound,
but only the last set value will take effect.
4.3.
Nested Counters and Scope
Counters are “self-nesting”;
instantiating
a new counter on an element
which inherited an identically-named
counter
from its parent
creates a new counter of the same name,
nested inside the existing counter.
This is important for situations like lists in HTML,
where lists can be nested inside lists to arbitrary depth:
it would be impossible to define uniquely named counters for each level.
The
counter()
function only retrieves the
innermost
counter of a given name on the element,
whereas the
counters()
function uses all counters of a given name that contain the element.
The
scope
of a
counter
therefore
starts at the first element in the document that
instantiates
that counter
and includes the element’s descendants and its following siblings with their descendants.
However, it does not include any elements in the scope of a counter with the same name
created by a
counter-reset
on a later sibling of the element,
allowing such explicit counter instantiations
to obscure those earlier siblings.
See
§ 4.4 Creating and Inheriting Counters
for the exact rules governing the scope of counters and their values.
The following code numbers nested list items.
The result is very similar to that of setting
display:list-item
and
list-style: inside
on the LI element:
ol
counter-reset
item
li
display
block
li::before
content
counter
item
". "
counter-increment
item
In this example,
an
ol
will create a counter,
and all children of the
ol
will refer to that counter.
If we denote the
th
instance of the
item
counter by item
then the following HTML fragment will use the indicated counters.
item
is created, set to 0
item
is incremented to 1
item
is incremented to 2
item
is created, set to 0, nested in item
item
is incremented to 1
item
is incremented to 2
item
is incremented to 3
item
is created, set to 0, nested in item
item
is incremented to 1
item
is incremented to 4
item
is created, set to 0, nested in item
item
is incremented to 1
item
is incremented to 5
item
is incremented to 3
item
is incremented to 4
item
is created, set to 0
item
is incremented to 1
item
is incremented to 2
4.4.
Creating and Inheriting Counters
Each element or pseudo-element in a document has
a (possibly empty) set of
counters
in the
scope
of that element,
either through inheritance from another element
or through instantiation on the element directly.
These counters are represented as a
CSS counters set
which is a
set
whose values are each a
tuple
of:
string
(representing a counter’s
name
),
an element (representing the counter’s
creator
),
a boolean (representing whether the counter is
reversed
),
and optionally an integer (representing the counter’s
value
).
The latest
counter
of a given name in that set
represents the
innermost
counter of that name.
4.4.1.
Inheriting Counters
An element
inherits
its initial set of counters
from its parent and preceding
sibling
It then takes the values for those counters
from the values of the matching counters
on its preceding
element in
tree order
(which might be its parent,
its preceding sibling,
or a descendant of its previous sibling).
To
inherit counters
into an
element
Let
element counters
be an initially empty
CSS counters set
representing
element
’s own
CSS counters set
If
element
is the
root
of its document tree,
return.
(The element has an initially-empty counter map
and inherits nothing.)
Let
counter source
be the
CSS counters set
of
element
’s preceding sibling,
if it has one,
or else of
element
’s parent
if it does not.
Let
value source
be the
CSS counters set
of the element immediately preceding
element
in
tree order
For each
(|=CSS counter/name=|,
originating element
, |=value=|) of
value source
If
counter source
also
contains
counter
with the same |=CSS counter/name=| and
originating element
then
append
a copy of
value source
’s
counter
(|=CSS counter/name=|,
originating element
, |=value=|)
to
element counters
Take the following code as an example:
foo
baz
Recall that
tree order
turns a document tree into an ordered list,
where an element comes before its children,
and its children come before its next sibling.
In other words,
for a language like HTML,
it’s the order in which the parser encounters start tags as it reads the document.
In here, the
ul
element establishes a new counter named
example
and sets its value to
The
#foo
element, being the first child of the
ul
inherits this counter.
Its parent is also its immediately preceding element in
tree order
so it inherits the value
with it,
and then immediately increments the value to
The same happens with the
#bar
element.
It inherits the
example
counter from
#foo
and inherits the value
from it as well
and increments it to
However, the
#baz
element is a bit different.
It inherits the
example
counter from the
#foo
element,
its previous sibling.
However, rather than inheriting the value
from
#foo
along with the counter,
in inherits the value
from
#bar
, the previous element in
tree order
This behavior allows a single counter to be used throughout a document,
continuously incrementing,
without the author having to worry about the nested structure of their document.
Note:
Counter inheritance, like regular CSS
inheritance
operates on the “flattened element tree”
in the context of the
[DOM]
4.4.2.
Instantiating Counters
Counters
are
instantiated
when named in
counter-reset
and also when not otherwise present if named in
counter-increment
counter-set
, or the
counter()
or
counters()
notations.
(Newly
instantiated
counters
replace identically-named
counters
originating from previous siblings,
but are added in addition to identically-named
counters
originating from ancestor elements,
see
§ 4.3 Nested Counters and Scope
.)
To
instantiate a counter
of a given
name
on an
element
optionally
reversed
with an optional starting
value
Let
counters
be
element
’s
CSS counters set
Let
innermost counter
be the last
counter
in
counters
with the name
name
If
innermost counter
’s originating element
is
element
or a previous sibling of
element
remove
innermost counter
from
counters
Append
a new
counter
to
counters
with name
name
originating element
element
reversed being
reversed
and initial value
value
(if given)
When a
counter
is
instantiated
without an initial value,
the user agent must dynamically calculate the initial value at layout-time
to be the value returned by the following algorithm:
Let
num
be 0.
Let
lastNonZeroIncrementNegated
be 0.
For each element or pseudo-element
el
that increments or
sets the same counter in the same
scope
Let
incrementNegated
be
el
’s
counter-increment
integer value for this counter,
multiplied by -1.
If
incrementNegated
is not zero,
then set
lastNonZeroIncrementNegated
to
incrementNegated
If
el
sets this counter with
counter-set
then add that integer value to
num
and
break this loop.
Add
incrementNegated
to
num
Add
lastNonZeroIncrementNegated
to
num
Return
num
Note:
Only
reversed
counters can be instantiated without an initial value.
4.5.
Counters in elements that do not generate boxes
An element that does not generate a box
(for example, an element with
display
set to
none
, or a pseudo-element with
content
set to
none
cannot set, reset, or increment a counter.
The counter properties are still valid on such an element,
but they must have no effect.
For example, with the following style sheet,
H2s with class "secret" do not increment
count2
h2
counter-increment
count2
h2.secret
display
none
Note:
Other methods of “hiding” elements,
such as setting
visibility
to
hidden
still cause the element to generate a box,
and so are not excepted here.
Whether a
replaced element’s
descendants
(such as HTML
option
or SVG
rect
can set, reset, or increment a counter
is undefined.
Note:
The behavior on
replaced element
descendants is currently undefined
due to a lack of interoperability across implementations.
4.6.
The Implicit
list-item
Counter
In addition to any explicitly defined
counters
that authors write in their styles,
list items
automatically increment
a special
list-item
counter
which is used when generating the default
marker string
on
list items
(see
list-style-type
).
Specifically,
unless the
counter-increment
property explicitly specifies
a different increment for the
list-item
counter,
it must be incremented by 1 on every
list item
or if the counter is
reversed
it must be incremented by -1 on every
list item
instead,
at the same time that
counters
are normally incremented
(exactly as if the
list item
had
list-item 1
or
list-item -1
appended to their
counter-increment
value,
including side-effects such as possibly
instantiating
a new
counter
, etc).
This does not affect the
specified
or
computed values
of
counter-increment
Because each
list item
automatically increments
the
list-item
counter by 1,
consecutive
list items
with a numeric
list-style-type
will be consecutively numbered by default—even if the author sets
counter-increment
to another value
such as
counter-increment: itemnumber
or even
none
This protects the automatic
list-item
counter
from inadvertently being overridden
by declarations intended to address other counters.
However, since the automatic
list-item
increment
does not
happen
if the
list item’s
counter-increment
explicitly mentions the
list-item
counter,
li { counter-increment: list-item 2; }
will increment
list-item
by 2 as specified,
not by 3 as would happen
if
list-item 1
were unconditionally appended.
This also allows to turn off the automatic
list-item
counter increment,
by overriding it explicitly, e.g.
counter-increment: list-item 0;
In all other respects, the
list-item
counter
behaves like any other
counter
and can be used and manipulated by authors
to adjust
list item
styling
or for other purposes.
In the following example,
the list is modified to count by twos:
ol.evens > li { counter-increment: list-item 2; }
A three-item list would be rendered as
2. First Item
4. Second Item
6. Third Item
UAs and host languages should ensure
that the
list-item
counter values
by default
reflect the underlying numeric value dictated by host language semantics
when setting up list item styling
in their UA style sheet and presentational hint style mappings.
See, e.g.
Appendix A: Sample Style Sheet For HTML
In the following example,
the
content
property is used to create tiered numbering
that hooks into the
list-item
counter,
and thus respects any numbering changes inflicted through HTML:
ol > li::marker { content: counters(list-item,'.') '.'; }
Nested lists using this rule would be rendered like
1. First top-level item
5. Second top-level item, value=5
5.3. First second-level item, list start=3
5.4. Second second-level item, list start=3
5.4.4. First third-level item in reversed list
5.4.3. Second third-level item in reversed list
5.4.2. Third third-level item in reversed list
5.4.1. Fourth third-level item in reversed list
5.5. Third second-level item, list start=3
6. Third top-level item
given markup such as
4.7.
Outputting Counters: the
counter()
and
counters()
functions
Counters
have no visible effect by themselves,
but their values can be used
with the
counter()
and
counters()
functions,
whose
used values
represent counter values as strings or images.
They are defined as follows:
= counter(
= counters(
where
specifies the
counter style
for
generating a representation
of the named counter(s)
as defined in
[css-counter-styles-3]
and
counter()
Represents the value of the
innermost
counter
in the element’s
CSS counters set
named
using the
counter style
named
counters()
Represents the values of all the
counters
in the element’s
CSS counters set
named
using the
counter style
named
sorted in outermost-first to
innermost
-last order
and joined by the specified
In both cases,
if the
argument is omitted it defaults to
decimal
Note:
If the
is one of the predefined symbolic styles,
like
disc
it might look different than when used in
list-style-type
See
CSS Counter Styles 3
§ 6.3 Symbolic: disc, circle, square, disclosure-open, disclosure-closed
If no
counter
named
exists
on an element where
counter()
or
counters()
is used,
one is first
instantiated
with a starting value of
H1::before { content: counter(chno, upper-latin) ". " }
/* Generates headings like "A. A History of Discontent" */
H2::before { content: counter(section, upper-roman) " - " }
/* Generates headings like "II - The Discontent Part" */
BLOCKQUOTE::after { content: " [" counter(bq, decimal) "]" }
/* Generates blockquotes that end like "... [3]" */
DIV.note::before { content: counter(notecntr, disc) " " }
/* Simply generates a bullet before every div.note */
P::before { content: counter(p, none) }
/* inserts nothing */
The following example shows a simple use of the
counters()
function:
ul
li
one
li
li
two
ul
li
nested one
li
li
nested two
li
ul
li
li
three
li
ul
style
li
::
marker
content
'('
counters
list-item
'.'
') '
style
The preceding document should render something like this:
(1) one
(2) two
(2.1) nested one
(2.2) nested two
(3) three
Because counters inherit to siblings as well,
they can be used to number headings and subheadings,
which aren’t nested within each other.
Unfortunately,
this prevents the use of
counters()
as counters from siblings don’t nest,
but one can create multiple counters and manually concatenate them instead:
h1
First H1
h1
...
h2
First H2 in H1
h2
...
h2
Second H2 in H1
h2
...
h3
First H3 in H2
h3
...
h1
Second H1
h1
...
h2
First H2 in H1
h2
...
style
body
counter-reset
h1
h2
h3
h1
counter-increment
h1
counter-reset
h2
h3
;}
h2
counter-increment
h2
counter-reset
h3
h3
counter-increment
h3
h1
::
before
content
counter
h1
upper-alpha
' '
h2
::
before
content
counter
h1
upper-alpha
'.'
counter
h2
decimal
' '
h3
::
before
content
counter
h1
upper-alpha
'.'
counter
h2
decimal
'.'
counter
h3
lower-roman
' '
style
The preceding document should render something like this:
A First H1
...
A.1 First H2 in H1
...
A.2 Second H2 in H1
...
A.2.i First H3 in H2
...
B Second H1
...
B.1 First H2 in H1
...
Counters are sometimes useful for things other than printing markers.
In general, they provide the ability to number elements in sequence,
which can be useful for other properties to reference.
For example, using
order
to put an element between two other specific elements
currently requires you to explicitly put
order
on every element before and/or after the desired insertion point.
If you can set the
order
value of everything to a counter though,
you can more easily insert an element into an arbitrary spot between two others.
Other use-cases involve nested or sibling elements with transforms that are meant to be slightly different from each other.
Today you have to use a preprocessor to do this in a reasonable way,
but a counter would make it work well in "plain" CSS.
(You can built up successive values in the nested case today
by using
custom properties
and stacking up nested
calc()
s,
but this is a *little bit* clumsy,
and doesn’t work for siblings.)
Suggestion is to add a
counter-value(
function,
which returns the value of the named counter as an integer,
rather than returning a string.
See
Issue 1026
Appendix A: Sample Style Sheet For HTML
This section is informative, not normative.
The
[HTML]
Rendering
chapter
defines the normative default properties that apply to HTML lists;
this sample style sheet is provided to illustrate the CSS features
using familiar markup conventions.
/* Set up list items */
li {
display: list-item; /* implies 'counter-increment: list-item' */
/* Set up ol and ul so that they scope the list-item counter */
ol, ul {
counter-reset: list-item;
/* Default list style types for lists */
ol { list-style-type: decimal; }
ul { list-style-type: toggle(disc, circle, square); }
/* The type attribute on ol and ul elements */
ul[type="disc"] { list-style-type: disc; }
ul[type="circle"] { list-style-type: circle; }
ul[type="square"] { list-style-type: square; }
ol[type="1"] { list-style-type: decimal; }
ol[type="a"] { list-style-type: lower-alpha; }
ol[type="A"] { list-style-type: upper-alpha; }
ol[type="i"] { list-style-type: lower-roman; }
ol[type="I"] { list-style-type: upper-roman; }
/* The start attribute on ol elements */
ol[start] {
counter-reset: list-item calc(attr(start integer, 1) - 1);
/* The value attribute on li elements */
li[value] {
counter-set: list-item attr(value integer, 1);
/* Handling reversed lists */
ol[reversed] {
counter-reset: reversed(list-item);
ol[reversed][start] {
counter-reset: reversed(list-item) calc(attr(start integer) + 1);
/* Box Model Rules */
ol, ul {
display: block;
margin-block: 1em;
marker-side: match-parent;
padding-inline-start: 40px;
ol ol, ol ul, ul ul, ul ol {
margin-block: 0;
li {
text-align: match-parent;
Acknowledgments
This specification is made possible by input from
Aharon Lanin,
Arron Eicholz,
Brad Kemper,
David Baron,
Emilio Cobos Álvarez,
Mats Palmgren,
Oriol Brufau,
Simon Sapin,
Xidorn Quan
Changes
This section documents the changes since previous publications.
Changes since the 9 July 2020 WD
Clarified properties that apply to
::marker
boxes
vs. to the contents of
::marker
boxes.
Issue 4568
Added
text-transform: none
to the UA default style sheet for
::marker
Issue 4206
Changed counter inheritance to take from the parent first,
and only take from the sibling if it’s a new counter.
Issue 5477
Changes since the 17 August 2019 WD
Specified that
outside
list markers
block containers
(Their
outer display type
remains undefined.)
Stole list of properties applying to
::marker
from
[CSS-PSEUDO-4]
and added animations, transitions, and
white-space
Added
white-space: pre
to UA default style sheet for
::marker
Issue 4448
Note, however, that the exact white space processing behavior of marker boxes
is still being worked out.
Changes since the 25 April 2019 WD
Rewrote the
§ 4 Automatic Numbering With Counters
section for better precision, editorial clarity, and synchronization with CSS2.
Changes since the 20 March 2014 WD
Use
consistently for counter names.
Dropped
position: marker
(marker positioning is now mostly undefined, as in CSS2).
Completely rewrote chapter on markers to tighten it up,
align with current expectations, and make editorial improvements.
Pulled the
list-item
counter definition
into its own section, added examples, and made some clarifications.
Renamed values of
marker-side
to match conventions from box/text alignment.
Defined that
counter-set
is applied after
counter-increment
rather than before.
Issue 3810
Established the canonical order of
list-style
serialization
to put
<'list-style-type'>
last.
Issue 2624
Changes From CSS Level 2
As described in the introduction section,
there are significant changes in this module when compared to CSS2.1.
The
::marker
pseudo-element has been introduced to allow styling of the list marker directly.
list-style-type
now accepts a
as well as the extended
values from
[css-counter-styles-3]
..
The
list-item
predefined counter identifier has been introduced.
The
counter-set
property has been added.
Allowed for
inline-level
list items
, as introduced in
[CSS-DISPLAY-3]
Privacy Considerations
No new privacy considerations have been reported on this specification.
Security Considerations
No new security considerations have been reported on this specification.
Conformance
Document conventions
Conformance requirements are expressed with a combination of
descriptive assertions and RFC 2119 terminology. The key words “MUST”,
“MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
“RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this
document are to be interpreted as described in RFC 2119.
However, for readability, these words do not appear in all uppercase
letters in this specification.
All of the text of this specification is normative except sections
explicitly marked as non-normative, examples, and notes.
[RFC2119]
Examples in this specification are introduced with the words “for example”
or are set apart from the normative text with
class="example"
like this:
This is an example of an informative example.
Informative notes begin with the word “Note” and are set apart from the
normative text with
class="note"
, like this:
Note, this is an informative note.
Advisements are normative sections styled to evoke special attention and are
set apart from other normative text with
, like
this:
UAs MUST provide an accessible alternative.
Tests
Tests relating to the content of this specification
may be documented in “Tests” blocks like this one.
Any such block is non-normative.
Conformance classes
Conformance to this specification
is defined for three conformance classes:
style sheet
CSS
style sheet
renderer
UA
that interprets the semantics of a style sheet and renders
documents that use them.
authoring tool
UA
that writes a style sheet.
A style sheet is conformant to this specification
if all of its statements that use syntax defined in this module are valid
according to the generic CSS grammar and the individual grammars of each
feature defined in this module.
A renderer is conformant to this specification
if, in addition to interpreting the style sheet as defined by the
appropriate specifications, it supports all the features defined
by this specification by parsing them correctly
and rendering the document accordingly. However, the inability of a
UA to correctly render a document due to limitations of the device
does not make the UA non-conformant. (For example, a UA is not
required to render color on a monochrome monitor.)
An authoring tool is conformant to this specification
if it writes style sheets that are syntactically correct according to the
generic CSS grammar and the individual grammars of each feature in
this module, and meet all other conformance requirements of style sheets
as described in this module.
Partial implementations
So that authors can exploit the forward-compatible parsing rules to
assign fallback values, CSS renderers
must
treat as invalid (and
ignore
as appropriate
) any at-rules, properties, property values, keywords,
and other syntactic constructs for which they have no usable level of
support. In particular, user agents
must not
selectively
ignore unsupported component values and honor supported values in a single
multi-value property declaration: if any value is considered invalid
(as unsupported values must be), CSS requires that the entire declaration
be ignored.
Implementations of Unstable and Proprietary Features
To avoid clashes with future stable CSS features,
the CSSWG recommends
following best practices
for the implementation of
unstable
features and
proprietary extensions
to CSS.
Non-experimental implementations
Once a specification reaches the Candidate Recommendation stage,
non-experimental implementations are possible, and implementors should
release an unprefixed implementation of any CR-level feature they
can demonstrate to be correctly implemented according to spec.
To establish and maintain the interoperability of CSS across
implementations, the CSS Working Group requests that non-experimental
CSS renderers submit an implementation report (and, if necessary, the
testcases used for that implementation report) to the W3C before
releasing an unprefixed implementation of any CSS features. Testcases
submitted to W3C are subject to review and correction by the CSS
Working Group.
Further information on submitting testcases and implementation reports
can be found from on the CSS Working Group’s website at
Questions should be directed to the
public-css-testsuite@w3.org
mailing list.
Index
Terms defined by this specification
, in § 4.7
counter
, in § 4
counter()
, in § 4.7
counter-increment
, in § 4.2
, in § 4
value for counter-reset
, in § 4.1
value for counter-set, counter-increment
, in § 4.2
counter properties
, in § 4
counter-reset
, in § 4.1
counters()
, in § 4.7
counter scope
, in § 4.3
counter-set
, in § 4.2
, in § 3.4
creator
, in § 4
CSS counters set
, in § 4.4
, in § 3.3
inherit counters
, in § 4.4.1
innermost
, in § 4.4
inside
, in § 3.5
instantiate
, in § 4.4.2
instantiate counter
, in § 4.4.2
list item
, in § 2
list-item
, in § 4.6
list-style
, in § 3.6
list-style-image
, in § 3.3
list-style-position
, in § 3.5
list-style-type
, in § 3.4
marker
, in § 3
marker box
, in § 3
marker image
, in § 3.3
marker-side
, in § 3.7
marker string
, in § 3.4
match-parent
, in § 3.7
match-self
, in § 3.7
name
, in § 4
none
value for counter-reset
, in § 4.1
value for counter-set, counter-increment
, in § 4.2
value for list-style-image
, in § 3.3
value for list-style-type
, in § 3.4
outside
, in § 3.5
reversed
, in § 4
, in § 4
, in § 4.1
scope
, in § 4.3
, in § 3.4
value
, in § 4
Terms defined by reference
[CSS-CASCADE-5]
defines the following terms:
author origin
computed value
inheritance
specified value
used value
user origin
user-agent origin
[CSS-CASCADE-6]
defines the following terms:
cascade
[CSS-COLOR-4]
defines the following terms:
color
[CSS-CONTENT-3]
defines the following terms:
content
none
normal
[CSS-COUNTER-STYLES-3]
defines the following terms:
counter style
decimal
disc
generate a counter representation
prefix
suffix
[CSS-DISPLAY-4]
defines the following terms:
anonymous
block container
display
display type
hidden
inline
inline box
inline-level
list-item
none
order
outer display type
principal box
replaced element
text sequence
visibility
[CSS-IMAGES-3]
defines the following terms:
default object size
default sizing algorithm
specified size
[CSS-IMAGES-4]
defines the following terms:
valid image
[CSS-OVERFLOW-3]
defines the following terms:
overflow
visible
[CSS-POSITION-3]
defines the following terms:
position
[CSS-PSEUDO-4]
defines the following terms:
::after
::before
::marker
[CSS-SYNTAX-3]
defines the following terms:
invalid
[CSS-TEXT-4]
defines the following terms:
forced line break
letter-spacing
text-transform
white-space
white-space-collapse
white-space-trim
word-spacing
[CSS-VALUES-4]
defines the following terms:
calc()
CSS-wide keywords
functional notation
||
[CSS-VARIABLES-2]
defines the following terms:
custom property
[CSS-WRITING-MODES-3]
defines the following terms:
direction
unicode-bidi
[CSS-WRITING-MODES-4]
defines the following terms:
inline-start
text-combine-upright
writing mode
[DOM]
defines the following terms:
root
tree order
[HTML]
defines the following terms:
li
ol
option
ul
[INFRA]
defines the following terms:
append
contain
for each
remove
set
string
tuple
[SELECTORS-4]
defines the following terms:
compound selector
originating element
pseudo-elements
selector
[SVG2]
defines the following terms:
rect
References
Normative References
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr..
CSS Cascading and Inheritance Level 5
. URL:
[CSS-CASCADE-6]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr..
CSS Cascading and Inheritance Level 6
. URL:
[CSS-CONTENT-3]
Elika Etemad; Mike Bremford.
CSS Generated Content Module Level 3
. URL:
[CSS-COUNTER-STYLES-3]
Tab Atkins Jr..
CSS Counter Styles Level 3
. URL:
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr..
CSS Display Module Level 4
. URL:
[CSS-IMAGES-3]
Tab Atkins Jr.; Elika Etemad; Lea Verou.
CSS Images Module Level 3
. URL:
[CSS-IMAGES-4]
Elika Etemad; Tab Atkins Jr.; Lea Verou.
CSS Images Module Level 4
. URL:
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal.
CSS Overflow Module Level 3
. URL:
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr..
CSS Positioned Layout Module Level 3
. URL:
[CSS-PSEUDO-4]
Elika Etemad; Alan Stearns.
CSS Pseudo-Elements Module Level 4
. URL:
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin.
CSS Syntax Module Level 3
. URL:
[CSS-TEXT-4]
Elika Etemad; et al.
CSS Text Module Level 4
. URL:
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad.
CSS Values and Units Module Level 3
. URL:
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad.
CSS Values and Units Module Level 4
. URL:
[CSS-VARIABLES-2]
CSS Custom Properties for Cascading Variables Module Level 2
. Editor's Draft. URL:
[CSS-WRITING-MODES-3]
Elika Etemad; Koji Ishii.
CSS Writing Modes Level 3
. URL:
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii.
CSS Writing Modes Level 4
. URL:
[CSS2]
Bert Bos; et al.
Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification
. URL:
[DOM]
Anne van Kesteren.
DOM Standard
. Living Standard. URL:
[HTML]
Anne van Kesteren; et al.
HTML Standard
. Living Standard. URL:
[INFRA]
Anne van Kesteren; Domenic Denicola.
Infra Standard
. Living Standard. URL:
[RFC2119]
S. Bradner.
Key words for use in RFCs to Indicate Requirement Levels
. March 1997. Best Current Practice. URL:
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr..
Selectors Level 4
. URL:
[SVG2]
Amelia Bellamy-Royds; et al.
Scalable Vector Graphics (SVG) 2
. URL:
Non-Normative References
[CSS-ANIMATIONS-1]
David Baron; et al.
CSS Animations Level 1
. URL:
[CSS-CASCADE-4]
Elika Etemad; Tab Atkins Jr..
CSS Cascading and Inheritance Level 4
. URL:
[CSS-COLOR-3]
Tantek Çelik; Chris Lilley; David Baron.
CSS Color Module Level 3
. URL:
[CSS-COLOR-4]
Tab Atkins Jr.; Chris Lilley; Lea Verou.
CSS Color Module Level 4
. URL:
[CSS-DISPLAY-3]
Elika Etemad; Tab Atkins Jr..
CSS Display Module Level 3
. URL:
[CSS-FONTS-3]
John Daggett; Myles Maxfield; Chris Lilley.
CSS Fonts Module Level 3
. URL:
[CSS-TEXT-3]
Elika Etemad; Koji Ishii; Florian Rivoal.
CSS Text Module Level 3
. URL:
[CSS-TRANSITIONS-1]
Chris Marrin; et al.
CSS Transitions Module Level 1
. URL:
Property Index
Name
Value
Initial
Applies to
Inh.
%ages
Animation type
Canonical order
Computed value
counter-increment
[
none
all elements
no
n/a
by computed value type
per grammar
the keyword none or a list, each item an identifier paired with an integer
counter-reset
[
none
all elements
no
n/a
by computed value type
per grammar
the keyword none or a list, each item an identifier or a reversed() function paired with an integer
counter-set
[
none
all elements
no
n/a
by computed value type
per grammar
the keyword none or a list, each item an identifier paired with an integer
list-style
<'list-style-position'> || <'list-style-image'> || <'list-style-type'>
see individual properties
list items
see individual properties
see individual properties
see individual properties
per grammar
see individual properties
list-style-image
none
list items
yes
n/a
discrete
per grammar
the keyword noneor the computed
list-style-position
inside | outside
outside
list items
yes
n/a
discrete
per grammar
keyword, but see prose
list-style-type
disc
list items
yes
n/a
discrete
per grammar
specified value
marker-side
match-self | match-parent
match-self
list items
yes
n/a
discrete
per grammar
specified keyword
Issues Index
white-space: pre
doesn’t have quite the right behavior;
white-space-collapse: preserve-spaces
white-space-trim: discard-after
might be closer to what’s needed here.
See discussion in
Issue 4448
and
Issue 4891
This is handwavey nonsense from CSS2, and needs a real definition.
Alternatively,
outside
could lay out the marker as a previous sibling of the principal inline box.
For this order punctuation inside the marker correctly,
it would also need to take the
direction
value of the parent.
[Issue #4202]
There are issues open on
renaming the keywords
and on
merging with
list-style-position
Counters are sometimes useful for things other than printing markers.
In general, they provide the ability to number elements in sequence,
which can be useful for other properties to reference.
For example, using
order
to put an element between two other specific elements
currently requires you to explicitly put
order
on every element before and/or after the desired insertion point.
If you can set the
order
value of everything to a counter though,
you can more easily insert an element into an arbitrary spot between two others.
Other use-cases involve nested or sibling elements with transforms that are meant to be slightly different from each other.
Today you have to use a preprocessor to do this in a reasonable way,
but a counter would make it work well in "plain" CSS.
(You can built up successive values in the nested case today
by using
custom properties
and stacking up nested
calc()
s,
but this is a *little bit* clumsy,
and doesn’t work for siblings.)
Suggestion is to add a
counter-value(
function,
which returns the value of the named counter as an integer,
rather than returning a string.
See
Issue 1026
MDN
counter-increment
In all current engines.
Firefox
1+
Safari
3+
Chrome
2+
Opera
9.2+
Edge
79+
Edge (Legacy)
12+
IE
8+
Firefox for Android
25+
iOS Safari
1+
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
10.1+
MDN
counter-reset
In all current engines.
Firefox
1+
Safari
3+
Chrome
2+
Opera
9.2+
Edge
79+
Edge (Legacy)
12+
IE
8+
Firefox for Android
25+
iOS Safari
1+
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
10.1+
MDN
counter-set
Firefox
68+
Safari
None
Chrome
85+
Opera
Edge
85+
Edge (Legacy)
IE
None
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
MDN
list-style-image
In all current engines.
Firefox
1+
Safari
1+
Chrome
1+
Opera
7+
Edge
79+
Edge (Legacy)
12+
IE
4+
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
10.1+
MDN
list-style-position
In all current engines.
Firefox
1+
Safari
1+
Chrome
1+
Opera
3.5+
Edge
79+
Edge (Legacy)
12+
IE
4+
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
37+
Samsung Internet
Opera Mobile
MDN
list-style-type
In all current engines.
Firefox
1+
Safari
1+
Chrome
1+
Opera
3.5+
Edge
79+
Edge (Legacy)
12+
IE
4+
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
37+
Samsung Internet
Opera Mobile
10.1+
MDN
list-style
In all current engines.
Firefox
1+
Safari
1+
Chrome
1+
Opera
7+
Edge
79+
Edge (Legacy)
12+
IE
4+
Firefox for Android
iOS Safari
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
10.1+
MDN
counter
In all current engines.
Firefox
1+
Safari
3+
Chrome
1+
Opera
9.2+
Edge
79+
Edge (Legacy)
12+
IE
8+
Firefox for Android
iOS Safari
1+
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
10.1+
counters
In all current engines.
Firefox
1.5+
Safari
3+
Chrome
1+
Opera
10+
Edge
79+
Edge (Legacy)
12+
IE
8+
Firefox for Android
iOS Safari
1+
Chrome for Android
Android WebView
Samsung Internet
Opera Mobile
10.1+