-
Notifications
You must be signed in to change notification settings - Fork 53
Description
Heuristics are great because they save time and ease migration costs, but when they fail they can degrade the user experience far more than if there was no heuristic at all, especially if they are used in parts of the platform that cannot be avoided. As a general UI/UX principle when introducing heuristics, one should also include ways to override the heuristic.
Overriding should be possible in both directions, if it makes sense in both directions:
- Opt-in and opt-out for binary heuristics (is X an A?)
- Increase/decrease for numerical heuristics (what is the score of X?)
- For numerical heuristics, overrides should be relative, rather than absolute
No override is necessary if the heuristic is 100% accurate in one direction.
The need for overrides is affected by two factors:
- How good is the heuristic? I.e. what is the rate of false positives/false negatives (for binary heuristics) or distance from the ideal value (for numerical heuristics). This is often very hard to determine before shipping! Overrides are still needed even when the heuristic is excellent (since it's not 100% or it wouldn't be a heuristic), but in that case they can be less prominent.
- How does it affect the user experience when the heuristic is wrong? Are there alternatives? Overrides may not be needed if the heuristic produces no user observable effect (e.g. is only used for analytics) or the feature is one of many that solve the same problem.
Examples from the web platform:
- 🚫 CSS specificity is a heuristic that attempts to infer importance from querying logic. It did not work great, and did not provide ways to override in both directions (you could increase specificity, but not decrease it — before
:where()
). It worked so poorly that developers ended up avoiding querying with selectors altogether, and managing querying with JS or manually (see BEM) - 🚫 CSS stacking order is largely inferred from document source order + positioning properties. There is a
z-index
property to override it, but it only works some of the time and is absolute, rather than relative, resulting in "z-index war" where authors setz-index
to huge values to "win" over other elements. - ✅ In JS,
array.concat()
heuristically determines whether to append the value itself to the array, or the values it contains (the heuristic is very simple: is the value an array or not?). This means it's not possible to use it to add an array as an element of another array (e.g.[1, 2].concat([3, 4])
will produce[1, 2, 3, 4]
, not[1, 2, [3, 4]]
). That's ok since a) the heuristic predicts intent correctly >95% of the time and b) users can simply use other functions to deal with the remaining use cases. - ✅ Soft navigations is a proposal that uses heuristics to detect soft navigations for analytics purposes. There are no overrides, but this is ok because the feature does not produce any observable effects to the user experience. However, if the concept were to be used for other web platform features, then overrides would need to be added.
Example that came up later: The web’s same origin policy is a heuristic that is attempting to infer the end-user’s desired privacy boundary from the URL structure. In many cases that matches user intent, but in some cases it does not:
- False positive: Multiple domains for essentially the same entity, e.g. amazon.com and amazon.co.uk or x.com and twitter.com
- False negative: Websites that allow users to host their own website across the same origin: e.g. when GitHub Pages originally launched, pages by users lived in the same origin as GitHub itself (github.com).
There are no mechanisms to override false negatives that I’m aware of. Mechanisms to override false positives include CORS, First Party Sets, Cross-window Messaging etc, but each imposes different restrictions. However, this is likely acceptable, since making it possible to override heuristics that exist to protect end-users’ privacy and security should be approached with a lot of care.