Description
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 supportdatalist
. In this case, theoption
elements are provided inside aselect
element inside thedatalist
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>