Guide

RGBA & Alpha Transparency in CSS

Alpha looks simple — a fourth number between 0 and 1 — but the way it composites against whatever sits behind it has practical consequences for color choice, accessibility, and performance.

Last reviewed on 2026-05-09

RGBA in one paragraph

RGBA stands for red, green, blue, and alpha. The first three channels are the same 0–255 values you'd write in rgb(). The fourth, alpha, is a number from 0 (fully transparent) to 1 (fully opaque). In CSS:

background: rgba(108, 92, 231, 0.4);
/* modern equivalent */
background: rgb(108 92 231 / 0.4);

The home converter shows the RGBA chip alongside HEX, RGB, and HSL — every color you type out includes its 1.0-alpha RGBA form by default.

What alpha actually does

Alpha is not opacity in the loose sense. It is a blending coefficient. When the browser paints a semi-transparent pixel, it computes:

result = (alpha × foreground) + ((1 − alpha) × background)

Per channel. So rgba(255, 0, 0, 0.5) over a white background gives rgb(255, 128, 128), not "half-strength red." The visual color depends on whatever is behind the element. This is why the same RGBA value can look completely different on a dark page versus a light one.

This compositing happens for every pixel of every overlapping layer. A semi-transparent button on a semi-transparent card on a gradient background runs the formula three times, in order, from back to front.

RGBA vs the opacity property

RGBA sets the alpha of one specific color value. The opacity CSS property sets the alpha of the entire element and everything inside it, including text, child elements, borders, and backgrounds.

A common mistake: setting opacity: 0.6 on a card to mute the background, then wondering why the text is hard to read. The fix is to keep the text at full opacity and only soften the background using RGBA.

RGBA vs 8-digit hex (#RRGGBBAA)

Modern CSS accepts an 8-digit hex code, where the last two characters encode alpha as a hexadecimal byte from 00 (transparent) to FF (opaque):

background: #6C5CE740;   /* alpha = 0x40 = 64/255 ≈ 0.25 */
background: #6C5CE7CC;   /* alpha = 0xCC = 204/255 = 0.8 */

Both notations produce identical pixels. Trade-offs:

RGBA8-digit hex
ReadabilityDecimal alpha (0.4) is easy to reason about.Hex alpha is opaque without a lookup.
ToolingUniversally supported in design apps.Some older tools do not export 8-digit hex.
DiffingOne change — the last argument.One change — the last two characters.
ConversionSame as RGB plus a decimal.Multiply alpha by 255, then convert to hex.

For a handful of common values: 0.1 ≈ 1A, 0.25 ≈ 40, 0.5 = 80, 0.75 ≈ BF, 0.9 ≈ E6.

When to reach for transparency

Where transparency hurts

Accessibility

The contrast checker on the home page assumes solid colors. The moment alpha is involved, the actual contrast ratio depends on what shows through. For text-on-background combinations, always compute the contrast against the resolved color (the foreground composited onto the actual background), not against the half-transparent foreground. The safer rule: keep text fully opaque, and reserve transparency for purely decorative elements.

Performance

Translucent layers force the browser to alpha-composite. On a static page this is invisible. On a page with dozens of overlapping translucent panels, large blurred backdrops, or animations on transparent elements, the cost adds up — especially on mobile GPUs. If a section is suddenly janky after adding a frosted-glass effect, suspect the compositor.

Print and screenshots

Some print engines and older PDF tools flatten transparency in unpredictable ways. If a page is intended to be exported as PDF or printed, test the result, or supply a flat fallback color in a print stylesheet.

Choosing an alpha value

A practical scale that covers most UI work:

Working with alpha in code

JavaScript has direct access to the four channels through canvas APIs. Reading a pixel from a <canvas> returns four entries — R, G, B, A — each from 0 to 255. To convert a UI alpha to canvas alpha, multiply the 0–1 value by 255 and round.

const ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgba(108, 92, 231, 0.4)';
ctx.fillRect(0, 0, 100, 100);
const pixel = ctx.getImageData(50, 50, 1, 1).data;
// pixel = [108, 92, 231, 102]  (102 ≈ 0.4 × 255)

Common mistakes

Quick reference