Skip to content

[Enabling Custom Control UI] No-JS fallbacks? #546

Open
@tigt

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 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>

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions