Opacity precision

Opacity is usually measured as a percentage in design tools, with zero percent being fully transparent, and one hundred percent being fully opaque.

While easy to understand, using integer percentages for opacity does not map well to what typically happens at a technical level — opacity values in 8bit per channel images have a range of 0 to 255. A design tool that uses a 0 to 100 range for opacity can not access 154 of the actual possible values. The percentages just get rounded to the nearest real value.

The animation below shows opacity with a 0 to 100 range mapped to 8bit values on top, and a 0 to 255 range below. The top slider skips many of the available steps. These values are simply impossible in tools that use integer percentages for opacity.

There are more missing steps than there are actual steps! This is an arbitrary limitation, and one that is just due to following traditions set in older design tools. There’s no real reason to not support the full range of possible 8bit opacities, or even more steps to cover wide gamut colour spaces and higher bit depths.

Does it matter? Quite often, shadows are incredibly sensitive to opacity changes, and many shadows use values from around 5% to 20%. That means there’s only 15 or so steps in the usable range, and single step jumps can be quite noticeable. This is not the most pressing issue in the design tools we use, but it is a real problem.

An easy solution is to stick with percentages, but allow fractional opacity values. Figma accepts up to two decimal places in its opacity text fields, providing 10,001 possible steps (0.00 to 100.00). That’s plenty for most uses. All the other tools I tested use integer percentages, so this problem is prevalent across almost the entire industry.

Slider length #

Another common issue is opacity sliders not being long enough to set the complete range of possible values. For an opacity slider to provide 101 steps, it needs to be at least 101 pixels wide (101 steps, because 0 and 100 are included in the range). For a slider to provide 256 steps, it needs to be at least 256 pixels wide. Mouse cursor precision is also a factor. Many design tool interfaces are only accurate to a macOS point, which means their smallest jump is 2 pixels on a Retina screen. Given they skip every other pixel, their sliders need to be twice as wide to be able to address each possible value.

This phenomenon can be seen in Photoshop’s layer opacity slider. The slider drag range itself is 184px wide on a Retina display, but mouse interactions jump in 2px increments. That means some opacity values simply can not be reached — 6%, 19%, 31%, 44%, 56%, 69%, 81%, and 94%. It doesn’t matter how hard you try, you just can not set 6% layer opacity via the slider in Photoshop (tested on a Mac with Photoshop’s default UI scale).

Photoshop’s opacity slider can not be set to 6%

Opacity precision comparison #

Different tools have different places where opacity values and sliders appear, so I tried to include a good representation of where they can be found in each tool. The common places are layer opacity, object opacity, colour opacity, and layer style opacity.

The table below is ranked vaguely from best to worst. Figma takes the top spot, because its sliders can reach all the values from 0 to 100, and the text fields are precise enough to easily cover 0 to 255 and beyond. Interestingly, Illustrator’s slider UI jumps in 2px increments, but the actual slider accuracy is 1px.

A comparison of opacity sliders across common design tools

The situation should be fairly easy to improve by adding support for fractional opacity values, and making some sliders slightly longer.

Published 6 December 2021.