CSS Opacity
Opacity controls how transparent or see-through an element is. A fully opaque element blocks everything behind it; a fully transparent element is invisible. CSS gives you two tools to control this: the opacity property and the alpha channel in color values.
The opacity Property
The opacity property accepts a value between 0 and 1.
opacity: 1— fully visible (default)opacity: 0.5— 50% transparentopacity: 0— completely invisible
DIAGRAM — Opacity levels:
opacity: 1.0 ████████████ ← Fully visible (solid)
opacity: 0.7 ▓▓▓▓▓▓▓▓▓░░ ← Mostly visible
opacity: 0.5 ▓▓▓▓▓▓░░░░░ ← Half transparent
opacity: 0.3 ▓▓▓░░░░░░░░ ← Mostly transparent
opacity: 0 ░░░░░░░░░░░ ← Completely invisible
.card {
background: darkblue;
color: white;
opacity: 0.8;
}
opacity Affects the Whole Element and Its Children
This is the key behavior to understand. When you set opacity on an element, it makes the element AND all its children transparent together. The children cannot override this — they inherit the transparency even if they have their own opacity set to 1.
DIAGRAM — opacity on parent affects children:
.box { opacity: 0.5; background: blue; }
└── p { opacity: 1; color: white; }
Result:
Both the blue box AND the white text
are at 50% transparency.
You cannot make the text fully opaque
while the box is transparent.
<div class="overlay">
<p>This text is also 50% transparent</p>
</div>
.overlay {
opacity: 0.5;
background: black;
}
Alpha Transparency — Transparent Colors Only
If you want only the background to be transparent (without affecting the text), use an alpha value inside a color function instead of the opacity property.
rgba()
/* rgba(red, green, blue, alpha) */
/* Alpha: 0 = transparent, 1 = opaque */
.box {
background: rgba(0, 0, 0, 0.5); /* 50% transparent black */
color: white; /* Text stays fully opaque */
}
DIAGRAM — opacity vs rgba:
Using opacity: 0.5 on a dark box:
┌─────────────────┐
│ Hello World │ ← text is also 50% see-through
└─────────────────┘
Using rgba(0,0,0,0.5) on background:
┌─────────────────┐
│ Hello World │ ← text is fully opaque
└─────────────────┘
(The box is semi-transparent, text is not)
hsla()
HSLA works like HSL colors but with an added alpha channel.
/* hsla(hue, saturation, lightness, alpha) */
.highlight {
background: hsla(200, 80%, 50%, 0.3); /* 30% transparent blue */
}
Hex with Alpha (#RRGGBBAA)
Modern CSS supports 8-digit hex codes where the last two digits control transparency.
#3498dbff → fully opaque (ff = 255 = 100%)
#3498db80 → 50% transparent (80 = 128 ≈ 50%)
#3498db00 → fully transparent (00 = 0 = 0%)
.card {
background: #3498db99; /* Blue at ~60% opacity */
}
Real Use Cases for Opacity
Disabled State
button:disabled {
opacity: 0.4;
cursor: not-allowed;
}
Hover Effect
.thumbnail {
opacity: 1;
transition: opacity 0.3s;
}
.thumbnail:hover {
opacity: 0.75;
}
Overlay on Images
.image-wrapper {
position: relative;
}
.image-wrapper::after {
content: "";
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.4); /* Dark overlay, image shows through */
}
Glass Morphism Effect
.glass-card {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.3);
}
Loading / Skeleton Screens
.loading {
opacity: 0.4;
pointer-events: none; /* Also disable clicks */
}
Invisible vs Hidden vs Transparent
DIAGRAM — Three ways to "hide" an element:
opacity: 0 → Element is invisible, still takes up space,
still receives mouse clicks
visibility: hidden → Element is invisible, still takes up space,
does NOT receive mouse clicks
display: none → Element is gone completely, no space,
no clicks, not rendered at all
| Method | Visible | Takes Space | Clickable |
|---|---|---|---|
| opacity: 0 | No | Yes | Yes |
| visibility: hidden | No | Yes | No |
| display: none | No | No | No |
Animating Opacity
Opacity is one of the best properties to animate because browsers handle it with GPU acceleration. It is much smoother than animating width or height.
.toast {
opacity: 0;
transition: opacity 0.5s ease;
}
.toast.visible {
opacity: 1;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.hero-text {
animation: fadeIn 1s ease-out;
}
Quick Reference
| Goal | Best Approach |
|---|---|
| Make whole element + children transparent | opacity: 0.5 |
| Make only background transparent | background: rgba(..., 0.5) |
| Transparent color in text | color: rgba(..., 0.5) |
| Transparent border | border-color: rgba(..., 0.3) |
| Fade animation | transition on opacity |
The key rule to remember: use opacity when you want the whole element (including text) to be transparent together. Use rgba() or hsla() on individual color properties when you want only the background, border, or text color to be transparent while the rest stays solid.
