Skip to content

CSS Background Color Generator

Pick a background colour or paste any CSS colour, set its opacity, and get a readable text colour with it. Add a hover shade and a dark-mode colour if you need them, then copy the CSS.

Preview

On the pagepage #FFFFFF
Sample heading

Body text at 14px. Hover this box to see the hover colour.

Text contrast 5.17:1 · AA

Write colours as
CSS
.box {
  background-color: #2563EB;
  color: #FFFFFF;
}

.box:hover {
  background-color: #1F55CC; /* color-mix(in oklab, #2563EB, black 10%) */
}
The background in other formats
  • HEX#2563EB
  • RGBrgb(37 99 235)
  • RGB (legacy commas)rgb(37, 99, 235)
  • HSLhsl(221.2 83.2% 53.3%)
  • OKLCHoklch(54.6% 0.215 262.9)

How background-color paints

Facts about the CSS background-color property
background-color
Starting valuetransparent, so the parent's background shows through
Inherited?No. Children look the same colour only because they are see-through
Area paintedUnder the content, padding and border (background-clip: border-box)
StackingAlways below any background-image on the same element
On html or bodyFills the whole browser window, not just the element's height
Animatable?Yes; transition: background-color 0.2s fades between colours

Two of those catch people out. Because the colour runs under the border, a dashed or semi-transparent border shows the background between its dashes; add background-clip: padding-box to stop at the border. And the page background is special: a colour set on html, or on body when html has none, is used for the whole canvas, which is why a short page still has its background colour all the way down.

Colour formats you can use

CSS colour formats for background-color
FormatExampleOpacity
HEX#2563EB8-digit form: #2563EB80
rgb()rgb(37 99 235)rgb(37 99 235 / 50%)
hsl()hsl(221 83% 53%)hsl(221 83% 53% / 0.5)
oklch()oklch(54.6% 0.215 262.9)/ 50%; Chrome 111, Firefox 113, Safari 15.4
hwb()hwb(221 15% 8%)/ 50%; Chrome 101, Firefox 96, Safari 15
NamedrebeccapurpleNo; 148 names plus transparent

All of these can carry opacity. The space-separated rgb(37 99 235 / 50%) form works in every current browser, and rgba() is now just another name for rgb(). The box above accepts every format in the table and also strips a pasted background-color: prefix. For converting long lists of codes, the HEX to RGB and RGB to HEX converters show the channel maths; for blends of several colours, use the CSS gradient generator.

Translucent backgrounds

A background with opacity below 100% is blended with whatever is behind it, channel by channel:

shown = colour × alpha + behind × (1 − alpha)

Navy rgb(15 23 42 / 50%) over a white page gives red 15 × 0.5 + 255 × 0.5 = 135, green 139 and blue 148.5, so it shows as #878B95, a mid grey-blue rather than navy. Over a dark page the same value stays almost navy. The preview reports the colour actually seen, and the text check uses it, so set "Page colour behind it" to whatever the element will sit on.

Opacity on the colour is not the same as the opacity property. opacity: 0.5 fades the whole element, text, icons and borders included; a translucent background-color fades only the fill and leaves the text at full strength.

Choosing the text colour

With "black or white" selected, the tool works out the contrast ratio of each against the background as it appears and picks the higher one. The two tie when the background's relative luminance is about 0.179. Lighter than that, black text wins; darker, white wins.

Mid greys show how close it gets. On #767676 black text scores 4.62:1 and white 4.54:1; both pass the 4.5:1 that WCAG asks for body text, and black only just comes out ahead. On #808080 black is clearly better (5.32:1 against 3.95:1, which fails for body text). On the default blue, #2563EB, white scores 5.17:1 and black 4.06:1.

WCAG 2 contrast levels for text
RatioNormal textLarge text (24px, or 18.66px bold)
7:1 or moreAAAAAA
4.5:1 to 7:1AAAAA
3:1 to 4.5:1FailsAA
Below 3:1FailsFails

A dark-mode background

Tick "Dark-mode colour" to give the element a second background for people whose system is set to dark. The export can do this two ways:

  • light-dark(light, dark) picks one of two colours inside a single declaration. It only works once color-scheme: light dark is set, so the export adds that to :root, and it writes a plain line first for browsers that do not know the function.
  • @media (prefers-color-scheme: dark) repeats the rule inside a media query. It is longer but works in every browser that supports dark mode at all.

color-scheme also matters on its own: with it set, the browser darkens its own parts (the default page, scrollbars and form controls), so a dark background is not left surrounded by white inputs.

Hover and active shades

The hover colour is the background mixed with black (or white, for "lighter") in OKLab, the same sum as color-mix(). For #2563EB and 10%:

background-color: #1F55CC; /* color-mix(in oklab, #2563EB, black 10%) */

The export writes the finished colour and keeps the color-mix() version as a comment, so it works everywhere. Mixing in OKLab darkens evenly; mixing in sRGB with black can make blues and purples look dull and greyish. If your colours live in custom properties, you can let the browser do the sum, or use relative colour syntax to change one channel:

.button:hover { background-color: color-mix(in oklab, var(--brand), black 10%); }
.button:active { background-color: oklch(from var(--brand) calc(l - 0.1) c h); }
Browser support for newer colour functions
FeatureChrome / EdgeFirefoxSafari
color-scheme819613
color-mix()11111316.2
light-dark()12312017.5
Relative colour syntax (oklch from …)12212818

When the background does not show

Common reasons a background colour does not appear
SymptomLikely causeFix
Nothing appearsThe element has no height: its children are floated or absolutely positioneddisplay: flow-root, or give it a height
Your colour is ignoredA later background: shorthand reset it, or a more specific selector winsCheck the Styles panel in DevTools for a struck-through line
Colour stops at the contentAn inline element such as span only paints behind its textdisplay: block or inline-block, plus padding
Gap at the page edgesThe browser's default 8px body marginbody { margin: 0 }
Paler than expectedOpacity below 100%, or an opacity property on a parentCompare with the "looks like" colour above

Frequently asked questions

background or background-color?

background-color sets only the colour. background is a shorthand that also resets the image, position, size and repeat, so a later background: line will wipe out an image set earlier. Use background-color when the colour is all you are changing.

How do I set the background of the whole page?

Put it on body (or html). The browser uses it for the entire window, even when the content is shorter than the screen. Remove body’s default 8px margin if the colour should reach the edges.

Can I give a background colour to only part of an element?

Not with background-color; it always fills the box. Use a gradient with hard stops, such as linear-gradient(90deg, #2563EB 30%, transparent 30%), or a pseudo-element.

Is 8-digit HEX safe to use?

Yes. #RRGGBBAA has worked in all major browsers since about 2017 (Chrome 62, Firefox 49, Safari 10). The last two digits are the opacity: 80 is about 50%, CC about 80%.

Why does the hover colour go lighter in dark mode?

On a dark background, darkening is hard to see, so most interfaces lighten on hover instead. The tool reverses the direction for the dark-mode colour; change the amount slider if you want it the other way.

Does the text colour here follow WCAG?

The contrast ratio uses the WCAG 2 formula on the colour as it appears on your page colour. It is the starting point; check the final page too, especially if images or gradients sit behind the element.

Sources