Menu

CSS Opacity: Transparent Elements, Backgrounds and Fades

opacity makes a whole element and everything inside it see-through, from 0 (invisible) to 1 (solid). Learn the values, why opacity fades the text too and how to make only the background transparent, opacity: 0 vs visibility vs display, and fading on hover.

This page includes runnable editors - edit, run, and see output instantly.

What opacity does

opacity sets how see-through an element is: 1 is solid (the default), 0 is invisible, and anything in between lets the background show through. The boxes below sit on a striped background so you can see it:

The last box is still there: it takes its 90px slot in the row, it just draws nothing. Notice that the white numbers fade with their boxes. opacity applies to the element and everything inside it.

Transparent background, solid text

Because opacity fades the children too, it is the wrong tool for "a see-through background behind readable text". Use a background color with an alpha channel instead:

Both white panels let the stripes show through by the same amount. In the first, the text is faded along with the panel. In the second only the background color is transparent (rgb(255 255 255 / 0.6), the same as rgba(255, 255, 255, 0.6)), so the text stays solid and easy to read. Colors with alpha are covered on the colors page.

A child cannot escape its parent's opacity: opacity: 1 on the child does nothing, because the parent is drawn as one faded layer with the child already inside.

Values

ValueResult
1 or 100%fully opaque (default)
0.5 or 50%half transparent
0 or 0%fully transparent, still in the layout and clickable
1.5, -1clamped to 1 and 0

Opacity is inherited visually but not as a property: a child's computed opacity stays 1, while it is drawn inside a faded parent.

opacity: 0 vs visibility: hidden vs display: none

All three make an element disappear, but they differ in everything else:

opacity: 0visibility: hiddendisplay: none
Takes up spaceyesyesno
Receives clicks and focusyesnono
Read by screen readersyesnono
Can be transitionedyes, smoothlyswitches at one end, no fadeno

The difference that bites is the second row. A button at opacity: 0 can still be clicked and tabbed to:

The readout asks the browser which element is under a point inside each hidden button. The opacity: 0 button answers "clickable"; the visibility: hidden one does not. The Visible button starts after two empty 150px slots, because the display: none button is the only one that gave its space back. To fade something out and then take it away, animate opacity and set visibility: hidden at the end.

Fading on hover

opacity is one of the cheapest properties to animate, so it is the standard way to fade things in and out. A caption that appears over an image:

:focus-within shows the caption to keyboard users too. Keep in mind the table above: while invisible, the caption is still read by screen readers, which is what you want for a caption.

Accessibility: faded text loses contrast

Lowering opacity lowers contrast. Gray text on white at opacity: 0.5 can drop well below the 4.5:1 ratio body text needs. For secondary text, pick a color that passes contrast rather than fading a dark one. For disabled controls, reduced opacity is a common signal, but pair it with the disabled attribute so the control is also unreachable by keyboard and announced as disabled.

Side effect: stacking context

Any opacity below 1 creates a new stacking context, like transform does. Children with a high z-index then stack only inside the faded element and cannot rise above elements outside it. If a dropdown inside a faded panel slides under another element, this is the reason (the z-index page explains stacking).

Common mistakes

  • Fading a card to make its background transparent. The text fades too. Use rgb(... / 0.5) on the background.
  • Trying to make a child opaque again. A parent's opacity limits every child.
  • Hiding with opacity: 0 alone. The element still takes clicks and focus. Add visibility: hidden, or use display: none (pointer-events: none stops clicks but not keyboard focus).
  • Writing opacity: 50. Opacity is 0 to 1; 50 is clamped to 1. Write 0.5 or 50%.
  • Low-contrast text through opacity. Check the contrast of the result, not of the original color.

Frequently Asked Questions

What does opacity do in CSS?

It sets how see-through an element is, from 0 (fully transparent) to 1 (fully opaque). It applies to the whole element, including its text, border, images and every child, as one flattened layer.

How do I make only the background transparent, not the text?

Leave opacity alone and give the background a color with alpha: background-color: rgb(37 99 235 / 0.5); or rgba(37, 99, 235, 0.5). The text and children stay fully opaque.

Can a child element be more opaque than its parent?

No. A parent's opacity applies to the whole group, so opacity: 1 on a child cannot undo it. A child of a parent at 0.5 is drawn at most at half opacity. Move the transparency to the parent's background color instead.

What is the difference between opacity: 0, visibility: hidden and display: none?

opacity: 0 hides the element but it still takes up space, can be clicked, and is read by screen readers. visibility: hidden keeps the space but is not clickable or read. display: none removes it from the layout entirely.

Can opacity be a percentage?

Yes. opacity: 50% is the same as opacity: 0.5 in all current browsers. Values below 0 or above 1 are clamped to that range.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED