A well-layered solution should ensure continuity of the ease-of-use vs power tradeoff curve and avoid sharp cliffs where a small amount of incremental use case complexity results in a large increase of code complexity.
However I think it’s important enough to promote to a separate principle. It’s not just about making simple things easy and complex things possible, it’s also about everything in between, and I see Web platform APIs (and UIs in general) with sharp cliffs all the time I'd say it's one of the most pervasive UI design problems.
Common counterexamples of this are APIs that make simple things easy by providing a prefacbricated thing that affords no customization and also provide a way to let authors re-implement everything from scratch. This does make simple things easy and complex things possible, but does not provide a smooth ease-of-use to power curve.
Some examples:
The HTMLMediaElement API (HTML <audio> and <video> elements: The controls attribute makes simple things easy (having a predefined controls UI), and the element API makes complex things possible (you can implement your own toolbar from scratch), but there is nothing in between. Even if you want to simply tweak the default controls a bit, add one button, remove a few controls, etc.) the only way is to implement a whole custom toolbar.
The proposed API for custom window frames that required re-implementing all window controls? (TODO: find link)
Many HTML elements afford very little customization, and authors' only recourse is to re-implement them from scratch simply to be able to style them (in the State of HTML, stylability especially around <select> was by far the biggest pain point). Slots are a positive example of this where authors can progressively customize parts of elements by providing custom Shadow DOM content without having to re-implement the element.
Many Houdini APIs had the philosophy of "Oh, you don't like how CSS works? How about you implement a WHOLE PART OF IT FROM SCRATCH then?"
JSON.stringify() is a positive example of that: simple cases are straightforward, gradual customization can be achieved with the callback argument.
This point is alluded to in 2.2. Consider tradeoffs between high level and low level APIs:
However I think it’s important enough to promote to a separate principle. It’s not just about making simple things easy and complex things possible, it’s also about everything in between, and I see Web platform APIs (and UIs in general) with sharp cliffs all the time I'd say it's one of the most pervasive UI design problems.
Common counterexamples of this are APIs that make simple things easy by providing a prefacbricated thing that affords no customization and also provide a way to let authors re-implement everything from scratch. This does make simple things easy and complex things possible, but does not provide a smooth ease-of-use to power curve.
Some examples:
HTMLMediaElement
API (HTML<audio>
and<video>
elements: Thecontrols
attribute makes simple things easy (having a predefined controls UI), and the element API makes complex things possible (you can implement your own toolbar from scratch), but there is nothing in between. Even if you want to simply tweak the default controls a bit, add one button, remove a few controls, etc.) the only way is to implement a whole custom toolbar.<select>
was by far the biggest pain point). Slots are a positive example of this where authors can progressively customize parts of elements by providing custom Shadow DOM content without having to re-implement the element.JSON.stringify()
is a positive example of that: simple cases are straightforward, gradual customization can be achieved with the callback argument.