Skip to content

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

This property can transform the case of an element.

There are 4 valid values:

Example:

p {
  text-transform: uppercase;
}

text-decoration

This property is sed to add decorations to the text, including

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:

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:

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

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:

Valid values that preserve white space are:

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

hyphens

Determines if hyphens should be automatically added when going to a new line.

Valid values are

text-orientation

When writing-mode is in a vertical mode, determines the orientation of the text.

Valid values are

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.

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.


→ Here's my latest YouTube video

→ Get my CSS Handbook

→ 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

Bootcamp 2025

Join the waiting list