CSS Typography
How to work with typography in CSS
In this post I’ll talk about styling text with CSS, using the following properties:
text-transform
text-decoration
text-align
vertical-align
line-height
text-indent
text-align-last
word-spacing
letter-spacing
text-shadow
white-space
tab-size
writing-mode
hyphens
text-orientation
direction
line-break
word-break
overflow-wrap
text-transform
This property can transform the case of an element.
There are 4 valid values:
capitalize
to uppercase the first letter of each worduppercase
to uppercase all the textlowercase
to lowercase all the textnone
to disable transforming the text, used to avoid inheriting the property
Example:
p {
text-transform: uppercase;
}
text-decoration
This property is sed to add decorations to the text, including
underline
overline
line-through
blink
none
Example:
p {
text-decoration: underline;
}
You can also set the style of the decoration, and the color.
Example:
p {
text-decoration: underline dashed yellow;
}
Valid style values are solid
, double
, dotted
, dashed
, wavy
.
You can do all in one line, or use the specific properties:
text-decoration-line
text-decoration-color
text-decoration-style
Example:
p {
text-decoration-line: underline;
text-decoration-color: yellow;
text-decoration-style: dashed;
}
text-align
By default text align has the start
value, meaning the text starts at the “start”, origin 0, 0 of the box that contains it. This means top left in left-to-right languages, and top right in right-to-left languages.
Possible values are start
, end
, left
, right
, center
, justify
(nice to have a consistent spacing at the line ends):
p {
text-align: right;
}
vertical-align
Determines how inline elements are vertically aligned.
We have several values for this property. First we can assign a length or percentage value. Those are used to align the text in a position higher or lower (using negative values) than the baseline of the parent element.
Then we have the keywords:
baseline
(the default), aligns the baseline to the baseline of the parent elementsub
makes an element subscripted, simulating thesub
HTML element resultsuper
makes an element superscripted, simulating thesup
HTML element resulttop
align the top of the element to the top of the linetext-top
align the top of the element to the top of the parent element fontmiddle
align the middle of the element to the middle of the line of the parentbottom
align the bottom of the element to the bottom of the linetext-bottom
align the bottom of the element to the bottom of the parent element font
line-height
This allows you to change the height of a line. Each line of text has a certain font height, but then there is additional spacing vertically between the lines. That’s the line height:
p {
line-height: 0.9rem;
}
text-indent
Indent the first line of a paragraph by a set length, or a percentage of the paragraph width:
p {
text-indent: -10px;
}
text-align-last
By default the last line of a paragraph is aligned following the text-align
value. Use this property to change that behavior:
p {
text-align-last: right;
}
word-spacing
Modifies the spacing between each word.
You can use the normal
keyword, to reset inherited values, or use a length value:
p {
word-spacing: 2px;
}
span {
word-spacing: -0.2em;
}
letter-spacing
Modifies the spacing between each letter.
You can use the normal
keyword, to reset inherited values, or use a length value:
p {
letter-spacing: 0.2px;
}
span {
letter-spacing: -0.2em;
}
text-shadow
Apply a shadow to the text. By default the text has now shadow.
This property accepts an optional color, and a set of values that set
- the X offset of the shadow from the text
- the Y offset of the shadow from the text
- the blur radius
If the color is not specified, the shadow will use the text color.
Examples:
p {
text-shadow: 0.2px 2px;
}
span {
text-shadow: yellow 0.2px 2px 3px;
}
white-space
Sets how CSS handles the white space, new lines and tabs inside an element.
Valid values that collapse white space are:
normal
collapses white space. Adds new lines when necessary as the text reaches the container endnowrap
collapses white space. Does not add a new line when the text reaches the end of the container, and suppresses any line break added to the textpre-line
collapses white space. Adds new lines when necessary as the text reaches the container end
Valid values that preserve white space are:
pre
preserves white space. Does not add a new line when the text reaches the end of the container, but preserves line break added to the textpre-wrap
preserves white space. Adds new lines when necessary as the text reaches the container end
tab-size
Sets the width of the tab character. By default it’s 8, and you can set an integer value that sets the character spaces it takes, or a length value:
p {
tab-size: 2;
}
span {
tab-size: 4px;
}
writing-mode
Defines whether lines of text are laid out horizontally or vertically, and the direction in which blocks progress.
The values you can use are
horizontal-tb
(default)vertical-rl
content is laid out vertically. New lines are put on the left of the previousvertical-lr
content is laid out vertically. New lines are put on the right of the previous
hyphens
Determines if hyphens should be automatically added when going to a new line.
Valid values are
none
(default)manual
only add an hyphen when there is already a visible hyphen or a hidden hyphen (a special character)auto
add hyphens when determined the text can have a hyphen.
text-orientation
When writing-mode
is in a vertical mode, determines the orientation of the text.
Valid values are
mixed
is the default, and if a language is vertical (like Japanese) it preserves that orientation, while rotating text written in western languagesupright
makes all text be vertically orientedsideways
makes all text horizontally oriented
direction
Sets the direction of the text. Valid values are ltr
and rtl
:
p {
direction: rtl;
}
word-break
This property specifies how to break lines within words.
normal
(default) means the text is only broken between words, not inside a wordbreak-all
the browser can break a word (but no hyphens are added)keep-all
suppress soft wrapping. Mostly used for CJK (Chinese/Japanese/Korean) text.
Speaking of CJK text, the property line-break
is used to determine how text lines break. I’m not an expert with those languages, so I will avoid covering it.
overflow-wrap
If a word is too long to fit a line, it can overflow outside of the container.
This property is also known as
word-wrap
, although that is non-standard (but still works as an alias)
This is the default behavior (overflow-wrap: normal;
).
We can use:
p {
overflow-wrap: break-word;
}
to break it at the exact length of the line, or
p {
overflow-wrap: anywhere;
}
if the browser sees there’s a soft wrap opportunity somewhere earlier. No hyphens are added, in any case.
This property is very similar to word-break
. We might want to choose this one on western languages, while word-break
has special treatment for non-western languages.
→ I wrote 17 books to help you become a better developer, download them all at $0 cost by joining my newsletter
→ JOIN MY CODING BOOTCAMP, an amazing cohort course that will be a huge step up in your coding career - covering React, Next.js - next edition February 2025