Specifying Legacy Features
I ran into an old article from Hixie that describes how he worked when specifying the drag and drop part of HTML. As I am working on specifying some legacy css features (like the user-select property or the appearance property), this felt really familiar.
Here’s how Hixie describes his approach:
I put my physicist training to use. As a scientist, you are supposed to approach problems using a simple process:
- Form a hypothesis that matches everything you know so far.
- Make some testable predictions using this hypothesis.
- Test reality to see if your predictions can be disproved.
- Repeat those steps until you can no longer find anything in reality that disagrees with what your hypothesis predicts.
- Publish your findings, along with all the data you collected, and the hypothesis you ended up with.
- Wait for someone to find a prediction that your hypothesis makes and which doesn’t match reality.
- Repeat the entire process.
When reverse-engineering a single implementation, this is a very sound way to proceed, and the number of times you have to run through step 3 is why is love jsbin so much these days.
However, there’s one important complication when what you’re trying to reverse-engineer and specify has not one, but several implementations. As you run steps 1–4, occasionally you find that some implementations match your predictions but that some others do not. Even though it shows that there not yet complete interoperability, the interesting thing is that this can sometimes be a good news.
If something has been in the market for a while with multiple implementations behaving interoperably, there’s a very good chance the web at large now depends on that specific behavior. That does not necessarily means web developers like the way it works. Maybe they do, or maybe the feature is terribly designed and they have to resolve to elaborate workarounds to get it to do what they want. But these workarounds are written, deployed, and depend on the behavior every browser agrees about and would likely break if they were to change.
When browsers do behave differently — assuming the difference is not limited to browsers with negligible market share — authors generally cannot rely on any particular behavior. So they don’t, and hardly any web site depends on browsers staying the same. This means we have an opportunity for making improvements.
If it’s some obscure detail of the feature that doesn’t really matter, it is sometimes just as well to document it as undefined behavior and move on. Getting every vendor to align on something is costly; it’s important to pick the right battles and not waste time on insignificant things. We can alway come back to it later anyway.
If it is some aspect of the feature that does matter, I get to take off my scientist hat and put on a more judgemental one: which the variants I’ve uncovered makes the most sense? Is there one that solves the problem better, or solves more problems, or fits better with how everything else works? Which one do I like best?
Occasionally, none of these disagreeing implementations is particularly good. Browser engineers are generally capable people but sometimes they’re in a hurry. Or maybe they came up with this years before other features which now conflict with their design were added. With the benefit of being able to learn from their mistakes, maybe I’ll be able to come up with something better.
Regardless of whether what I want to go with what one of the browsers did or something I made up, I still have to try to convince all the implementers that will need to change that this is the right thing to do. Although browser vendors can sometimes be uncooperative and just drag feet until others agree to match their implementations, they generally do want the best for the web and will try to accommodate each other.
It is also fairly common that these discussion will uncovered some aspect of the problem I had not yet noticed and throw me back either at the science lab to find out what is really happening or at the drawing board to come up with a better solution.
Having gone through many such cycles,
the user-select property
is now a hybrid that matches different browsers on different aspects.
The lack of inheritance and behavior auto
value
are in line with Microsoft’s implementation.
The none
value on the other hand was superficially the same in all browsers
but where they differed the specification now rules in favor of Firefox’s approach…
And so on for various other parts of the feature.