CSS Text Color
CSS text color controls the foreground color of written content on a web page. It can be applied to headings, paragraphs, links, buttons, labels, lists, table cells, form elements, and almost any HTML element containing text.
The main CSS property used for this purpose is color.
p {
color: blue;
}
This rule changes the text inside every <p> element to blue.
Text color may look like a simple design choice, but it also influences readability, accessibility, branding, visual hierarchy, and the overall user experience.
Basic Syntax
The color property follows standard CSS property-and-value syntax:
selector {
color: value;
}
Example:
h2 {
color: darkgreen;
}
HTML:
<h2>This heading is dark green.</h2>
The color property changes the foreground color of an element. It normally affects the elements text and may also influence related features such as:
- Text decorations
- List markers
- Carets in editable fields
- Borders that use
currentColor - SVG elements that inherit the text color
- Some form-control details, depending on the browser
Ways to Define Text Colors in CSS
CSS supports several color formats. Each format has advantages for particular situations.
Color Names
CSS includes named colors such as red, blue, green, black, white, and tomato.
p {
color: navy;
}
Another example:
.warning {
color: crimson;
}
Named colors are easy to read, but they provide limited precision compared with numeric color formats.
.success {
color: seagreen;
}
.error {
color: firebrick;
}
.information {
color: royalblue;
}
Commonly used named colors include:
| Color name | General appearance |
|---|---|
black | Black |
white | White |
red | Bright red |
blue | Bright blue |
green | Darker standard green |
gray | Medium gray |
navy | Dark blue |
teal | Blue-green |
purple | Purple |
orange | Orange |
transparent | Fully transparent |
CSS color names are case-insensitive. However, lowercase values are usually preferred for consistency.
p {
color: DarkSlateGray;
}
The above declaration is valid, but this style is generally easier to maintain:
p {
color: darkslategray;
}
Hexadecimal Colors
Hexadecimal, or hex, colors begin with a hash symbol followed by red, green, and blue values.
p {
color: #336699;
}
The common six-digit format follows this structure:
#RRGGBB
Each pair represents one color channel:
RRrepresents red.GGrepresents green.BBrepresents blue.
The values range from 00 to FF.
.red-text {
color: #ff0000;
}
.green-text {
color: #008000;
}
.blue-text {
color: #0000ff;
}
Some colors can be written using a three-digit shorthand:
p {
color: #369;
}
This is equivalent to:
p {
color: #336699;
}
The shorthand works only when each pair contains two identical digits.
/* Valid shorthand for #ffffff */
color: #fff;
/* Valid shorthand for #aabbcc */
color: #abc;
Hex values are case-insensitive, but lowercase letters are commonly used.
Eight-Digit Hex Colors
An eight-digit hex value includes an alpha channel for transparency.
#RRGGBBAA
Example:
.overlay-text {
color: #00000080;
}
In this value:
#000000creates black.80gives it approximately 50% opacity.
A four-digit shorthand is also available:
p {
color: #0008;
}
This expands to:
p {
color: #00000088;
}
Alpha transparency can be useful, but partially transparent text may produce unpredictable contrast when its background changes.
RGB Colors
The rgb() function defines a color using red, green, and blue channels.
p {
color: rgb(51, 102, 153);
}
In the traditional comma-separated syntax, each channel usually ranges from 0 to 255.
.red {
color: rgb(255, 0, 0);
}
.black {
color: rgb(0, 0, 0);
}
.white {
color: rgb(255, 255, 255);
}
Modern CSS also supports a space-separated form:
p {
color: rgb(51 102 153);
}
Percentages may be used:
p {
color: rgb(20% 40% 60%);
}
RGB Colors with Transparency
An alpha value can be added to control opacity:
p {
color: rgb(0 0 0 / 70%);
}
The alpha value may be written as a number or percentage:
.example-one {
color: rgb(255 0 0 / 0.5);
}
.example-two {
color: rgb(255 0 0 / 50%);
}
The older rgba() notation is also widely recognized:
p {
color: rgba(0, 0, 0, 0.7);
}
Modern CSS treats rgb() and rgba() as closely related forms. The space-separated syntax with a slash is generally clearer in newer stylesheets.
HSL Colors
The hsl() function represents a color through hue, saturation, and lightness.
p {
color: hsl(210 50% 40%);
}
Its components are:
| Component | Meaning |
|---|---|
| Hue | Position on the color wheel |
| Saturation | Intensity of the color |
| Lightness | How light or dark the color appears |
Hue is usually expressed as an angle:
0degis red.60degis yellow.120degis green.180degis cyan.240degis blue.300degis magenta.
Example:
.red-text {
color: hsl(0 100% 50%);
}
.green-text {
color: hsl(120 100% 25%);
}
.blue-text {
color: hsl(240 100% 50%);
}
HSL is convenient when creating lighter, darker, or less saturated versions of the same color.
.heading {
color: hsl(220 70% 30%);
}
.secondary-text {
color: hsl(220 20% 45%);
}
HSL Colors with Transparency
Use a slash followed by an alpha value:
p {
color: hsl(220 70% 30% / 80%);
}
The older hsla() form is also supported:
p {
color: hsla(220, 70%, 30%, 0.8);
}
HWB Colors
The hwb() function defines color using hue, whiteness, and blackness.
p {
color: hwb(210 20% 30%);
}
The first value represents hue. The second adds whiteness, while the third adds blackness.
Transparency can also be included:
p {
color: hwb(210 20% 30% / 75%);
}
HWB can be intuitive when a designer wants to create softer or darker variations of a hue.
LAB and LCH Colors
Modern CSS provides perceptual color formats such as lab() and lch().
.lab-example {
color: lab(50% 40 30);
}
.lch-example {
color: lch(50% 50 40);
}
These formats are designed to make color adjustments more closely reflect how people perceive differences between colors.
LCH uses:
- Lightness
- Chroma
- Hue
Example:
.brand-text {
color: lch(48% 62 275);
}
Browser support should be considered when targeting older browsers.
OKLAB and OKLCH Colors
oklab() and oklch() offer improved perceptual uniformity and are especially useful in modern design systems.
.heading {
color: oklch(45% 0.18 250);
}
An alpha channel can be added:
.muted {
color: oklch(45% 0.05 250 / 70%);
}
oklch() can make it easier to generate visually consistent light and dark color variations.
:root {
--brand-dark: oklch(40% 0.18 250);
--brand-normal: oklch(55% 0.18 250);
--brand-light: oklch(70% 0.18 250);
}
Wide-Gamut Colors
The color() function can represent colors in spaces such as Display P3.
.highlight {
color: color(display-p3 0.9 0.2 0.1);
}
Wide-gamut colors may display more vivid tones on compatible screens. A fallback is helpful for browsers or displays that cannot reproduce the wider color range.
.highlight {
color: #e63322;
color: color(display-p3 0.9 0.2 0.1);
}
The browser uses the last supported declaration.
Applying Text Color to HTML Elements
Paragraph Text
p {
color: #333333;
}
A dark gray is often more comfortable than pure black on a white background.
Heading Text
h2,
h3 {
color: #173b64;
}
Link Text
a {
color: #005fcc;
}
Different link states can have different colors:
a:link {
color: #005fcc;
}
a:visited {
color: #6b3fa0;
}
a:hover {
color: #003f8a;
}
a:active {
color: #c62828;
}
Do not rely on color alone to identify links. Underlining or another visible cue makes links easier to recognize.
a {
color: #005fcc;
text-decoration: underline;
}
Button Text
button {
color: white;
background-color: #174ea6;
}
List Text
li {
color: #374151;
}
A list marker often follows the elements color value. It can also be styled separately:
li::marker {
color: #e11d48;
}
Table Text
table {
color: #222222;
}
th {
color: #ffffff;
background-color: #263b5e;
}
Form Text
input,
textarea,
select {
color: #1f2937;
}
Placeholder text requires its own pseudo-element:
input::placeholder,
textarea::placeholder {
color: #6b7280;
opacity: 1;
}
The opacity: 1 declaration may help create more consistent placeholder rendering across browsers.
Text Color and Background Color
The color property changes the foreground color. The background-color property changes the background.
.notice {
color: #7f1d1d;
background-color: #fee2e2;
}
These properties are independent:
.card {
color: #1f2937;
background-color: #f9fafb;
}
Always evaluate the two together because readable text needs sufficient contrast against its background.
Text Color Inheritance
The color property is inherited by default. Child elements usually receive the computed text color of their parent.
article {
color: #333333;
}
HTML:
<article>
<h2>Article heading</h2>
<p>Article paragraph.</p>
</article>
Unless another rule overrides the color, both the heading and paragraph inherit #333333.
Inheritance reduces repetition:
body {
color: #222222;
}
This establishes a default color for most text on the page.
A child can override the inherited value:
body {
color: #222222;
}
.special {
color: #b91c1c;
}
The currentColor Keyword
The currentColor keyword refers to the computed value of an elements color property.
.card {
color: #2563eb;
border: 2px solid currentColor;
}
Both the text and border become blue.
It can also be used for backgrounds, outlines, SVG fills, and shadows:
.icon-button {
color: #7c3aed;
border: 1px solid currentColor;
}
.icon-button svg {
fill: currentColor;
}
This technique keeps icons and decorative elements synchronized with nearby text.
CSS Global Values
The color property accepts CSS-wide keywords.
inherit
Forces the element to use its parents computed color:
button {
color: inherit;
}
This is useful because form controls may receive browser-specific default styling.
initial
Sets the property to its initial CSS value:
p {
color: initial;
}
For color, the initial value is typically represented by the browsers default canvas text color rather than a guaranteed literal black in every environment.
unset
Acts as inherit for inherited properties and initial for non-inherited properties. Since color is inherited, unset normally causes it to inherit:
.note {
color: unset;
}
revert
Returns the property to the value established by an earlier origin in the CSS cascade, such as browser or user styles:
a {
color: revert;
}
revert-layer
Reverts the value within the cascade-layer system:
.component-link {
color: revert-layer;
}
This is useful in stylesheets organized with @layer.
Using CSS Custom Properties for Text Colors
CSS custom properties make color systems easier to maintain.
:root {
--text-primary: #1f2937;
--text-secondary: #4b5563;
--text-muted: #6b7280;
--text-link: #005fcc;
--text-danger: #b42318;
}
Use them throughout the stylesheet:
body {
color: var(--text-primary);
}
.description {
color: var(--text-secondary);
}
.metadata {
color: var(--text-muted);
}
a {
color: var(--text-link);
}
.error-message {
color: var(--text-danger);
}
A fallback can be supplied:
p {
color: var(--article-text, #222222);
}
If --article-text is unavailable or invalid, #222222 is used.
Text Color in Light and Dark Themes
A good color system should work across different themes.
:root {
color-scheme: light;
--page-background: #ffffff;
--text-primary: #202124;
--text-secondary: #5f6368;
--link-color: #005fcc;
}
body {
color: var(--text-primary);
background-color: var(--page-background);
}
Dark theme:
[data-theme="dark"] {
color-scheme: dark;
--page-background: #121212;
--text-primary: #f1f5f9;
--text-secondary: #cbd5e1;
--link-color: #7db7ff;
}
A theme can also follow the operating system:
@media (prefers-color-scheme: dark) {
:root {
color-scheme: dark;
--page-background: #121212;
--text-primary: #f1f5f9;
--text-secondary: #cbd5e1;
--link-color: #7db7ff;
}
}
Avoid using the same text color in light and dark modes without checking contrast in both environments.
System Color Keywords
CSS supports system color keywords that adapt to the users environment.
body {
color: CanvasText;
background-color: Canvas;
}
Other examples include:
button {
color: ButtonText;
background-color: ButtonFace;
}
System colors can be valuable for accessibility and forced-color environments because they follow colors selected by the browser or operating system.
Text Color and Pseudo-Classes
Interactive text can change color according to its state.
.menu-link {
color: #334155;
}
.menu-link:hover {
color: #005fcc;
}
.menu-link:focus-visible {
color: #003f8a;
outline: 2px solid currentColor;
outline-offset: 3px;
}
Disabled elements can use a softer color:
button:disabled {
color: #767676;
background-color: #eeeeee;
cursor: not-allowed;
}
Make sure disabled text remains readable. Extremely pale gray text can be difficult to see.
Text Color and Pseudo-Elements
Pseudo-elements may receive their own colors.
blockquote::before {
content: "";
color: #9ca3af;
}
Selected text can also be styled:
::selection {
color: #ffffff;
background-color: #1d4ed8;
}
The text and background of selected content should remain clearly distinguishable.
Gradient Text
The color property accepts a solid color, not a gradient. Gradient text is generally created by applying a gradient background and clipping it to the text.
.gradient-text {
color: transparent;
background: linear-gradient(90deg, #7c3aed, #db2777);
background-clip: text;
-webkit-background-clip: text;
}
A fallback solid color should appear before the enhanced styling:
.gradient-text {
color: #7c3aed;
}
@supports (background-clip: text) {
.gradient-text {
color: transparent;
background: linear-gradient(90deg, #7c3aed, #db2777);
background-clip: text;
}
}
Gradient text should be used carefully. Complex gradients can reduce readability, especially on small text.
Text Color with text-shadow
A shadow does not replace the text color, but it can change how the text appears.
.hero-title {
color: white;
text-shadow: 0 2px 6px rgb(0 0 0 / 60%);
}
Text shadows sometimes improve visibility over images, but they are not a reliable substitute for a sufficiently contrasting background.
For dependable readability, consider adding a solid or translucent overlay behind the text.
Color and the CSS Cascade
If several rules set text color, CSS determines the winner through cascade origin, importance, cascade layers, specificity, scoping proximity, and source order.
p {
color: blue;
}
.article p {
color: green;
}
A paragraph inside .article becomes green because the second selector has greater specificity.
Inline CSS generally overrides ordinary stylesheet declarations:
<p style="color: red;">Red text</p>
Avoid excessive inline styling because it makes a site harder to maintain.
The !important flag should also be used sparingly:
p {
color: red !important;
}
A clear selector structure and reusable classes are usually better choices.
Accessibility and Color Contrast
Readable text needs sufficient contrast against its background. Contrast is especially important for users with low vision, color-vision differences, glare, poor-quality displays, or small mobile screens.
Under WCAG guidance, commonly used minimum contrast targets are:
| Text type | Minimum contrast |
|---|---|
| Normal text | 4.5:1 |
| Large text | 3:1 |
| Enhanced target for normal text | 7:1 |
| Enhanced target for large text | 4.5:1 |
Large text generally means at least:
- 18-point regular text, or
- 14-point bold text
In CSS, these sizes are approximately 24px and 18.67px respectively when standard conversions apply.
Example of a readable combination:
body {
color: #222222;
background-color: #ffffff;
}
A potentially weak combination:
p {
color: #bbbbbb;
background-color: #ffffff;
}
Do Not Communicate Meaning Through Color Alone
This error message uses color, text, and a visible border:
.error {
color: #9f1239;
background-color: #fff1f2;
border-left: 4px solid currentColor;
padding: 0.75rem;
}
HTML:
<p class="error">
Error: Enter a valid email address.
</p>
The word Error communicates meaning even if the user cannot distinguish the color.
The same principle applies to:
- Form validation
- Status badges
- Charts
- Required fields
- Success messages
- Warning notices
- Selected navigation items
Check Every Interaction State
Links, buttons, focus states, hover states, and visited links all need appropriate contrast.
a {
color: #005fcc;
}
a:hover,
a:focus-visible {
color: #003f88;
}
Do not make hover color the only signal of interactivity. Keyboard users may never activate the hover state.
Forced-Colors and High-Contrast Modes
Some users enable forced-color or high-contrast modes. In these environments, the browser may replace authored colors with system colors.
@media (forced-colors: active) {
.notice {
color: CanvasText;
background-color: Canvas;
border: 1px solid CanvasText;
}
}
Avoid disabling these adjustments unless there is a strong accessibility reason. Browser and operating-system color overrides are often essential to the user.
Common Mistakes
Forgetting the Hash in a Hex Value
Incorrect:
p {
color: ff0000;
}
Correct:
p {
color: #ff0000;
}
Confusing color with background-color
p {
color: white;
background-color: black;
}
color affects the text. background-color affects the area behind it.
Applying Color to the Wrong Selector
.article {
color: #333333;
}
This works through inheritance, but a more specific child rule may override it:
.article p {
color: #666666;
}
Use browser developer tools to inspect which declaration is active.
Using an Invalid Color Value
p {
color: blue-green;
}
Because blue-green is not a valid named color, the browser ignores the declaration.
Use a supported format:
p {
color: #0d9488;
}
Using Low-Contrast Gray Text
Light gray text may look elegant on a design mockup but become difficult to read on real screens.
/* Often too faint on white */
p {
color: #c4c4c4;
}
Choose the color only after checking its contrast against the actual background.
Applying Opacity to the Entire Element
.card {
opacity: 0.5;
}
This reduces the opacity of the text, background, border, and all descendants.
If only the text should be transparent, include alpha in the color:
.card {
color: rgb(0 0 0 / 50%);
}
Be aware that the resulting contrast depends on whatever appears behind the text.
Making Links Indistinguishable from Normal Text
a {
color: inherit;
text-decoration: none;
}
This may hide the visual difference between links and ordinary text. If inherited color is necessary, keep another visible indication:
a {
color: inherit;
text-decoration: underline;
text-underline-offset: 0.15em;
}
Overusing Bright Colors
Highly saturated colors can cause visual fatigue when used for long paragraphs. Reserve strong colors for links, calls to action, short headings, and status messages.
For body text, neutral dark tones usually provide better reading comfort.
Practical Text Color System
A small, consistent palette is easier to maintain than unrelated color values scattered throughout a stylesheet.
:root {
--color-text: #1f2937;
--color-text-secondary: #4b5563;
--color-text-muted: #6b7280;
--color-heading: #111827;
--color-link: #005fcc;
--color-link-hover: #003f88;
--color-success: #166534;
--color-warning: #92400e;
--color-danger: #991b1b;
}
Usage:
body {
color: var(--color-text);
}
h2,
h3 {
color: var(--color-heading);
}
.subtitle {
color: var(--color-text-secondary);
}
.date,
.author,
.caption {
color: var(--color-text-muted);
}
a {
color: var(--color-link);
}
a:hover {
color: var(--color-link-hover);
}
.success-message {
color: var(--color-success);
}
.warning-message {
color: var(--color-warning);
}
.error-message {
color: var(--color-danger);
}
This approach improves consistency and makes future redesigns easier.
Responsive Text Color
Text color itself does not usually need to change according to screen size. However, different layouts or backgrounds may require adjustments.
.hero {
color: #1f2937;
background-color: #f8fafc;
}
@media (min-width: 768px) {
.hero {
color: #ffffff;
background-color: #1e3a8a;
}
}
Whenever a responsive layout changes the background, verify the text contrast again.
Example: Readable Article Styling
HTML:
<article class="article">
<p class="article-meta">Updated August 31, 2026</p>
<h2>Understanding CSS Text Color</h2>
<p>
CSS provides several ways to control the foreground color of text.
A clear color system improves readability and visual consistency.
</p>
<p class="article-note">
Remember to test the contrast between the text and its background.
</p>
<a href="#">Read the accessibility guide</a>
</article>
CSS:
.article {
color: #28313d;
background-color: #ffffff;
line-height: 1.7;
}
.article h2 {
color: #102a43;
}
.article-meta {
color: #667085;
}
.article-note {
color: #7c2d12;
background-color: #fff7ed;
border-left: 4px solid currentColor;
padding: 1rem;
}
.article a {
color: #005fcc;
text-decoration-thickness: 0.1em;
text-underline-offset: 0.15em;
}
.article a:hover,
.article a:focus-visible {
color: #003f88;
}
Best Practices
Follow these principles when selecting CSS text colors:
- Establish a default text color on the
bodyelement. - Use reusable custom properties for important colors.
- Keep body text neutral and comfortable to read.
- Maintain sufficient contrast against every background.
- Check colors in both light and dark themes.
- Do not communicate meaning through color alone.
- Preserve visible focus styles for keyboard users.
- Keep links recognizable through more than color.
- Use alpha transparency cautiously.
- Test text over images and gradients in multiple conditions.
- Consider forced-color and high-contrast modes.
- Use
currentColorto coordinate borders, icons, and decorations. - Avoid unnecessary
!importantdeclarations. - Test the final design on mobile devices and different displays.
Frequently Asked Questions
Which CSS property changes text color?
The color property changes the foreground color of text.
p {
color: blue;
}
What is the default text color in CSS?
The initial value of color is the systems canvas text color. Browsers commonly render ordinary text as black or a very dark color in a standard light theme, but authors should not assume that it will always be literal black.
Can CSS text color use transparency?
Yes. Use an alpha-enabled format such as:
p {
color: rgb(0 0 0 / 70%);
}
Eight-digit hex, HSL, HWB, LAB, LCH, OKLAB, and OKLCH formats may also include alpha transparency.
Does the color property inherit?
Yes. Child elements normally inherit their parents computed text color unless another rule overrides it.
How can I change only one words color?
Wrap the word in a <span> and apply a class:
<p>This word is <span class="highlight">important</span>.</p>
.highlight {
color: #b91c1c;
}
How do I change text color on hover?
Use the :hover pseudo-class:
a:hover {
color: #c2410c;
}
Also provide an accessible focus style for keyboard navigation.
a:focus-visible {
color: #c2410c;
outline: 2px solid currentColor;
}
Can the color property create gradient text?
No. The property represents a color, not an image gradient. Gradient text is generally created with a gradient background and background-clip: text.
Why is my CSS text color not working?
Possible reasons include:
- Another selector has greater specificity.
- An inline style overrides the rule.
- Another declaration uses
!important. - The color value is invalid.
- The stylesheet is not loaded.
- The selector does not match the intended element.
- A state selector such as
:visitedoverrides the color. - The browser is using forced-colors mode.
- The declaration is crossed out by the cascade.
Browser developer tools can reveal the active and overridden declarations.
Should body text be pure black?
Pure black on white provides strong contrast, but a very dark gray can sometimes feel visually softer while remaining accessible. The best choice depends on the background, font, size, weight, and overall design.
Conclusion
CSS text color is controlled primarily through the color property. It supports simple named colors, hexadecimal values, RGB, HSL, HWB, modern perceptual formats, wide-gamut colors, system colors, transparency, inheritance, and custom properties.
Effective text coloring is not only about visual appeal. It must also support readability, consistent branding, clear interaction states, dark mode, and accessibility. A carefully planned color system makes a website easier to read, easier to maintain, and more comfortable for a wider range of users.