Daltonize CSS Filter Generator
Generate a real colour-matrix filter you can drop into any page — either to correct colours for a given deficiency, or to simulate one. Copy the SVG, reference it from CSS, done.
Model: Viénot 1999 — reproduces this site’s simulator exactly.
Preview
Top row is the original, bottom row is the filter applied. Computed with the same matrix in the same colour space the browser uses, so what you see here is what the copied filter does.
Generated code
<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"
style="position:absolute;width:0;height:0;overflow:hidden">
<defs>
<!-- linearRGB is required: the model is defined on linear light. -->
<filter id="daltonize-deuteranopia" color-interpolation-filters="linearRGB">
<feColorMatrix type="matrix" values="
0.79507 0.20492 0 0 0
0 1 0 0 0
-0.20492 0.20492 1 0 0
0 0 0 1 0" />
</filter>
</defs>
</svg>.cvd-preview {
filter: url(#daltonize-deuteranopia);
}The color-interpolation-filters="linearRGB" attribute is not optional. These matrices are defined on linear light; drop it and the browser may apply them to gamma-encoded values, which produces a visibly different and incorrect result.
Method
Why This Is an SVG Filter and Not a CSS One
CSS filter functions cannot express what a colour vision transform actually is.
Search for a colour blindness CSS filter and you will find recipes built from hue-rotate(), saturate() and sepia(). They cannot be right, and the reason is structural rather than a matter of tuning.
Simulating a colour vision deficiency means taking the red, green and blue components of a colour and producing three new ones, where each output depends on all three inputs. That is a 3×3 matrix. CSS hue-rotate() is a rotation in a fixed plane, saturate() scales toward grey — neither can produce the asymmetric channel mixing a cone deficiency causes. Stacking them gets closer in some hues and further in others.
SVG has the right primitive: <feColorMatrix> takes exactly the matrix the model specifies. CSS can reference it with filter: url(#id), so you still write one line of CSS — the matrix just lives in an SVG block instead of being approximated by stacked functions.
Correcting composes into one matrix too
Daltonisation works by finding the information a deficiency discards and pushing it into channels that viewer can still see. Written out, the corrected colour is the original plus a redistribution of the difference between the original and the simulated version. Because simulation is itself a matrix, the whole correction collapses algebraically into a single matrix — so correcting costs exactly one filter pass, not three.
Linear light, which is where this usually goes wrong
These matrices are defined on linear RGB, not on the gamma-encoded values a colour picker shows you. SVG filters default to linear, but the generated code states color-interpolation-filters="linearRGB" explicitly rather than trusting the default. Omit it and the transform is applied in the wrong space: the result still looks like “something colour-blindness-ish”, which is exactly what makes the mistake so easy to ship.
| Vision type | Model | Fidelity |
|---|---|---|
| Protanopia | Viénot 1999 | Exact — a single matrix by construction |
| Deuteranopia | Viénot 1999 | Exact — a single matrix by construction |
| Protanomaly | Machado 2009 | Exact — matrices published per severity |
| Deuteranomaly | Machado 2009 | Exact — matrices published per severity |
| Tritanopia | Brettel 1997 | Approximate — the model is piecewise, so a constrained least-squares matrix is used instead. Typical error 19/255 per channel. |
| Tritanomaly | Brettel 1997 | Approximate — same fit, applied at reduced strength. |
Limits
Do Not Ship the Correction Filter Sitewide
Daltonisation is a diagnostic and an opt-in accommodation. It is not an accessibility fix.
A correction filter helps one viewer by hurting the picture for everyone else. It shifts hues visibly — reds drift, greens flatten, brand colours stop being brand colours. Applied to your whole site by default it degrades the experience for the ~92% of visitors who did not need it, and it does so silently.
It also cannot recover information that was never encoded. If two elements are distinguished only by a red/green difference, daltonisation can pull that difference into a channel the viewer sees — but if two elements share a colour entirely, no filter invents a distinction. The fix there is in the design, not the pipeline.
And it is per-person. The right correction depends on the type and severity of an individual's deficiency, which a website has no way to know and no business asking. Operating-system level colour filters exist precisely because that is where the setting belongs.
Where it genuinely earns its place
As a user-controlled toggle inside a tool whose whole job is colour — a map, a chart builder, a photo editor — where the person can turn it on for themselves. As a review aid during design, in simulate mode, to see what a component looks like before it ships. And as a teaching device, which is most of what this generator gets used for.
FAQ
Daltonize and CSS Filter Questions
What people ask about colour-matrix filters.
What does daltonize actually mean?
It means transforming colours so that distinctions a particular colour vision deficiency cannot perceive get re-encoded into differences it can. The name comes from John Dalton, the chemist who first described his own colour blindness in 1794. It does not restore normal colour vision — it trades accuracy for separability, deliberately.
Can I do this with plain CSS filter functions?
Not correctly. A colour vision transform mixes all three input channels into each output channel, which is a matrix operation. CSS hue-rotate and saturate cannot express that, so recipes built from them are approximations that drift in a hue-dependent way. SVG feColorMatrix is the right primitive, and CSS can reference it directly.
Why does the code include color-interpolation-filters?
Because the matrices are defined on linear light rather than gamma-encoded sRGB. The SVG specification defaults filters to linearRGB, but browsers have not always agreed on inline filter defaults, and getting it wrong produces a result that is subtly and confidently incorrect. Stating it removes the ambiguity.
Is the tritanopia filter as accurate as the others?
No, and the tool says so where you choose it. The accurate tritan model splits colour space with a separation plane and applies different matrices on each side, which no single matrix can reproduce. The filter uses the closest single matrix — constrained so greys stay grey — with a typical error around 19/255 per channel and worse on saturated blues. Protan and deutan have no such caveat.
Should I add the correction filter to my whole website?
No. It visibly shifts colour for everyone, including the majority who did not need it, and the correct strength depends on an individual’s type and severity, which your site cannot know. Offer it as a toggle inside a colour-critical tool, or leave it to the operating system, which is where per-person colour filters belong.
Does the filter apply to images and video too?
Yes. It applies to everything rendered inside the element it is set on, including images, video, canvas and text. That is often what you want for a review pass, and often not what you want in production — another reason to scope it to a container rather than the whole document.
How do I check whether my colours need this at all?
Test the specific colours rather than filtering everything. Our colour pair checker tells you whether two colours stay apart across every vision type, and the website checker previews a whole page. A design that passes those needs no filter.