CSS Text Color and Alignment

Two of the very first properties every CSS author reaches for are color, which sets the color of an element’s text, and text-align, which controls how that text is positioned horizontally inside its container. They look simple, but both interact with inheritance, the box model, and the difference between inline and block-level boxes in ways that trip up beginners constantly. This lesson covers the full picture: how each property is computed by the browser, every value format you can use, and the mistakes that most often produce "my CSS isn’t working" bug reports.

Overview / How it works

color is an inherited property. When you set it on an element, every descendant that does not have its own color declaration inherits the computed value. This is why setting color once on <body> can style an entire page’s text: the value cascades down the DOM tree unless something more specific overrides it. Internally, the browser resolves whatever color format you used (a keyword, a hex code, a function like rgb()) into a single internal color representation used for painting glyphs during the paint stage of rendering — well after layout has already happened, since color never affects the size or position of a box.

text-align is different: it is also inherited, but it does not paint anything by itself. Instead it is a formatting instruction consumed by the block layout algorithm. It only has an effect on block-level boxes that establish an inline formatting context — that is, elements whose content includes text or inline children, such as <p>, <div>, <li>, or table cells. When the browser lays out the lines of inline content inside such a box, text-align tells it where to position each line within the available width of that box: flush left, flush right, centered, or stretched edge-to-edge (justified). Setting text-align on an inline element like <span> or on the box itself to try to move the box has no effect on the box’s own position — a very common source of confusion covered later in this lesson.

Syntax

selector {
  color: value;
  text-align: value;
}
Property Common values Inherited? Affects layout?
color keyword, hex, rgb(), hsl(), currentColor Yes No (paint only)
text-align left, right, center, justify, start, end Yes Yes (inline layout)

color value formats

  • Keywordred, rebeccapurple, transparent. Easy to read, but limited to ~150 named colors.
  • Hex#ff0000 or the short form #f00; an 8-digit form like #ff000080 adds an alpha channel.
  • rgb()rgb(255 0 0) for opaque, or rgb(255 0 0 / 50%) for 50% opacity. Modern CSS allows the space-separated syntax shown here without commas.
  • hsl()hsl(0 100% 50%) expresses color as hue/saturation/lightness, which is often more intuitive for building color scales by hand.
  • currentColor — a keyword that resolves to the element’s own computed color value. Useful on border, box-shadow, or fill so a border automatically matches the text color without repeating a value.

text-align value reference

Value Effect
left Lines start at the left edge of the box
right Lines start at the right edge of the box
center Each line is centered within the box’s width
justify Word spacing is stretched so every line except the last fills the full width
start / end Like left/right, but relative to the text direction (logical, so they flip automatically in right-to-left languages)

Examples

Example 1: Basic color and alignment on a paragraph

p.intro {
  color: #2b2b2b;
  text-align: left;
}

This applies to a paragraph like <p class="intro">Welcome to the course.</p>.

Result: the paragraph’s text renders in a dark charcoal gray instead of the browser default black, and stays flush against the left edge of its container (the default in left-to-right languages, so this rule is mostly here for explicitness).

This is the simplest possible case: one color value, one alignment value, applied directly to the element that contains the text.

Example 2: Centered heading and a semi-transparent warning message

h2.section-title {
  color: hsl(210 70% 40%);
  text-align: center;
}

p.warning {
  color: rgb(178 34 34 / 90%);
  text-align: center;
}

Result: the heading renders in a medium, slightly desaturated blue and is centered horizontally within its own box. The warning paragraph renders in a firebrick red that is very close to fully opaque (90% alpha lets a hint of the background show through), and its text is also centered.

Notice that hsl() and rgb() can both take an optional alpha channel using the / syntax. This is the modern, comma-less function syntax supported by all evergreen browsers.

Example 3: A realistic card component using currentColor and a custom property

:root {
  --brand-color: #1a73e8;
}

.card {
  border: 2px solid currentColor;
  color: var(--brand-color);
  padding: 1.5rem;
  text-align: justify;
}

.card__title {
  color: inherit;
  text-align: left;
  font-weight: 700;
}

.card__cta {
  color: #ffffff;
  background-color: var(--brand-color);
  text-align: center;
  padding: 0.5rem 1rem;
}

This targets a structure like a <div class="card"> containing an <h3 class="card__title"> and a <button class="card__cta">.

Result: the card gets a 2px border painted in the same blue as its text, because currentColor picks up the .card element’s own color: var(--brand-color). Body text inside the card is justified so both edges of each line align. The title explicitly inherits the same blue and stays left-aligned, overriding the justify behavior it would otherwise inherit. The call-to-action button gets solid blue background with white text, centered.

This example shows how currentColor and custom properties reduce repetition: change --brand-color once and both the border and the button background update together.

How it works step by step

Common Mistakes

Mistake 1: Using text-align to try to center the box itself

.box {
  width: 300px;
  text-align: center;
}

This is wrong when the goal is to horizontally center the .box element on the page. text-align only centers the inline content inside the box — it has no effect on where the box itself sits relative to its parent. Beginners often add this rule, see nothing move, and assume CSS is broken.

The fix is to center the box using margins (for a block element with a fixed width) instead:

.box {
  width: 300px;
  margin: 0 auto;
  text-align: left;
}

Mistake 2: A typo’d property name silently doing nothing

span.label {
  colour: red;
  text-align: center;
}

Browsers silently ignore any declaration they don’t recognize, so colour (the British spelling) simply never applies — no error appears anywhere, which makes this bug easy to miss. In addition, text-align here has no visible effect because <span> is inline by default and does not establish its own block-level box to align content within.

The corrected version uses the correct American-spelled property name and makes the span a block-level box so alignment has something to act on:

span.label {
  color: red;
  display: inline-block;
  text-align: center;
}

Best Practices

  • Set a base color on <body> or :root and let inheritance carry it through the page instead of repeating the same color on every element.
  • Prefer rgb()/hsl() with an alpha channel over plain hex when you need transparency — it keeps the color and opacity values in one readable declaration.
  • Use currentColor for borders, shadows, and SVG fills that should always match the surrounding text color, so you only maintain one color value per component.
  • Reach for start/end instead of left/right when a page might support right-to-left languages, since the logical values flip automatically with text direction.
  • Always check color contrast against the background (aim for at least a 4.5:1 ratio for body text) — a color that looks fine to you may fail accessibility guidelines for users with low vision.
  • Remember text-align only works on block-level boxes with inline content; if it seems to do nothing, check whether the target element is inline and needs display: inline-block or block first.
  • Avoid text-align: justify on narrow columns of body text — it can create large, ugly gaps between words when there are few words per line.

Practice Exercises

  • Create a rule for a <blockquote> that sets its text color to a muted gray using hsl(), and center-aligns its text. Then add a nested <footer> inside the blockquote whose color should be different from the quote text — write the override.
  • You have a <div class="alert"> with width: 400px that a teammate tried to center on the page using only text-align: center, and it didn’t move. Explain why, and write the corrected CSS that actually centers the box itself while keeping its text left-aligned.
  • Build a small badge component: a <span> with a colored background and white text, centered text, using a CSS custom property for the background color so the same variable could be reused for a border elsewhere via currentColor.

Summary

  • color sets text color and is inherited; it affects paint only, never layout.
  • text-align controls how lines of inline content are positioned inside a block-level box; it does not move the box itself.
  • Color can be specified as a keyword, hex, rgb(), hsl(), or via the special currentColor keyword, all of which support an alpha channel for transparency.
  • text-align only has a visible effect on elements that establish an inline formatting context — inline elements need display: inline-block or block first.
  • Use start/end instead of left/right for layouts that need to support right-to-left languages.
  • To center a box (not its text), use margins or a layout method like flexbox/grid — not text-align.