Color transparency
Transparency says how much of the background should show through a pixel. Formats handle it in two ways: either a pixel is fully transparent or not (GIF), or it has a smooth degree of opacity, an alpha channel (PNG, WebP, AVIF).
Binary transparency in GIF
GIF has no alpha channel. Instead, one palette index can be marked transparent. The graphic control extension ($F9) does this: one bit turns transparency on and one byte gives the color index. Pixels with that index are not drawn, so whatever was underneath shows through.
The drawback: an edge is either opaque or transparent. An antialiased text edge prepared on a white background has pixels between the text color and white. On a dark background those pixels form a light fringe (a halo).
The alpha channel
The alpha channel is a fourth pixel component, α, from 0 (fully transparent) to 1 (opaque). PNG stores it either as a full channel in RGBA or, for palette images, as a tRNS chunk with a separate α for each palette entry.
Compositing a pixel onto a background is described by the "over" operator (Porter and Duff, 1984):
Example: 50% opacity on white and black
#c85028 with α = 0.5:
The difference is clear, especially on black. Compositing in linear light is the physically correct one (see gamma correction). Browsers and CSS composite on sRGB values by default, though, so designers are used to that look. What matters is sticking to one method within a project.
Premultiplied alpha
Many programs store color already multiplied by α: instead of (R, G, B, α) they keep (α·R, α·G, α·B, α). The "over" formula then simplifies to:
Advantages: faster compositing, and correct resizing and blurring (transparent pixels do not "leak" their color into neighbors). Drawback: at small α, color precision is lost. PNG always stores alpha non-premultiplied, so programs convert it on load.
Where halos come from
- A GIF antialiased against a specific background and placed on another: the in-between pixels carry the old background color.
- Resizing an alpha image without premultiplication: the color in fully transparent pixels (often black) mixes with neighbors and the edge darkens.
- Saving to JPEG, which has no transparency: transparent pixels turn into whatever color they happened to hold, usually black or white.