How to make list markers stand upright in vertical text

This page has been substatively changed since the start of the review period.

In Chinese, Japanese, Korean, and Mongolian vertically-set text it is normal for list counters to sit upright above the start of the list.

Picture of a vertical list in Japanese with numeric counters. Picture of a vertical list in Mongolian with numeric counters.

Until recently this was problematic, because browsers would only show the numbers lying on their side. This article describes how to make them stand upright as shown in the picture above, and the currently remaining issues.

Details

We'll look at three alternative approaches, one of which works across all major browser engines, another which doesn't currently work with WebKit browsers, and a third that doesn't yet work with any major browser.

Use counter-styles & upright characters

The simplest approach is to use counters that are always upright in vertical text.

Customised counter-styles are now supported by all major browser engines. This therefore provides an opportunity that will lead to an interoperable solution.

First, you need to create an @counter-style declaration in your CSS. We suggest a circled decimal style below, but as these are customisable you can also make up your own.

@counter-style circled-decimal { 
system: fixed 0;
symbols: '\24EA' '\2460' '\2461' '\2462' '\2463' '\2464' '\2465' '\2466' '\2467' '\2468' '\2469' '\246A' '\246B' '\246C' '\246D' '\246E' '\246F' '\2470' '\2471' '\2472' '\2473' '\3251' '\3252' '\3253' '\3254' '\3255' '\3256' '\3257' '\3258' '\3259' '\325a' '\325b' '\325c' '\325d' '\325e' '\325f' '\32b1' '\32b2' '\32b3' '\32b4' '\32b5' '\32b6' '\32b7' '\32b8' '\32b9' '\32ba' '\32bb' '\32bc' '\32bd' '\32be' '\32bf';
/* symbols: '⓪' '①' '②' '③' '④' '⑤' '⑥' '⑦' '⑧' '⑨' '⑩' '⑪' '⑫' '⑬' '⑭' '⑮' '⑯' '⑰' '⑱' '⑲' '⑳' '㉑' '㉒' '㉓' '㉔' '㉕' '㉖' '㉗' '㉘' '㉙' '㉚' '㉛' '㉜' '㉝' '㉞' '㉟' '㊱' '㊲' '㊳' '㊴' '㊵' '㊶' '㊷' '㊸' '㊹' '㊺' '㊻' '㊼' '㊽' '㊾' '㊿'; */
suffix: '';
}

This counter style definition is taken from Ready-made Counter Styles, where you can find several alternative styles that may be of interest. The suffix is still specified, to avoid the default full stop appearing, but is reduced to a null string to avoid harmful effects on the horizontal positioning.

Note that this particular counter style is of the “fixed” type. This means that it only supports lists containing up to 50 items. Other similar styles may support fewer counters. This is probably not problematic for most lists in vertical text.

Once you have added this counter-style definition to your CSS, then tie it to your list using CSS code such as the following. You can, of course, add a class name or context to your element selector, if you want to apply the style to just certain lists.

li { list-style-type: circled-decimal; }

Output in your browser:

  1. 仕込む前に生芋を1/4ぐらいの大きさにカット。
  2. すり潰した生芋
  3. ながらのパケット式の定量練り、通称バタ練り機

Styling the counter using ::marker

Many horizontal counter styles use simple digits or alphabetic characters as counters, but in vertical text this will result in a counter lying on its side. Here we look at how to prevent that, using ordinary decimal counters. This would enable you to have lists longer than those described above, but it's necessary to take one or two extra steps to ensure that the counter is upright and is properly centred above the vertical line.

For this approach we use the following CSS.


@counter-style upright-decimal {
	system: extends decimal;
	suffix: '';
	}

li {
	list-style-type: upright-decimal;
	}

li::marker {
	text-combine-upright: all;
	}

We use a counter-style rule to remove the dot and space that follow decimal counters by default. (To make the counter look like "1.", "2,", etc. just set the suffix to ".".) We then use CSS's ::marker pseudo-element to make the counter stand upright above the line.

Here's the result in your browser. It works in Blink and Gecko browsers, but it doesn't work at all in WebKit browsers, so it's not a fully interoperable solution (at least not yet).

Output in your browser:

  1. 仕込む前に生芋を1/4ぐらいの大きさにカット。
  2. すり潰した生芋
  3. ながらのパケット式の定量練り、通称バタ練り機

The example above shows the basic mechanics, but it could do with some additional styling to look right.

Using more CSS to tweak the presentation

Both types of list described above can benefit from additional styling. For example, using the following CSS we can make the markers in the example just above slightly bigger, and coloured, and we can create an appropriately sized gap between the counter and the list text. (Some of these things are slightly unusual, but they serve as a demonstration of what's possible.)

We'll also change the counter to have parentheses around it. Note how the browser squeezes the result to fit within a line.


@counter-style upright-parens {
	system: extends decimal;
	prefix: '('; suffix: ')';
	}

li { 
    list-style-type: upright-parens;
    padding-inline-start: .4em;
    }

li::marker {
    text-combine-upright: all;
    color: red;
    font-size: 1.2em;
    }

Output in your browser:

  1. 仕込む前に生芋を1/4ぐらいの大きさにカット。
  2. すり潰した生芋
  3. ながらのパケット式の定量練り、通称バタ練り機

The CSS ::marker pseudo-element allows you to apply the following adjustments:

  1. all font properties
  2. the white-space property
  3. color
  4. text-combine-upright, unicode-bidi, and direction
  5. the content property
  6. all animation and transition properties

Mixing vertical & horizontal in markers

Another common style of counters looks like the following.

Picture of a vertical list in Japanese with numeric counters that have rotated parentheses above and below.

The basic principle for creating this style is the same as previously described, but with a twist, because we need to allow the parentheses to rotate but keep the digit(s) upright.

In theory, we just need to use a different value for text-combine-upright.


@counter-style upright-decimal {
	system: extends decimal;  /* same as before */
	suffix: '';
	}

li {
	list-style-type: upright-parens; /* same as before */
	}

li::marker {
	text-combine-upright: digits; /* changed */
	}

The digits value seeks out digits within a string and makes them horizontal while leaving the surrounding text vertical. (The syntax shown should work for any 2-digit number. If you ever need to go higher than that, just use digits 4 to allow for numbers up to 9,999.)

Unfortunately, this is only a theoretical solution for the time being, because no browser yet supports the digits value.