Hacker News new | ask | show | jobs
by denormalfloat 2375 days ago
There are wrong reasons to sniff the UA string, and less wrong reasons. If a Browser has a bug that gets fixed in later versions, sites have to sniff the UA string to do the right thing. For example, a browser bug may cause people to see an error, and the they are using an old version of the browser. The right thing to do is to upgrade, but how to tell? When you are subject to the bugs of some other code, and which are skewed across different versions of the software, the most reasonable way to work around it is by UA sniffing.
3 comments

I would have bought this argument a decade ago, but at this stage the number of site users not doing some form of automatic updates on their browser should be in the minority. The problems user agents were designed to solve back in the Netscape Navigator days have since been standardized using much better signals, and the odd standards compliance bug here and there isn't really justification for something as weak and unreliable as a user agent string.

I say kill it. Fix it to some static value and require new sites moving forward to do proper feature detection if they really care to work around standards bugs or use experimental new features.

The core web features don't have such bugs anymore for all practical purposes, but newer apis do. Content security policy in particular has a lot of bugs especially around features in v2 and v3 of the spec, when they were first implemented in chrome / Firefox often took a few major versions to get right. I think I've seen similar hacks around use of newer crypto apis. The alternative is to wait 2-3 years between the release of a new api by all major browsers and actually using it.
Sadly, feature detection is still impossible for many features.

For instance, the only way to detect `contentEditable` support is through user-agent sniffing. Many versions of Android Chrome and iOS Safari will happily report that they support `contentEditable` and then refuse to make the content editable.

I'm actually struggling with a similar issue right now: there's no way to detect an on-screen keyboard, so there's no way to focus a textbox only if it wouldn't cover up the screen with an on-screen keyboard (which is pretty important for chat apps). The best you can do involves a lot of hacks, including UA sniffing.

Ouch. Wasn't aware of those. But still not surprised there are edge cases out there.

If I look hard enough, I can always find places where different browser behaviors differ. For instance, I once discovered that the maximum top value I could put a position absolute div within a position relative div was around 20 million px in chrome but only 1.53 million in IE (if my memory serves). This was at least fixable by stacking multiple divs for every 1.5 million pixels I wanted to lay out.

But for every quirk like this that's possible to work around by coding to the lowest common denominator, there's another somewhere that you just can't. I recall doing another project which involved trying to pop open a mobile app to view content; and it was supposed to switch to the store to prompt you to install if you didn't have the app. At the time this involved different hacks for iOS Safari and Android chrome. Behaviors that differed included what happened when you navigate to a scheme with no handler (in chrome, the previous page kept running), and whether the scheme could trigger the app from an iframe (which was blocked in chrome but not Safari iirc). And handing off state to the app during the install flow was simple on Android, but on iOS required another pile of hacks. Whole thing ended up an overcomplicated mess, but we ended up pretty good ux for the intended flows. This was 2014 so the situation is probably better today - I think iOS Safari added some meta tags that are targeted to very similar use cases.

If you don't mind me asking, why are you dealing with million-pixel distances? What problems do they solve?
Probably the most common use case for such things is progressively-rendered/-loaded lists, where you know the number of items and the height of each item in the list, so that you can reserve all the space and provide a meaningful scrollbar, and have a limited number of children absolutely positioned on screen at any given time.

This gives a far better experience than infinite scrolling (which has no meaningful scrollbar, so you can’t jump to the end or an arbitrary point in the middle) or pagination (which is just generally painful once you want something not at the start).

We do this in Fastmail’s webmail, and have put in workarounds for overly-tall elements breaking browsers. https://github.com/fastmail/overture/blob/41cdf36f3e7c8f0dd1... lists them, including some values at which things break. (Actually, IE doesn’t allow containers anywhere near that tall, capping effective values much earlier, with the consequence that you can’t access things near the end of the list. But the problem was that once you get much larger still, it starts ignoring the values you specify altogether, which would break the entire technique.)

For us, the most common height of each email’s entry in the list is 51px; at that, 400,000 emails is enough to get to 20,400,000px high, which is enough to break both IE and Firefox (not sure about Chrome or Safari, I’ve never actually tested it; their failure mode may well just be different, limiting numbers instead of ignoring them).

400,000 emails in a mailbox isn’t all that common, but it does happen.

Oh the other thing was that we were using an https url override on Android and the custom scheme was primary iOS. And the iOS 8 or 9 added the ability for apps to handle https urls, which could be used to simplify our iOS nonsense. But not all of it.
That depends on your user base. For example [1] sees about 10-20% of Chrome and Firefox users on some notably "outdated" version. If your demographic skews towards enterprise users that seems very plausible, large companies regularly hold updates back until they are tested or use extended support releases.

1: https://www.stetic.com/market-share/browser/

For most CSS and JavaScript incompatibility issues, the way to check doesn't require UA sniffing at all. You merely check if the browser supports said feature by looking for whether the supports media query runs or if the new method is available at all.

https://developer.mozilla.org/en-US/docs/Web/CSS/@supports

@supports is often unreliable for CSS features. At least in Blink, it acts more as a "valid syntax" check then a "supported feature" check and for some reason Blink's CSS engine recognizes many new CSS features as valid syntax while not actually supporting them.
I for one would serve adapted css that is matched to the browser. Due to vendor prefixes there is unfortunately some mandatory bloat for a cross-browser stylesheet.

It would also skip polyfills when those aren't needed.