Fonts and text styling
A page is mostly letters, and how they look decides whether people read it. This lesson covers the font properties (which font, how big, how heavy, which features), the text properties (alignment, lines, spacing, wrapping, direction) and the web font element, with examples you can run and a short guide for Persian and Arabic text.
- Choosing a font
- Size
- Weight, style and width
- Web fonts
- Features, variants and variable fonts
- Aligning and transforming text
- Lines, shadows and outlines
- Line height and spacing
- Wrapping and cutting
- Direction and vertical text
- Ruby and emphasis marks
- Persian and Arabic text
- Reference: every font and text property
- Try it yourself
Choosing a font
You cannot know which fonts a visitor has installed. font family therefore takes a list, called a font stack: the browser tries the names from left to right and uses the first font that exists and has the letters it needs to draw. A name that contains spaces goes in single quotes inside the string. The last name should be a generic family, which every browser can always fill: serif (letters with small feet), sans-serif (without feet), monospace (equal width, for code), cursive and fantasy (decorative, and different on every system) and system-ui (the font of the operating system's own windows). ui-monospace is the system's code font.
page:
title = "Font stacks"
global: selector = "body" margin = "1.5rem" line height = 1.6 end
paragraph: font family = "Georgia, 'Times New Roman', serif" content = "Serif: Georgia, then Times New Roman, then any serif font." end
paragraph: font family = "system-ui, sans-serif" content = "Sans serif: the interface font of the system." end
paragraph: font family = "ui-monospace, Consolas, monospace" content = "Monospace: every letter is equally wide." end
paragraph: font family = "cursive" content = "Cursive: the look of handwriting." end
paragraph: font family = "NoSuchFont, serif" content = "The first name does not exist, so the browser takes the next." end
endLook at the last line of the preview. The first name does not exist, so the browser skips it silently and takes the next. This is also how a missing Persian glyph is handled: if the first font has no such letter, the browser asks the next font in the list for that single letter.
Put the rule on body with a global element, as the examples do, and every element inherits it. Only set font family on a single element when that element really needs a different font, such as code.
Size
font size accepts a bare number (pixels), or a string with a unit. The useful units are rem, which is relative to the font size of the whole page, em and %, which are relative to the parent element, and vw, which is a part of the window width. There are also keywords from xx-small to xx-large, and clamp(min, preferred, max), which grows with the window but never leaves the two limits. Prefer rem to pixels for text: people who raise the default size in their browser then get bigger text on your page too.
page:
title = "Font sizes"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
paragraph: font size = 12 content = "12 means 12px" end
paragraph: font size = 12 + 6 content = "An expression: 12 + 6 is 18px" end
paragraph: font size = "1.5rem" content = "1.5rem is one and a half root sizes" end
paragraph: font size = "150%" content = "150% of the parent size" end
paragraph: font size = "x-large" content = "The keyword x-large" end
paragraph: font size = "clamp(1rem, 4vw, 2rem)" content = "clamp() grows with the window, within limits" end
endThe second line is an expression. Any number or string that the compiler can compute is a valid value, so you can also use a constant declared above the page, such as font size = BASE * 2, and change one number to resize many elements.
Before the next sections, try the settings yourself. The slider and the list below run small functions that use the dom package, which is explained in its own page. Each time the slider moves, its function reads the value and sets the CSS property font-size of the sample. Inside such a function, CSS properties keep their original names with dashes.
import dom
page:
title = "Type tester"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
paragraph: id = "label" content = "Size: 28px" end
box: display = "flex" gap = 12
input: id = "size" type = "range" min = 12 max = 64 value = 28
input = ():
size := dom.GetValue(dom.ById("size"))
dom.SetStyle(dom.ById("sample"), "font-size", size + "px")
dom.SetText(dom.ById("label"), "Size: " + size + "px")
end
end
select: id = "family" change = (): dom.SetStyle(dom.ById("sample"), "font-family", dom.GetValue(dom.ById("family"))) end
option: value = "Georgia, serif" content = "Serif" end
option: value = "system-ui, sans-serif" content = "Sans serif" end
option: value = "ui-monospace, monospace" content = "Monospace" end
end
end
paragraph: id = "sample" font family = "Georgia, serif" font size = 28 content = "Sphinx of black quartz, judge my vow." end
endWeight, style and width
font weight is a number from 1 to 1000: 400 is normal text, 700 is bold. normal and bold are the same as 400 and 700, and bolder and lighter move one step away from the parent. A font file has only the weights its designer drew. If you ask for 300 and the font has 400 and 700, the browser shows 400, so in the preview below the first lines may look equal. font style chooses upright, italic (a separate design) or oblique (the upright letters leaned over). font stretch and its newer name font width choose narrower or wider designs and only matter for fonts that have them.
page:
title = "Weight, style and width"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" line height = 1.6 end
paragraph: font weight = 300 content = "Weight 300, light" end
paragraph: font weight = 400 content = "Weight 400, normal" end
paragraph: font weight = 700 content = "Weight 700, bold" end
paragraph: font weight = 900 content = "Weight 900, black" end
paragraph: font style = "italic" content = "Italic: the italic design of the font" end
paragraph: font style = "oblique" content = "Oblique: the upright letters slanted" end
paragraph: font stretch = "condensed" content = "Condensed, if the font has a narrow design" end
paragraph: font = "italic 700 1.25rem/1.4 Georgia, serif" content = "All of it in one shorthand" end
endThe last line uses the shorthand font. It sets style, weight, width, size, line height and family in one string, in this order, with the line height after a slash. Only the size and the family are required.
The shorthand font resets every property it does not mention. If you write font = "16px serif" after a font weight = 700 on the same element, the weight is back to 400. When you only want to change one thing, write that one property.
If a font has no bold or italic design, the browser fakes one by thickening or leaning the normal letters. The result is often a little ugly. font synthesis forbids this, and its parts font synthesis weight, font synthesis style, font synthesis small caps and font synthesis position forbid a single kind of faking.
Web fonts
To use a font that visitors do not have, ship the file with the page. The font element describes one file: name is the name you will use in font family, and url is the address of the file. Salam turns it into an @font-face rule, and the browser downloads the file only when some text uses the font. When one family has several files, write one font element per file with the same name and the weight or style that the file provides.
page:
title = "A web font"
font:
name = "Course Serif"
url = "/fonts/course-serif.woff2"
weight = 400
style = normal
display = swap
end
font:
name = "Course Serif"
url = "/fonts/course-serif-bold.woff2"
weight = 700
display = swap
end
global: selector = "body" font family = "'Course Serif', Georgia, serif" margin = "1.5rem" line height = 1.7 end
heading: size = 2 content = "Reading in comfort" end
paragraph: content = "The font files are not part of this preview, so the browser shows the next name in the stack." end
paragraph: font weight = 700 content = "This line asks for weight 700 and would use the second file." end
endThe two files of this example do not exist in the preview, so the page shows the next font of the stack. That is the right way to build a page: the fallback must always be good enough to read. On your own site, put the files in a folder that your server serves, and the page starts using them. Salam checks the address while compiling: an unsafe address is an error, and a relative file that cannot be found next to the program is a warning. If you leave out type, Salam finds out the format from the end of the address.
Three attributes shape the loading. display = swap shows the fallback font at once and swaps in the real one when it arrives, so the text is never invisible. range lists the Unicode ranges a file covers, so a Persian file is downloaded only by pages that contain Persian letters. weight can be a range such as "100 900" for a variable font.
Every font file is a download, and a page that waits for five of them feels slow. Use one or two families, only the weights you really use, and the woff2 format, which is the smallest. And check the licence: a font on your computer is not always a font you may publish.
Features, variants and variable fonts
A good font contains more than letters: small capitals, several kinds of digits, ligatures (shapes where two letters join, such as fi) and alternate forms. They are called OpenType features, and each has a four letter tag such as smcp or liga. The properties that start with font variant switch the common ones in words: font variant caps, font variant numeric, font variant ligatures, font variant position, font variant alternates, font variant east asian and font variant emoji. font feature settings is the raw version for the rest: "'smcp' 1" turns a feature on, and 0 turns it off. font kerning controls the pair spacing, which is on by default and should stay on.
page:
title = "Font variants"
global: selector = "body" font family = "Georgia, serif" margin = "1.5rem" line height = 1.8 end
paragraph: font variant caps = "small-caps" content = "Small capitals for a book title" end
paragraph: font variant numeric = "tabular-nums" content = "1111 and 8888 line up in tables" end
paragraph: font variant numeric = "oldstyle-nums" content = "Old style figures 2026 sit in the line" end
paragraph: font variant ligatures = "none" content = "office affinity: ligatures switched off" end
paragraph: font kerning = "none" content = "AVATAR WAVE: kerning switched off" end
paragraph: font feature settings = "'smcp' 1" content = "The same small capitals through the raw feature tag" end
paragraph: font variation settings = "'wght' 650" content = "A variable font reads this axis; others ignore it" end
endA variable font is one file that contains a whole range of designs along axes, such as weight (wght) or width (wdth). font variation settings sets the axes by their tag, and font optical sizing lets a font with an optical size axis change its shape with the text size. When an ordinary property exists, use it: font weight = 650 sets the weight axis and is easier to read. font palette picks one of the colour sets of a colour font.
Features only work if the font has them. A font without small capitals shows the normal letters or, in some browsers, faked ones, and a line in the preview above may look unchanged. Test with the font you really use.
Aligning and transforming text
text align places the lines of a block. Use start and end and not left and right: they follow the direction of the text, so the same rule is correct for English and for Persian. center centres every line and justify stretches every line but the last to the full width. text align last sets the last line separately, and text justify chooses whether the extra space goes between words or between letters. text indent pushes the first line in, the way books mark a new paragraph. text transform changes the case of the shown letters without changing the text, which is better than typing capitals because a screen reader and a search still see the real text.
page:
title = "Aligning text"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" line height = 1.6 end
box: text align = "start" content = "Start: the side where reading begins." border = "1px solid #cbd5e1" padding = 8 margin bottom = 8 end
box: text align = "center" content = "Center: lines in the middle." border = "1px solid #cbd5e1" padding = 8 margin bottom = 8 end
box: text align = "end" content = "End: the side where reading ends." border = "1px solid #cbd5e1" padding = 8 margin bottom = 8 end
box:
text align = "justify"
text align last = "center"
text indent = "2em"
border = "1px solid #cbd5e1"
padding = 8
margin bottom = 8
max width = 420
content = "Justified text stretches every line to the same width, and the last line can be placed on its own. The first line is indented by two letters."
end
box: text transform = "uppercase" content = "uppercase letters" end
box: text transform = "capitalize" content = "every word starts large" end
endJustified text needs wide lines. In a narrow column the gaps between words become large and uneven, so use justify only for wide blocks.
Lines, shadows and outlines
text decoration draws lines on text. It is a shorthand of four properties: text decoration line (underline, overline, line-through), text decoration style (solid, double, dotted, dashed, wavy), text decoration color and text decoration thickness. Two more properties tune underlines: text underline offset moves the line away from the letters, and text decoration skip ink decides if the line jumps over the tails of letters like g and y. text shadow adds one or more shadows, each as horizontal offset, vertical offset, blur and colour; two shadows of the same colour make a glow. webkit text stroke and webkit text fill color outline letters; the name starts with webkit because browsers adopted the idea under that prefix, and all of them still use it.
page:
title = "Decoration and shadow"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" line height = 1.8 font size = 20 end
paragraph: text decoration line = "underline" text decoration style = "wavy" text decoration color = "crimson" text decoration thickness = 2 content = "A red wavy underline" end
paragraph: text decoration line = "underline" text underline offset = 6 text decoration skip ink = "none" content = "An underline moved down from the letters" end
paragraph: text decoration = "line-through 2px #64748b" content = "Crossed out in one shorthand" end
paragraph: text decoration line = "overline underline" text decoration style = "double" content = "A line above and a double line below" end
paragraph: text shadow = "2px 2px 4px #94a3b8" font size = 32 font weight = 700 content = "Soft shadow" end
paragraph: text shadow = "0 0 8px #38bdf8, 0 0 16px #0ea5e9" color = "white" background = "#0f172a" padding = 8 content = "A glow made of two shadows" end
paragraph: webkit text stroke = "1px #0f172a" webkit text fill color = "transparent" font size = 40 font weight = 700 content = "Outline" end
endPeople expect an underline to mean a link. Do not underline other text, and do not remove the underline of real links without another clear sign, such as a different colour plus a weight. Shadows and outlines also reduce contrast, so check that the text stays readable.
Line height and spacing
line height is the most important property for reading. Give it a plain number, without a unit: 1.6 means 1.6 times the font size of that element, and a child with a larger size gets a larger line height by itself. A length such as "24px" is passed to the children as a fixed result and makes big headings overlap. Around 1.5 suits English, and Persian needs about 1.9 because of its dots and marks above and below the line. letter spacing and word spacing add space between letters and between words. A small positive letter spacing is good for capitals, and a tiny negative one for very large headings. vertical align moves an inline element up or down within the line, as super and sub do for powers and indices. tab size sets the width of a tab character in preformatted text.
page:
title = "Spacing"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box: width = 300 line height = 1 background = "#f1f5f9" margin bottom = 12 content = "line height 1: the lines of this paragraph are packed tightly together." end
box: width = 300 line height = 1.6 background = "#f1f5f9" margin bottom = 12 content = "line height 1.6: comfortable for reading long text in a paragraph." end
box: width = 300 line height = 2.2 background = "#f1f5f9" margin bottom = 12 content = "line height 2.2: so open that the lines start to fall apart." end
box: letter spacing = "0.25em" text transform = "uppercase" font size = 14 margin bottom = 12 content = "Letter spacing for a label" end
box: word spacing = "0.5em" content = "Words spread apart by half a letter" end
endDo not use letter spacing on Persian or Arabic. The letters of these scripts are joined, and a gap between them cuts the word into pieces. Browsers treat it differently, and where a gap is added it cuts the word apart, so the safe value is always 0 or nothing.
Wrapping and cutting
Normally the browser breaks a line at spaces. white space changes this: nowrap never breaks, pre keeps the text as typed, pre-wrap keeps it and still wraps, and pre-line keeps only the line breaks. white space collapse is the "what happens to spaces" half of it. When a single word is longer than its box, overflow wrap = "anywhere" lets it break so it does not stick out of the page, which is exactly what a long web address needs. word break = "break-all" breaks everywhere, even where the word would fit, and keep-all is for Chinese, Japanese and Korean, where it forbids breaks inside a word. hyphens = "auto" hyphenates words in languages the browser has a dictionary for, if the element has the right lang. text wrap = "balance" evens out the lines of a short heading, and pretty avoids a last line with one short word.
page:
title = "Wrapping long text"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box: width = 180 white space = "nowrap" overflow = "hidden" text overflow = "ellipsis" background = "#f1f5f9" margin bottom = 12 content = "This sentence is far too long for its box" end
box: width = 180 overflow wrap = "anywhere" background = "#e0f2fe" margin bottom = 12 content = "https://example.com/a/very/long/address/that-does-not-fit" end
box: width = 180 word break = "break-all" background = "#fef9c3" margin bottom = 12 content = "Break-all cuts at any letter, even in short words." end
box: width = 180 hyphens = "auto" lang = "en" background = "#dcfce7" margin bottom = 12 content = "Hyphenation helps incomprehensibilities fit narrow columns." end
box: width = 180 white space = "pre-line" background = "#fae8ff" content = "Line breaks in the source\nare kept\nwith pre-line." end
endTo show only the first lines of a long text, you have two tools. text overflow = "ellipsis" replaces the cut-off end of one line with an ellipsis, and line clamp limits a block to a number of lines. Both are new or fussy, so build the example below the way it is written: with a max height and overflow = "hidden" as a safety net that works everywhere.
page:
title = "Clamping lines"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box:
width = 260
line height = 1.5
line clamp = 3
overflow = "hidden"
max height = "4.5em"
background = "#f1f5f9"
padding = "0 10"
content = "A card preview shows only the first lines of a long text, so every card in a list keeps the same height, however much the author wrote. Everything after the third line is cut off here."
end
heading: size = 3 text wrap = "balance" max width = 260 content = "A long headline that is split into two lines of similar length" end
endtext overflow does nothing alone. It needs three properties together: overflow (anything but visible), white space = "nowrap" and a limited width. If you see no ellipsis, one of the three is missing.
Direction and vertical text
direction chooses ltr or rtl for the text of an element. In practice you set the direction with the dir attribute (see the lesson on the head and global attributes) because it tells screen readers too, and use the CSS property only for a rule that applies to many elements. unicode bidi controls how text of mixed directions is ordered, and bidi-override forces the order whatever the letters are; the elements isolate and direction override in the lesson on text elements do the same job.
writing mode goes further and turns the lines themselves: vertical-rl writes down the page and stacks the lines from right to left, as in Japanese and Chinese. text orientation decides whether the letters of other scripts stand up or lie down, and text combine upright squeezes a short run, such as a year, into the space of one character.
page:
title = "Vertical writing"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" end
box: display = "flex" gap = 32 font size = 22 height = 200
box: writing mode = "vertical-rl" content = "Vertical lines run top to bottom" end
box: writing mode = "vertical-rl" text orientation = "upright" content = "UPRIGHT" end
box: writing mode = "vertical-rl"
content = "In "
span: text combine upright = "all" content = "2026" end
end
end
endRuby and emphasis marks
Ruby is a small annotation above or below a word, mostly the pronunciation of a Chinese or Japanese word, written with the ruby and ruby text elements. ruby position sets the side and ruby align how the annotation is spread over the word. East Asian text has no italics, so emphasis is drawn as small marks on each character, with text emphasis style, text emphasis color and text emphasis position. The shorthand is text emphasis.
page:
title = "Ruby and emphasis"
global: selector = "body" font family = "system-ui, sans-serif" margin = "1.5rem" font size = 26 line height = 2.2 end
paragraph:
ruby: ruby position = "over" ruby align = "center"
content = "東京"
ruby parenthesis: content = "(" end
ruby text: content = "とうきょう" end
ruby parenthesis: content = ")" end
end
end
paragraph: text emphasis style = "filled dot" text emphasis color = "crimson" content = "Dots mark the emphasis" end
paragraph: text emphasis style = "open circle" text emphasis position = "under right" content = "Circles below the text" end
endPersian and Arabic text
Everything above works for Persian, and a few points need care. A page in a Persian file already has lang = "fa" and the right-to-left direction. Then:
- Choose a font that has Persian letters, and put a safe one at the end of the stack, such as
Tahoma. Many fonts made for English have no Persian letters, and the browser fills the gap letter by letter from another font, which looks uneven. A web font such as Vazirmatn or Estedad is the real fix: load it with thefontelement and therangeof the Persian block. - Set
line heightto about 1.9 for body text. Persian letters carry dots and marks that need space above and below. - Use
text alignstartandend, neverleftandright. - Keep
letter spacingat zero. Do not turn ligatures off either, because the joined forms are the script itself. - Digits are characters, not a style.
۱۲۳and123are different letters, and no CSS property converts one into the other.font variant numericonly changes the look of the digits a font has, such as the equal width form for columns. - Browsers do not hyphenate Persian, and
justifyworks well if the lines are long. - Italics are rare in Persian type. A line that is only
obliquelooks slanted, which is fine for a short quotation but tiring for a paragraph. Use bold, or a different size, for emphasis.
page:
title = "Persian text"
global: selector = "body" font family = "Tahoma, system-ui, sans-serif" margin = "1.5rem" end
box: dir = "rtl" lang = "fa" line height = 1.9 margin bottom = 16 border = "1px solid #cbd5e1" padding = 10 max width = 340
content = "هر کتاب برای خوانندهای نوشته میشود. این بند ۳ سطر دارد و ارتفاع خطش ۱٫۹ است تا نقطهها و کسرهها جا داشته باشند."
end
box: dir = "rtl" lang = "fa" line height = 1.2 margin bottom = 16 border = "1px solid #fecaca" padding = 10 max width = 340
content = "همین متن با ارتفاع خط ۱٫۲ فشرده و خستهکننده میشود، چون سطرها به هم میچسبند و نقطهها روی هم میافتند."
end
box: dir = "rtl" lang = "fa" line height = 1.9 text align = "justify" max width = 340 border = "1px solid #cbd5e1" padding = 10
content = "ترازشدن دوطرفه در متن فارسی خوب کار میکند، به شرط آنکه خطها به اندازهی کافی بلند باشند."
end
endThe example puts the same text three times. The first box has a comfortable line height, the second a tight one where the lines nearly touch, and the third is justified. The preview shows the page as the compiler built it, with Persian letters from the system.
Reference: every font and text property
Each entry shows the name in Salam, its name in CSS, the values it accepts and an example. The examples are checked by the compiler, so you can paste any of them inside a page: block. The colour of text, color, belongs to the lesson on colours and backgrounds, and the box around the text to the lessons that follow it. Persian names work in any file, and the Persian lessons use them.
Fonts: family, size, weight and style
These choose the font and its basic look.
| Property | What it does and what it accepts | Example |
|---|---|---|
font familyخانواده قلم font-family | The fonts to try, in order. The browser uses the first one that is installed (or loaded) and has the letters it needs, so always end the list with a generic family: serif, sans-serif, monospace, cursive, fantasy or system-ui. A name with spaces goes in single quotes inside the string. [comma list of names, quoted names and generic families (serif, sans-serif, ...)] | box: font family = "Georgia, 'Times New Roman', serif" content = "A serif stack" end |
font sizeاندازه قلم font-size | The size of the letters. A bare number means pixels. "1.5rem" is relative to the size of the page root, "1.2em" and percentages to the size of the parent, and vw to the width of the window. The keywords xx-small to xx-large are fixed steps chosen by the browser, and smaller and larger move one step from the parent. [length / percentage / xx-small, x-small, small, medium, large, x-large, ...] | box: font size = "1.5rem" content = "One and a half root sizes" end |
font size adjustتنظیم اندازه قلم font-size-adjust | Rescales a fallback font so that its lowercase letters look as tall as the first font's. The number is the wanted ratio of lowercase height to font size, for example 0.5, and none switches it off. It stops text from jumping in size when a web font is replaced by a fallback. [number / none] | box: font size adjust = "0.5" content = "Same apparent size in every font" end |
font weightوزن قلم font-weight | How heavy the strokes are. Use a number from 1 to 1000 (100 is thin, 400 is normal, 700 is bold, 900 is black) or the words normal and bold. bolder and lighter go one step from the parent. A font that has only two weights shows the nearest one, and a variable font can show every number. [number / normal, bold, bolder, lighter] | box: font weight = 700 content = "Bold text" end |
font styleسبک قلم font-style | Chooses the upright, italic or oblique design. italic uses the font's own italic letters if it has them, and oblique slants the upright letters. Persian fonts rarely have an italic design, so the browser slants the letters. [normal, italic, oblique] | box: font style = "italic" content = "Italic text" end |
font stretchکشیدگی قلم font-stretch | Selects a narrower or wider design of the font, from 50% to 200% or with words such as condensed and expanded. It only does something when the font has width variants, and it never squeezes letters by itself. [percentage / normal, condensed, expanded] | box: font stretch = "condensed" content = "A narrow design" end |
font widthپهنای قلم font-width | The newer name of font stretch, with the same values. Older browsers only know font stretch, so use that one when the page must work everywhere. [a percentage / a font-stretch keyword] | box: font width = "75%" content = "Seventy five percent wide" end |
fontقلم font | The shorthand for style, weight, width, size, line height and family in one string: "italic 700 1.25rem/1.5 Georgia, serif". The size and the family are required, in that order, and every property you leave out is reset to its normal value, so it can wipe settings made earlier. [CSS-wide keywords only] | box: font = "italic 700 1.25rem/1.5 Georgia, serif" content = "Style, weight, size, line height and family at once" end |
font synthesisساخت قلم font-synthesis | Decides what the browser may fake when the font lacks it: weight (bold), style (italic), small-caps and position (sub and superscript). none forbids all of it, which keeps the shapes true to the type designer. [up to 4 values] | box: font synthesis = "none" content = "No faked bold or italic" end |
font synthesis weightساخت وزن قلم font-synthesis-weight | Allows (auto) or forbids (none) a bold that the browser draws by thickening the regular letters. [auto / none] | box: font synthesis weight = "none" content = "No fake bold" end |
font synthesis styleساخت سبک قلم font-synthesis-style | Allows (auto) or forbids (none) an italic made by slanting the upright letters. oblique-only keeps the slant but never uses it for italic. [auto / none / oblique-only] | box: font synthesis style = "none" content = "No fake italic" end |
font synthesis small capsساخت حروف کوچک قلم font-synthesis-small-caps | Allows (auto) or forbids (none) small capitals made by shrinking full capitals. [auto / none] | box: font synthesis small caps = "none" content = "No fake small capitals" end |
font synthesis positionساخت جایگاه قلم font-synthesis-position | Allows (auto) or forbids (none) subscripts and superscripts made by shrinking and moving the normal letters. [auto / none] | box: font synthesis position = "none" content = "No fake superscript" end |
Fonts: features, variants and variable fonts
These switch the extra forms and axes a font offers. The effect depends on the font.
| Property | What it does and what it accepts | Example |
|---|---|---|
font kerningفاصلهگذاری قلم font-kerning | Turns the font's kerning on or off. Kerning pulls certain pairs of letters, such as AV, closer together. auto and normal use it, none does not. Leave it on for text, and only switch it off for tests or special effects. [auto, normal, none] | box: font kerning = "none" content = "AVATAR WAVE without kerning" end |
font optical sizingاندازه بصری قلم font-optical-sizing | Lets a variable font that has an optical size axis change the shape of its letters with the text size: sturdier at small sizes, finer at large ones. auto does it, none keeps one design. It has no effect on ordinary fonts. [auto, none] | box: font optical sizing = "none" content = "Same design at every size" end |
font variantنسخه قلم font-variant | A shorthand that picks several alternate letter forms at once: small-caps, a numeric style, ligatures and so on, or normal to reset them. Use the longer properties below when you want to set only one thing. [up to 99 values] | box: font variant = "small-caps" content = "Small capitals" end |
font variant capsحروف بزرگ قلم font-variant-caps | Chooses capital-letter forms: small-caps (lowercase letters become small capitals), all-small-caps (capitals too), petite-caps, unicase and titling-caps. If the font has no such shapes, browsers may fake the first two. [normal, small-caps, all-small-caps] | box: font variant caps = "all-small-caps" content = "Every letter a small capital" end |
font variant ligaturesپیوندها نسخه قلم font-variant-ligatures | Controls ligatures, the joined shapes such as fi. Words: common-ligatures, no-common-ligatures, discretionary-ligatures, historical-ligatures, contextual, or none for all off. Do not switch ligatures off for Persian and Arabic, where joined forms are the script itself. [up to 4 values] | box: font variant ligatures = "no-common-ligatures" content = "office affinity without ligatures" end |
font variant numericعددی نسخه قلم font-variant-numeric | Chooses the shape and spacing of digits: lining-nums, oldstyle-nums, proportional-nums, tabular-nums (every digit equally wide, for columns), diagonal-fractions, slashed-zero and ordinal. The font must contain these forms. It does not turn English digits into Persian digits: that is a matter of the characters you write. [up to 5 values] | box: font variant numeric = "tabular-nums" content = "1111 and 8888 line up" end |
font variant east asianآسیایی شرق نسخه قلم font-variant-east-asian | Picks forms of Chinese and Japanese characters: simplified, traditional, the JIS standards jis78 to jis04, full-width, proportional-width and ruby. It only matters for a font that carries several forms of the same character. [up to 3 values] | box: font variant east asian = "traditional" content = "漢字 in the traditional forms" end |
font variant alternatesجایگزین های نسخه قلم font-variant-alternates | Switches on alternate glyphs the font offers: historical-forms, or the functions stylistic(), styleset(), swash(), ornaments() and annotation(), which take a name defined by a font feature values rule. [up to 9 of historical-forms or a function like swash()] | box: font variant alternates = "historical-forms" content = "Historical letter forms" end |
font variant positionجایگاه نسخه قلم font-variant-position | Uses the font's own subscript (sub) or superscript (super) glyphs, which are drawn to match the weight of the text. normal uses neither. [normal / sub / super] | box: font variant position = "super" content = "x2 as a real superscript" end |
font variant emojiگونه شکلک قلم font-variant-emoji | Chooses how characters that exist both as symbols and as emoji are drawn: text (a plain monochrome glyph), emoji (the colour picture), unicode (as the character itself says) or normal (the browser decides). [normal / text / emoji / unicode] | box: font variant emoji = "text" content = "A heart as plain text: ❤" end |
font feature settingsتنظیمات ویژگی قلم font-feature-settings | Switches OpenType features by their four letter tags: a comma list such as 'smcp' 1, 'liga' 0, where 1 is on and 0 is off. It is the low level tool, so prefer the font variant properties and use this one for features that have none. [comma list] | box: font feature settings = "'smcp' 1, 'liga' 0" content = "Small capitals, no ligatures" end |
font variation settingsتنظیمات تغییر قلم font-variation-settings | Sets the axes of a variable font by their four letter tags, as a comma list such as 'wght' 650, 'wdth' 90. Ordinary fonts ignore it. When a normal property exists, such as font weight for wght, use that property instead. [comma list] | box: font variation settings = "'wght' 650, 'wdth' 90" content = "A weight between two steps" end |
font paletteپالت قلم font-palette | Chooses the colour palette of a colour font: light, dark, normal, or the name of a palette defined with a @font-palette-values rule. Fonts without colour layers ignore it. [normal / light / dark / an ident / palette-mix()] | box: font palette = "dark" content = "A colour font in its dark palette" end |
font language overrideجایگزینی زبان قلم font-language-override | Forces the OpenType language system, written as a four letter tag in quotes such as 'TRK', instead of the one taken from the lang attribute. normal goes back to the default. Rarely needed. [a quoted string / normal] | box: font language override = "'TRK'" content = "Turkish forms of the letters" end |
Web font element
The font element goes directly inside the page.
font (Persian: قلم)
Declares a web font, which becomes an @font-face rule. name and url are required, and the element goes directly inside the page. Afterwards write the name in font family. Browsers download the file only when some text uses the font, and until then they show the next font of the stack.
font:
name = "Course Serif"
url = "/fonts/course-serif.woff2"
weight = 400
display = swap
end
box: font family = "Course Serif, Georgia, serif" content = "Set in the course font" end
| Attribute | What it does | Example |
|---|---|---|
nameنام | The family name you choose for the font. It is free text and has nothing to do with the name of the file: you write the same name later in font family. Required. [string] | font: name = "Course Serif" url = "/fonts/course-serif.woff2" end
box: font family = "Course Serif, serif" content = "The name is what font family uses" end |
urlنشانی | Where the font file is. Write one address, or several separated by spaces, best first: the browser takes the first format it understands (woff2 before woff). A relative address is read from the page, an unsafe one such as javascript: is an error, and a relative file that does not exist next to the program gives a warning. Required. [url (list)] | font: name = "Course Serif" url = "/fonts/course-serif.woff2 /fonts/course-serif.woff" end |
typeنوع | The file format: woff2, woff, ttf (truetype), otf (opentype) or collection. Leave it out and Salam works it out from the end of the address, then from the bytes of a file next to the program. A type that disagrees with the file is an error. [enum: font_format] | font: name = "Course Serif" url = "/fonts/course-serif.bin" type = woff2 end |
weightوزن | The weight this file provides, a number from 1 to 1000 such as 400 or 700. For a variable font give the range inside a string, such as "100 900". A number outside the range is an error. Declare one font per weight with the same name. [string] | font: name = "Course Serif" url = "/fonts/course-serif-bold.woff2" weight = 700 end |
styleسبک | The style this file provides: normal, italic or oblique. The browser picks the file whose style matches the text. [enum: font_style] | font: name = "Course Serif" url = "/fonts/course-serif-italic.woff2" style = italic end |
displayنمایش | What the browser shows while the font file is still loading. swap shows the fallback font at once and swaps when the file arrives (the usual choice), block hides the text for a moment, fallback and optional swap late or never on a slow line, and auto leaves it to the browser. [enum: font_display] | font: name = "Course Serif" url = "/fonts/course-serif.woff2" display = swap end |
rangeبازه | The characters this file covers, as Unicode ranges separated by commas. The browser downloads the file only when the page contains a character of that range, so a font split into a Latin file and a Persian file loads only what the page uses. U+0600-06FF is the Arabic and Persian block. [string] | font: name = "Course Serif" url = "/fonts/course-serif-arabic.woff2" range = "U+0600-06FF, U+200C-200D" end |
Text appearance: alignment, case, lines and shadows
These change how a line of text is placed and drawn.
| Property | What it does and what it accepts | Example |
|---|---|---|
text alignترازمتن text-align | How the lines of a block sit between its sides: start and end follow the reading direction (right and left in Persian), left and right are fixed, center and justify stretch every line but the last to the full width. Prefer start to left so that one page works in both directions. [start, end, left, right, center, justify] | box: text align = "center" content = "Centered text" end |
text align lastتراز خط آخر text-align-last | Sets the alignment of the last line of a block, and of lines that end with a forced break. It takes the same words as text align plus auto. It is mostly used with text align = "justify". [auto, start, end, left, right, center, ...] | box: text align last = "center" content = "The last line of a justified block is centered. It wraps over a few lines in a narrow box to show it." end |
text justifyچینش متن text-justify | Where a justified line gets its extra space: inter-word (between words), inter-character (between letters), auto or none. It only matters when text align is justify. [auto, none, inter-word, inter-character] | box: text align = "justify" text justify = "inter-character" width = 260 content = "Space is added between letters when the text is justified, which is how Chinese and Japanese are set." end |
text indentتورفتگی متن text-indent | The empty space before the first line of a block. A length or a percentage, and a negative number pushes the first line out, which together with padding makes a hanging indent. [length / percentage] | box: text indent = "2em" content = "The first line of a paragraph starts two letters in. The rest of the lines do not move, so the paragraph reads like in a book." end |
text transformتبدیل متن text-transform | Changes the case of the shown letters without touching the text itself: uppercase, lowercase, capitalize (the first letter of each word) or none. Persian and Arabic have no case, so it does nothing to them. [none, uppercase, lowercase, capitalize] | box: text transform = "uppercase" content = "shout in capitals" end |
text decorationتزیین متن text-decoration | The shorthand for line, style, colour and thickness of the lines drawn on text: "underline wavy crimson". Links have an underline by default, and "none" removes it. [CSS-wide keywords only] | box: text decoration = "underline wavy crimson" content = "A wavy red underline" end |
text decoration lineخط تزیین متن text-decoration-line | Which lines are drawn: underline, overline, line-through or none. You can list several words in one string. [none, underline, overline, line-through; up to 3 values] | box: text decoration line = "underline overline" content = "A line above and a line below" end |
text decoration styleسبک تزیین متن text-decoration-style | The look of the line: solid, double, dotted, dashed or wavy. It needs a decoration line to be visible. [solid, double, dotted, dashed, wavy] | box: text decoration style = "dashed" content = "A dashed underline" end |
text decoration colorرنگ تزیین متن text-decoration-color | The colour of the decoration line. Without it the line takes the colour of the text. [color] | box: text decoration line = "underline" text decoration color = "crimson" content = "A crimson underline" end |
text decoration thicknessضخامت تزیین متن text-decoration-thickness | The thickness of the line: a length, a percentage of the font size, auto or from-font, which uses what the font recommends. [length / percentage / auto, from-font] | box: text decoration line = "underline" text decoration thickness = 4 content = "A thick underline" end |
text decoration skip inkپرش جوهر تزیین text-decoration-skip-ink | Whether an underline or overline skips the parts of letters it would touch, such as the tail of a g. auto skips, none draws through them, and all skips for every script. [auto, none, all] | box: text decoration line = "underline" text decoration skip ink = "none" content = "The line runs through gypsy and jumpy" end |
text underline offsetفاصله زیرخط text-underline-offset | How far the underline sits from the baseline: a length, a percentage or auto. A bigger number moves it away from the letters. [length / percentage / auto] | box: text decoration line = "underline" text underline offset = 8 content = "An underline moved down" end |
text underline positionجای زیرخط text-underline-position | Where an underline goes: auto, under (below every descender) or, for vertical text, left and right. Useful for scripts with long descenders. [auto, under, left, right; up to 2 values] | box: text decoration line = "underline" text underline position = "under" content = "The line sits below the lowest letters" end |
text shadowسایه متن text-shadow | One or more shadows, separated by commas. Each one is: horizontal offset, vertical offset, an optional blur and a colour, for example "2px 2px 4px #94a3b8". Several shadows make glows and outlines. Keep enough contrast so the text stays readable. [comma list] | box: text shadow = "2px 2px 4px #94a3b8" content = "A soft shadow" end |
webkit text strokeخط دور متن -webkit-text-stroke | Draws an outline around each letter: a width and a colour, such as "1px #0f172a". Every current browser supports it under the -webkit- name. Combine it with a transparent fill colour for outlined text. [length and color, in either order] | box: webkit text stroke = "1px #0f172a" webkit text fill color = "transparent" font size = 36 font weight = 700 content = "Outline" end |
webkit text stroke widthضخامت خط دور متن -webkit-text-stroke-width | The width of the outline only: a length or thin, medium, thick. A thick stroke eats into the letters, since it is centred on their edge. [length / thin / medium / thick] | box: webkit text stroke width = 2 webkit text stroke color = "teal" font size = 36 font weight = 700 content = "Thick outline" end |
webkit text stroke colorرنگ خط دور متن -webkit-text-stroke-color | The colour of the outline only. It needs a stroke width above zero to be seen. [color] | box: webkit text stroke width = 1 webkit text stroke color = "crimson" font size = 36 font weight = 700 content = "Red outline" end |
webkit text fill colorرنگ پر متن -webkit-text-fill-color | The colour that fills the letters. It beats color when both are set, and transparent lets the background or the stroke show through. [color] | box: webkit text fill color = "#0f766e" content = "Filled with teal" end |
text renderingنمایش متن text-rendering | A hint about speed against quality: auto, optimizeSpeed, optimizeLegibility (kerning and ligatures on) or geometricPrecision. Browsers may ignore it. [auto, optimizeSpeed, optimizeLegibility, geometricPrecision] | box: text rendering = "optimizeLegibility" content = "Optimised for reading" end |
Spacing and wrapping
These set the space between lines, letters and words, and decide where lines break or are cut.
| Property | What it does and what it accepts | Example |
|---|---|---|
line heightارتفاع خط line-height | The height of each line. A bare number (1.6) is multiplied by the font size of the element and is the best choice, because children inherit the number and not a fixed result. A length or a percentage gives a fixed height. Use about 1.5 for English and about 1.9 for Persian. [number / length / percentage / normal] | box: line height = 1.7 width = 260 background = "#f1f5f9" content = "Lines that have room to breathe. A number is multiplied by the font size, so it follows the text when the size changes." end |
letter spacingفاصله حروف letter-spacing | Extra space between letters: a length, best in em so it grows with the text, or normal. A small positive value suits capitals and labels. Never use it on Persian or Arabic, whose letters join and must stay joined. [length / normal] | box: letter spacing = "0.2em" text transform = "uppercase" content = "spaced capitals" end |
word spacingفاصله واژهها word-spacing | Extra space between words: a length, a percentage or normal. A negative value pulls them closer. [length / percentage / normal] | box: word spacing = "0.6em" content = "Words pushed apart a little" end |
vertical alignتراز عمودی متن vertical-align | Where an inline element or a table cell sits vertically: baseline, sub, super, top, middle, bottom, text-top, text-bottom, or a length that raises (positive) or lowers (negative) it. It does not centre a box inside its parent. [length / percentage / baseline, sub, super, text-top, text-bottom, middle, ...] | box: vertical align = "super" font size = 22 content = "x2 raised on the line" end |
white spaceفضای سفید white-space | How spaces and line breaks in the text are treated: normal merges them and wraps, nowrap never wraps, pre keeps everything and never wraps, pre-wrap keeps everything and wraps, pre-line keeps the line breaks only and break-spaces keeps spaces that can wrap. [normal, nowrap, pre, pre-wrap, pre-line, break-spaces] | box: white space = "pre-line" width = 220 background = "#f1f5f9" content = "Breaks in the text\nare kept as they are\nin this box." end |
white space collapseادغام فضای سفید white-space-collapse | Only the spaces half of white space: collapse (merge), preserve (keep all), preserve-breaks (keep line breaks, merge spaces), preserve-spaces and break-spaces. [collapse, preserve, preserve-breaks, preserve-spaces, break-spaces] | box: white space collapse = "preserve-breaks" width = 220 background = "#f1f5f9" content = "Line breaks\nstay, extra spaces go." end |
word breakشکستن واژه word-break | Where a line may break inside words: normal, break-all (between any two letters), keep-all (never inside Chinese, Japanese and Korean words) or break-word. For ordinary text overflow wrap is the better tool. [normal, break-all, keep-all, break-word] | box: word break = "break-all" width = 150 background = "#fef9c3" content = "Break-all cuts words anywhere" end |
overflow wrapشکستن سرریز overflow-wrap | Lets a word that is too long for the box break so it does not stick out. normal never breaks it, break-word breaks only if there is no other way, and anywhere does the same and also counts the break points when the box size is computed. [normal, break-word, anywhere] | box: overflow wrap = "anywhere" width = 150 background = "#e0f2fe" content = "https://example.com/an/address/with/no/spaces" end |
line breakقاعده شکستن خط line-break | How strict the rules are for where a line may break, mostly for Chinese and Japanese: auto, loose, normal, strict or anywhere. [auto, loose, normal, strict, anywhere] | box: line break = "anywhere" width = 150 background = "#e0f2fe" content = "Strict rules or loose rules for where lines may break." end |
hyphensخط تیره hyphens | Whether a word may be split with a hyphen at the end of a line: none, manual (only at soft hyphens you write) or auto (the browser decides). auto needs a lang it has a dictionary for, and browsers do not hyphenate Persian. [none, manual, auto] | box: hyphens = "auto" lang = "en" width = 160 background = "#dcfce7" content = "Hyphenation helps incomprehensibilities fit narrow columns." end |
hyphenate characterنویسه خط تیره hyphenate-character | The character shown where a word is broken by hyphenation. auto uses the hyphen of the language, and a string such as "~" uses that instead. [string / auto] | box: hyphens = "auto" hyphenate character = "\"~\"" lang = "en" width = 160 background = "#dcfce7" content = "Incomprehensibilities break with a tilde." end |
hyphenate limit charsحد نویسه خط تیره hyphenate-limit-chars | Limits hyphenation to words of a certain size: up to three numbers for the shortest word, the shortest part before the hyphen and the shortest part after it, for example "8 3 3". auto leaves it to the browser. [up to 3 of an integer or auto] | box: hyphens = "auto" hyphenate limit chars = "8 3 3" lang = "en" width = 160 background = "#dcfce7" content = "Only long words are hyphenated, never leaving a short stub." end |
text wrapپیچش متن text-wrap | How lines are broken. wrap is normal, nowrap never breaks, balance makes the lines about equally long (good for headings), pretty avoids a lone short word on the last line, and stable does not reflow lines while you edit the text. [wrap, nowrap, balance, pretty, stable] | box: text wrap = "balance" width = 260 font size = 22 font weight = 700 content = "A headline that is split into two even lines" end |
text wrap modeحالت پیچش متن text-wrap-mode | Only the first half of text wrap: wrap lets lines break and nowrap keeps all text on one line. [CSS-wide keywords only] | box: text wrap mode = "nowrap" width = 160 overflow = "hidden" background = "#f1f5f9" content = "A sentence that refuses to wrap" end |
text wrap styleسبک پیچش متن text-wrap-style | Only the second half of text wrap: auto, balance, pretty or stable. [CSS-wide keywords only] | box: text wrap style = "pretty" width = 200 background = "#f1f5f9" content = "A paragraph that avoids ending on a single short word" end |
text overflowسرریز متن text-overflow | What a line shows where it is cut off: clip cuts it, ellipsis ends it with an ellipsis. It works only when the box has overflow other than visible and the text cannot wrap, so it is used together with white space = "nowrap". [clip, ellipsis] | box: text overflow = "ellipsis" white space = "nowrap" overflow = "hidden" width = 180 background = "#f1f5f9" content = "This sentence is far too long for its box" end |
line clampمحدود کردن سطرها line-clamp | Limits a block to a number of lines (an integer) and shows an ellipsis at the cut. It is a new standard property that only recent browsers have, so also give the box max height and overflow as in the example, which cuts the text in every browser. [integer / none] | box: line clamp = 2 overflow = "hidden" max height = "3em" line height = 1.5 width = 220 background = "#f1f5f9" content = "A long text that is limited to a number of lines and ends with an ellipsis when it does not fit." end |
tab sizeاندازه زبانه tab-size | The width of a tab character: a number of spaces or a length. It only matters in text where tabs survive, that is in white space = "pre" or pre-wrap, such as source code. [integer / length] | box: tab size = 2 white space = "pre" font family = "monospace" content = "a\tb\tc" end |
orphansسطرهای یتیم orphans | In printed or multi-column text, the least number of lines of a paragraph that may stay alone at the bottom of a page or column. An integer, usually 2 or 3. [integer] | box: orphans = 3 content = "At least three lines stay at the bottom of a page when printed." end |
widowsسطرهای بیوه widows | The opposite of orphans: the least number of lines of a paragraph that may stay alone at the top of the next page or column. [integer] | box: widows = 3 content = "At least three lines go to the top of the next page when printed." end |
hanging punctuationنشانهگذاری آویزان hanging-punctuation | Lets an opening quote or a closing mark hang outside the text edge so the letters line up: first, last, force-end, allow-end or none. Only Safari supports it. [none, first, last, force-end, allow-end; up to 3 values] | box: hanging punctuation = "first" content = "“The quote mark hangs outside the edge of the text.”" end |
text boxجعبه متن text-box | The shorthand of text box trim and text box edge: "trim-both cap alphabetic" cuts the empty space above the capitals and below the baseline. normal cuts nothing. [normal or a trim keyword with an edge keyword] | box: text box = "trim-both cap alphabetic" font size = 28 background = "#fef9c3" content = "Tight around the letters" end |
text box trimبرش جعبه متن text-box-trim | Removes the half-leading, the extra space the line height adds above the first line and below the last one: trim-start, trim-end, trim-both or none. It is a new property, so check browser support first. [none / trim-start / trim-end / trim-both] | box: text box trim = "trim-both" text box edge = "cap alphabetic" font size = 28 background = "#fef9c3" content = "Half-leading removed" end |
text box edgeلبه جعبه متن text-box-edge | Which lines the trimmed edges are measured from: for the top text, cap or ex, for the bottom text or alphabetic, such as "cap alphabetic". Used together with text box trim. [up to 2 of auto, text, cap, ex, alphabetic, ...] | box: text box trim = "trim-both" text box edge = "ex alphabetic" font size = 28 background = "#fef9c3" content = "Edges at the x-height" end |
initial letterحرف آغازین initial-letter | Makes the first letter of a block a drop cap that spans a number of lines, for example 3 for three lines. A second number sets how far it sinks. It applies to the first letter of a block, and browser support is still partial. [normal / number, with an optional drop/raise count] | box: width = 260 font size = 18
span: initial letter = 3 color = "crimson" content = "S" end
span: content = "alam begins with a tall first letter." end
end |
Direction and writing modes
These set the direction of the text and turn lines upright.
| Property | What it does and what it accepts | Example |
|---|---|---|
directionجهت متن direction | The writing direction of the text of an element: ltr (left to right) or rtl (right to left). It decides which side start is, where the punctuation goes and which way the columns of a table run. For a whole element, the dir attribute is the better choice, because it also tells assistive technology. [ltr, rtl] | box: direction = "rtl" width = 260 background = "#f1f5f9" content = "Right to left text: (end of the sentence)." end |
unicode bidiدوسویه یونیکد unicode-bidi | How mixed direction text is ordered. normal uses the standard algorithm, isolate lays the element out on its own, embed opens a new level, bidi-override forces the order of direction whatever the letters are, and plaintext chooses by the first strong letter. [normal, embed, isolate, bidi-override, isolate-override, plaintext] | box: unicode bidi = "bidi-override" direction = "rtl" content = "Reversed by force" end |
writing modeحالت نوشتار writing-mode | The direction in which lines run: horizontal-tb (normal), vertical-rl (lines go top to bottom and are stacked from right to left, as in Japanese) or vertical-lr (stacked left to right). All the logical properties turn with it. [horizontal-tb, vertical-rl, vertical-lr] | box: writing mode = "vertical-rl" height = 160 font size = 22 content = "Vertical text runs top to bottom" end |
text orientationجهتگیری متن text-orientation | How letters stand in vertical text: mixed turns Latin letters sideways and keeps East Asian characters upright, upright keeps every letter upright, and sideways turns all of them. [mixed, upright, sideways] | box: writing mode = "vertical-rl" text orientation = "upright" height = 160 font size = 22 content = "UPRIGHT" end |
text combine uprightترکیب ایستاده متن text-combine-upright | In vertical text, sets a short run of characters, such as a year, side by side in the space of one character. all does it for the whole element and none does not. Used on a span inside a vertical block. [none, all] | box: writing mode = "vertical-rl" height = 140 font size = 22
content = "Year "
span: text combine upright = "all" content = "2026" end
end |
Ruby, emphasis and East Asian typography
These are made for Chinese, Japanese and Korean, though most of them work with any text.
| Property | What it does and what it accepts | Example |
|---|---|---|
ruby alignتراز آوانما ruby-align | How the small annotation is spread over its base text: start, center, space-between or space-around. It is set on the ruby element. [start, center, space-between, space-around] | ruby: ruby align = "space-between" font size = 28
content = "漢字"
ruby text: content = "kanji" end
end |
ruby positionجای آوانما ruby-position | Which side the annotation goes: over (above horizontal text), under, alternate (above and below by turns) or inter-character (beside the characters, as used for Taiwanese bopomofo). [over, under, alternate, inter-character; up to 2 values] | ruby: ruby position = "under" font size = 28
content = "東京"
ruby text: content = "Tōkyō" end
end |
text emphasisتاکید متن text-emphasis | The shorthand for the mark drawn on each character, its colour and its place: "filled dot crimson". Used in East Asian text, where italic letters do not exist, but it works with any text. [CSS-wide keywords only] | box: text emphasis = "filled dot crimson" content = "Dots mark the emphasis" end |
text emphasis styleسبک تاکید متن text-emphasis-style | The mark: none, a shape (dot, circle, double-circle, triangle, sesame) with filled or open before it, or any single character in quotes. [string; up to 2 values] | box: text emphasis style = "open circle" content = "Hollow circles on every letter" end |
text emphasis colorرنگ تاکید متن text-emphasis-color | The colour of the marks. Without it they take the colour of the text. [color] | box: text emphasis style = "filled dot" text emphasis color = "crimson" content = "Red dots" end |
text emphasis positionموقعیت تاکید متن text-emphasis-position | Where the marks go: over or under, then right or left (the side they take in vertical text), for example "under right". [up to 2 values] | box: text emphasis style = "filled dot" text emphasis position = "under right" content = "Dots below the letters" end |
text spacing trimبرش فاصله متن text-spacing-trim | In Chinese and Japanese, controls whether the empty half of full-width punctuation is trimmed: normal, space-all (never), space-first or trim-start. [normal / space-all / space-first / trim-start] | box: text spacing trim = "space-all" font size = 24 content = "「東京」と「大阪」" end |
text autospaceفاصله خودکار متن text-autospace | Adds a small space between Chinese or Japanese characters and Latin letters or digits next to them: normal, no-autospace or the words ideograph-alpha and ideograph-numeric. [up to 3 autospace keywords] | box: text autospace = "normal" font size = 24 content = "東京Towerと12個" end |
Try it yourself
- Take the type tester and add a second slider that sets
line heightbetween 1 and 3 on the sample. At what value does a paragraph start to feel loose? - Write the front of a book: a title in small capitals with
letter spacing, an author line in italics, and a paragraph that is justified with atext indentof 2em. - Declare a
fontwith a file that does not exist, use it in a font stack with a good fallback, and check that the page is still readable. - Make a card that shows the first three lines of a long text and a headline with
text wrap = "balance".