
Setting CSS Blur Filter to Zero on a Retina Screen
This Article is Over Eleven Years Old...
Things can and do move very quickly in tech, which means that tech-related articles go out of date almost as soon as they have been written and published. If you are looking for up-to-date technical advice or opinion, it is unlikely that you will find it on this page.
You may find that my recent articles are more relevant, and you are always welcome to drop me a line if you have a specific technical problem you are trying to solve.
Despite fairly widespread uptake in the development and browser community, the filter property is still a relatively immature part of CSS (the module specification is still currently only a working draft). In the case of using the blur() filter, the draft specification notes that a CSS length parameter is used to define the radius of the Gaussian function applied:
“The passed parameter (the radius) defines the value of the standard deviation to the Gaussian function. The parameter is specified a CSS length, but does not accept percentage or negative values.
In layman's terms: blur() needs a numerical value, with or without a unit value (px, em, etc); the bigger the value, the more blurry the element you apply it to will render (assuming the correct use of vendor prefixes and browser support).
At present, prevailing wisdom suggests the pre‑emptive use of each of the major vendor prefixes. whether those vendors currently support the property or not. As an example, if you wanted to add a 10px blur to an element using CSS, you would end up with a piece of CSS that looks something like this:
.blur-me { filter: blur(10px); -webkit-filter: blur(10px); -moz-filter: blur(10px); -o-filter: blur(10px); -ms-filter: blur(10px);}Of course, you could also include an SVG filter in there as a final fallback, but given how minimal browser support currently is for all filter effects if it simply wouldn't be acceptable for your development to degrade back to non‑blurred for the 56.59% of browsers that don't currently support it, then you might need to consider another route that doesn't use the effect at all.
One of the nice things about filters is that they can be animated and used in conjunction with CSS transitions. I use it myself on the previous version of this website to blur the main website content when the mobile fly‑in navigation is opened, which is where I came across a stumbling block. My CSS looked something like this:
.page { filter: blur(0); -webkit-filter: blur(0); -moz-filter: blur(0); -o-filter: blur(0); -ms-filter: blur(0);}.nav-open .page { filter: blur(3px); -webkit-filter: blur(3px); -moz-filter: blur(3px); -o-filter: blur(3px); -ms-filter: blur(3px);}All fairly straightforward: .page would have no blur (blur(0)) by default, and a 3px blur when switched via the parent class (.nav‑open).
Although this method worked just as expected, it also revealed an interesting bug in the way that WebKit handles display on Apple's retina screens: when viewed on my MacBook Pro the blur never quite fully extinguished itself, retaining a very subtle blur:

However, using filter: none still reverted (correctly) back to no blur at all, although that's not an ideal solution if you're using other filters on that same element!
Reverting to the incessant knowledge of Stack Overflow, the answer seems to be that this is a known bug in WebKit (although from all my searching, I couldn't find any mention of it online), and the only answer aside from using none is a combination of using either ‑webkit‑transform: translateZ(0) or ‑webkit‑backface‑visibility: hidden. Both will work, although either may have other unintended effects depending on your situation. Tread lightly.
The nice thing is that since this appears to be solely a WebKit issue, there isn't any need for any other vendor prefixes, although I do opt to include the non‑prefixed version of the fix, too for forward compatibility:
.page { -webkit-transform: translateZ(0) transform: translateZ(0) filter: blur(0); -webkit-filter: blur(0); -moz-filter: blur(0); -o-filter: blur(0); -ms-filter: blur(0);}.nav-open .page { filter: blur(3px); -webkit-filter: blur(3px); -moz-filter: blur(3px); -o-filter: blur(3px); -ms-filter: blur(3px);}What I find most interesting about this is that both the workarounds above share one thing in common: both are used as sort‑of hacky ways of boosting transition and filter performance by allowing hardware acceleration in WebKit browsers. Perhaps it is nothing more than a coincidence, but I do wonder whether the reason the zero‑setting works when using hardware acceleration on these high‑density screens relates to the GPU being designed specifically to process at these sub‑pixel/zero levels, whereas the software acceleration appears to round the blur effect to somewhere in‑between 0px and 1px.
Related Articles

Backtracking Decision Trees: Solving 'Combination Sum'. 
Optimising HTML Markup for SEO. Optimising HTML Markup for SEO

Finding the Difference Between Two Strings in JavaScript. Finding the Difference Between Two Strings in JavaScript

Dynamically Create a Script Element with JavaScript. Dynamically Create a Script Element with JavaScript

Optimising Vue.js Performance with Lazy Loading and Code Splitting. Optimising Vue.js Performance with Lazy Loading and Code Splitting

Next.js vs. Remix: Understanding the Key Differences. Next.js vs. Remix: Understanding the Key Differences

Best Practices for Angular Routing and Lazy Loading. Best Practices for Angular Routing and Lazy Loading

The Differences Between Lead and Senior Roles in Front‑End Development. The Differences Between Lead and Senior Roles in Front‑End Development

Creating Custom Vue Directives for Enhanced Functionality. Creating Custom Vue Directives for Enhanced Functionality

Creating Custom Viewport Units Instead of Using vh and vw. Creating Custom Viewport Units Instead of Using
vhandvw
How Much Does a Front‑End Developer Make? How Much Does a Front‑End Developer Make?

Break Out of CSS Nesting with Sass. Break Out of CSS Nesting with Sass