Styling vertical Chinese, Japanese, Korean and Mongolian text

Intended audience: CSS developers, and anyone who needs guidance on how to produce vertically-oriented text for Chinese, Japanese and Korean using CSS. This article explains how to use CSS to produce vertical text for languages such as Chinese, Japanese, Korean, and Mongolian. The CSS specification contains a lot of implementation-specific information. This article draws out the basic information that content authors need to create the more common features of vertical text. It also compares the theory and practice about what is possible. Each section explains how you would mark up up your content according to the CSS spec (which is usually simple and straightforward), but then looks at what you currently have to do to achieve the same result in browsers that don't implement the standard property and value names. For more information, see Browser support.

Basic setup Where it is supported, most of what you need should be achievable by applying the writing-mode property to the content that you want to be set vertically. In Japanese, Chinese and Korean, lines start at the right side of the figure box and progress to the left. Latin script text typically runs down the page, with the letters rotated clockwise, while the Han characters remain upright. Any graphic also remains upright. Chinese and Japanese vertical text lines run right to left. This example shows vertical Japanese text. To produce the Japanese example above we would use the following CSS on a block element that contains the text (in this case a div ). div { writing-mode: vertical-rl; } proprietary syntax Test in your browser: standard syntax For Webkit-based browsers you currently need to use the proprietary -webkit-writing-mode property. IE requires -ms-writing-mode , but in addition requires the deprecated value rl-tb . That value can be used with the unprefixed writing-mode property in IE, but -ms-writing-mode was introduced in mid 2014 to improve the behaviour of nested properties in IE. See test results for major browsers. In Mongolian the lines start at the left side of the containing box and progress to the right. The Latin script text still runs down the page, with the letters rotated clockwise, and the Mongolian characters display as expected. Mongolian lines run left to right. For Mongolian, use: div { writing-mode: vertical-lr; } proprietary syntax Test in your browser: standard syntax Webkit doesn't correctly display the Mongolian text. Glyphs are rotated anti-clockwise away from the correct orientation, and don't join. If you embed a right-to-left script in the text, such as Arabic or Hebrew, it will run from bottom to top along the line, and the top of the letters will be to the right. This is analogous to what happens in horizontal text. Arabic text embedded in vertical Chinese. proprietary syntax Test in your browser: standard syntax In Trident (Internet Explorer), the addition of the dir attribute in vertical text causes the space where the text should appear to go blank. Other values of writing-mode In addition to horizontal-tb , which is the normal setting for horizontal text, there are two other property values for writing-mode , which are primarily intended for use with scripts which are normally horizontal but that are being used vertically for captions, table headers, UI elements, and so forth. They may only rarely be useful for vertical Chinese, Japanese, or Korean, and are unlikely to be useful at all for Mongolian. The value sideways-rl makes all characters to which it is applied lie on their right side, including Han characters. The text runs from top to bottom, and lines progress from right to left. Text set with the property sideways-rl . proprietary syntax Test in your browser: standard syntax The sideways-lr value makes all characters lie on their left side. Left-to-right text starts at the bottom of the line, and lines progress from left to right. Text set with the property sideways-lr . proprietary syntax Test in your browser: standard syntax The vertical- values of writing-mode are really intended for use in setting a normal vertical context for CJK or Mongolian text. On the other hand, if your content is in English and you want some title text to run from bottom to top vertically, say on a book spine or in table header, you would use writing-mode:sideways-lr, not one of the vertical- values. (To make Arabic script text run up the page, you'd use sideways-rl .)

Changing the glyph orientation for embedded text Default character orientation In vertical text, certain characters are normally upright and others are normally rotated sideways. The Unicode Standard assigns a property to each character and browsers can use this to determine the default orientation of a given character. For example, ordinary number digits in vertical text lie on their side by default, whereas fullwidth digits and enclosed alphanumerics, such as ①, are upright by default. In some cases, rotation may also involve a transformation of a character – for example (vertical) vs. (horizontal). This change requires more than simple rotation, and you will need to use a font that supports the alternative glyphs. Occasionally you may come across situations where the browser doesn't support the expected default behavior, or the default is different according to the language of the text. However, most of the time, the browser will automatically do what you expect, on a per character basis. For Japanese there are currently ongoing investigations into what does and doesn't currently work well. (See for example Kadokawa and Denshalab.) For those situations where you may want to do something different from the default, the sections that follow will examine how to influence the rotation of characters. Keeping embedded Latin text upright Sometimes you may want to show embedded Latin letters standing upright, rather than running down the page, particularly for initialisms. Currently there are a number of ways of achieving this, but all have pros and cons. Using dedicated CSS. One alternative is to apply the text-orientation property. Note how the letter i is upright in the following example. Upright Latin text in vertical Japanese. If you want to restyle characters so that they stand upright, use markup such as span or abbr to identify the relevant text so that you can apply a CSS property. In the examples below we put the Latin text in a span with a class name upright . <p>『<span class="upright">i</span>』は、浅䈡の双子の兄であり、共犯者だ。</p> To make the letter i upright, you would then use this CSS declaration: .upright { text-orientation: upright; } proprietary syntax Test in your browser: standard syntax For Webkit-based browsers you need to use the proprietary -webkit-text-orientation property. However, Webkit seems to have a problem centering the letter in the vertical line. This option doesn't convert any characters to fullwidth. If you need to do so, you could apply additional CSS for that, if the browser supports it (see the next subsection). Full-width transforms. If you transform the text into fullwidth characters, that may actually be sufficient on its own, since fullwidth characters are displayed upright by default. Using a fullwidth transform to make Latin letters stand upright. The letters 'W3C' in the above example initially ran down the page, but applying the fullwidth transform using the following CSS makes them stand upright. .upright { text-transform: full-width; } proprietary syntax Test in your browser: standard syntax This is appropriate for initialisms, but is not necessarily useful for all types of upright text, and note especially that this technique only works for Latin characters without accents! text-transform: full-width currently only works in Gecko. Text in other scripts will not have full-width equivalents, and so will need to use the next approach. Using full-width characters. Another way to achieve this is to just use fullwidth characters, such as Ｗ３Ｃ. These will automatically be displayed upright by default. You don't need any markup in this case. Of course, this also only works for Latin script text that doesn't include accents (since those are the only letters for which full-width variants exist). Upright Latin text produced by using fullwidth characters. proprietary syntax Test in your browser: standard syntax Embedding other languages upright Mixtures of vertical Chinese, Japanese, Korean and Mongolian text should just work as expected, but for other non-Latin scripts and Latin text with accents you will need to use the text-orientation property to make the text stand upright. If the Latin text contains accents or diacritics as separate characters alongside their base character, you should not see the combining characters on separate lines. However, there are some scripts that present additional issues, although it should be said that these non-Latin scripts don't seem to be set upright often. Expected rendering of Uighur words, devanagari syllables, and Latin characters with separate combining characters when set upright. proprietary syntax Test in your browser: standard syntax Embedded Arabic script text (shown in the two right-most lines above) is usually joined up. It is not possible to join Arabic characters when they are displayed upright, so isolated forms should be used. In addition, the order of characters is top to bottom when written upright, whereas Arabic script text that is rotated clockwise is read from bottom to top (because it is right-to-left). Webkit and Blink browsers produce isolated Arabic letters correctly, but incorrectly order the glyphs from bottom to top within each word. Some complex scripts, such as Devanagari (used for Hindi, and shown in the two left-most lines above) require upright text to be split at syllable boundaries. Such syllables are currently not handled well by browsers in upright text runs. None of the browser engines that support upright orientation of characters do well with Hindi. Many, if not all, combining characters appear on separate lines. Webkit does combine some consonant clusters, but still has problems with spacing combining characters. In Gecko and Blink browsers the indic script text also has large gaps between characters and runs outside the box it is displayed in.

The sideways value of text-orientation CSS provides one more value of the text-orientation property: sideways . This value only works if you have also applied the values of writing-mode that begin with vertical- . This value of text-orientation makes all characters lie on their right side, including Han characters. The result of using this value with with writing-mode:vertical-rl is different from that seen when using writing-mode:sideways-lr since the text starts at the top of the block and glyphs lie on their right side. The result of using text-orientation:sideways with writing-mode:vertical-lr . proprietary syntax Test in your browser: standard syntax It is more likely that you will want to use the sideways-rl and sideways-lr values of writing-mode (see above) to render text sideways. For Webkit browsers you need to use the prefixed property name, ie. -webkit-text-orientation: sideways .

Horizontal-in-vertical text It is common for short numbers of 2-3 digits (sometimes 4) and occasionally other runs of text, to run horizontally within the vertical flow. In Japanese this is called tate chū yoko. See the month and day digits in this example. Tate chū yoko applied to 2-digit numbers. Making inline digits run horizontally The easiest way to apply this to numeric digits is to use text-combine-upright with a digits x value. Gecko, Webkit and Blink browsers do not yet support this property for the digits value. In Internet Explorer and Edge this property is called -ms-text-combine-horizontal . It works in Edge, but unlike other browsers stretches any single character to the width of the line. Internet Explorer doesn't appear to be able to pick the digits out of a sequence of characters when using the digits value. It makes all the content of the element horizontal (see the demos). It only works for digits in the ASCII range, and full-width Unicode codepoints are automatically converted to ASCII codepoints during the process. It doesn't work for other numbering systems, such as Arabic, Bengali, etc. Let's suppose we have some HTML markup like the following, where the date 2015年5月22日 is inside a time element. <p>今日は<time datetime="2016-05-22">2015年5月22日</time>です。</p> We can reproduce the rendering seen in the above example using the following CSS. time { text-combine-upright: digits 2; } proprietary syntax Test in your browser: standard syntax This makes any double-digit numbers in the text run horizontally, but doesn't affect anything else. Note that you get the same effect by omitting the number after digits . To fit longer numbers horizontally, change the number after digits . In the previous example 2015 is not horizontal. You could make it horizontal using text-combine-upright:digits 4 . Then any numeric sequence up to four digits long will be horizontal. Four is the maximum number of digits you can layout horizontally in vertical text using this style. Tate chu yoko applied to all numbers of 4 digits or less. proprietary syntax Test in your browser: standard syntax If you'd like the unaffected numbers to be full-width, you can use the following styling. Full-width characters are displayed upright by default. time { text-combine- upright : digits 2; text-transform: full-width; } proprietary syntax Test in your browser: standard syntax Fullwidth transform applied to non-affected digits. Use dedicated markup where possible. For example, for dates and times, you could just apply the style to the time element. You can set this style on block elements such as p or section and the style will only be applied to runs of numbers. Be aware, however, that you may need to correct the behavior if you set text-combine-upright for a whole paragraph or more if that content contains numbers like 10,000, since the comma interrupts the sequence of digits; the result will be 10 set horizontally, and ,000 set running down the page. Making non-digit inline text run horizontally If you want to apply horizontal layout to non-digit text, you have to use text-combine-upright:all and surround the text you want to be horizontal with markup. You can still use the digits value for the numbers, but you'll need to use all for the other stuff. (Assuming that you are using the -ms-text-combine-horizontal property name for Edge and IE.) For example, given some content marked up as follows <p>...是有<span class="tcy">5012</span><span class="tcy">GI</span>的話、...</p> we can produce the desired effect with the following CSS. .tcy { text-combine-upright: all; } proprietary syntax Test in your browser: standard syntax Note how we used two spans , in order to clearly indicate the boundaries of the horizontal text. Tate chu yoko applied to other types of text. The browser will try to squeeze the horizontal text into the width of a single character, so don't be too ambitious about how many characters you do this to. It is likely to be hard to read if you have more than three characters side-by-side. Preventing inline text from running horizontally Suppose you applied the digits styling to a whole section, and there's a number 10,000 in that section that you don't want to be affected. You can use the none value for that. For example you could surround the number with a span with a class such as no-tcy that has the following styling. .no-tcy { text-combine-upright: none; } proprietary syntax Test in your browser: standard syntax See the result in the figure below, where the right hand side shows before, and the left, after. Text with text-combine-upright set to digits at the paragraph level. Corrected on the left by applying text-combine-upright:none to the number. Choosing a font for horizontal inline text The browser will try to use special narrow variants of the horizontal characters if they are included in the font being used (eg. OpenType's hwid and twid ). After trying that, it will compress the glyphs to fit them in the space available. The former approach will produce a much nicer result, especially at larger sizes, therefore, it's worth using a font that has those extra glyphs (many do).

Using logical dimensions You may decide that you want to align text along the left edge in horizontal text. Scripts like Arabic, Hebrew, and Thaana tend to mirror-image horizontal text, so where you would apply left text alignment to English text, you would apply right alignment to text in those scripts. How does it work, then, if you want to apply a vertical writing mode to that text? A great deal of time and confusion can be saved by using 'logical' properties, rather than right, left, top and bottom, for things such as alignment. CSS is developing the necessary keywords in the Logical Properties specification, which at the time of writing is still an editor's draft. Some of the properties described there, however, are already supported by browsers. To go back to our example of text alignment, let's suppose that we want text to be right-aligned for horizontal left-to-right text, left-aligned for paragraphs of right-to-left text, such as Arabic, and bottom-aligned for vertically set text. We can achieve all those with a single keyword: text-align:end will produce the effect you need based on the direction of the content. To align in the other direction, use the value start . Take a look at the following three boxes. We applied dir="rtl" to the Arabic one, and writing-mode:vertical-rl to the Japanese one. In our CSS we have aligned them all using text-align:end . text-align:end takes into account the writing-mode of the text. proprietary syntax Test in your browser: standard syntax The new keywords being defined in the specification allow you not only to align things to one or other end of a line, but to align things relative to the containing box in a logical way. You will also be able to do other things, such as position and float items logically too. Unfortunately, Microsoft Edge still doesn't support the start and end values for text-align . The other values described in the Logical Properties are also likely to be poorly supported at the moment, but it's worth watching out for them as they become usable.