MSEdgeExplainers icon indicating copy to clipboard operation
MSEdgeExplainers copied to clipboard

[Enabling Custom Control UI] No-JS fallbacks?

Open tigt opened this issue 3 years ago • 1 comments

The backwards-compat story is partially detailed under § Feature Detection, but is there a native no-JS way to have old controls progressively enhance up to the newer ones? Like:

<range name="volume" min="-1" max="20" step="0.1">
  <div slot="thumb" part="thumb"><svg><!-- Use SVG to draw the thumb icon... --></svg></div>

  <input slot="fallback" type="range" name="volume" min="-1" max="20" step="0.1">
</range>

<style>
/* styles for browers that don't see `<range>` as anything special */
range > [part=thumb] {
  display: none
}

/* ::read-write is just a pseudo-class that indicates the browser sees it as a form element,
it could be whatever other pseudo-selector indicates browser support. ::shadow? */
range:read-write > [part=thumb] {
  display: initial
}
</style>

Newer browsers would render the older <input> just fine, but if <range> was supported then it would hopefully upgrade seamlessly. Something like how <datalist> accepts a <select> element inside for fallback rendering if the browser didn’t natively support it?

In the more elaborate case, the datalist element can be given contents that are to be displayed for down-level clients that don't support datalist. In this case, the option elements are provided inside a select element inside the datalist element.

<label>
 Animal:
 <input name=animal list=animals>
</label>
<datalist id=animals>
 <label>
  or select from the list:
  <select name=animal>
   <option value="">
   <option>Cat
   <option>Dog
  </select>
 </label>
</datalist>

The other existing pattern is like <picture>, where the wrapper and its <source> children enhance the existing <img> element, which continues to work like it always has in older browsers. This has the benefit of reducing the duplicate attributes in my earlier example, to become more like:

<range>
  <div slot="thumb" part="thumb"><svg><!-- Use SVG to draw the thumb icon... --></svg></div>

  <input slot="fallback" type="range" name="volume" min="-1" max="20" step="0.1">
</range>

tigt avatar Dec 23 '21 18:12 tigt

The second <picture>-style upgrade method also seems like it could solve the other problem of opting-in as mentioned in the explainer? Figured I’d mention it since the explainer asks for alternate solutions as an open question.

tigt avatar Dec 23 '21 18:12 tigt