Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental rollout plan for form controls #10804

Open
mfreed7 opened this issue Aug 29, 2024 · 3 comments
Open

Incremental rollout plan for form controls #10804

mfreed7 opened this issue Aug 29, 2024 · 3 comments

Comments

@mfreed7
Copy link
Contributor

mfreed7 commented Aug 29, 2024

{This posting is the result of a request made at this meeting for some clarity on Google's view about how to roll out form control stylability.}

TL;DR

We want to tackle not only stylability of form controls, but interoperability and composability. We believe this is a rather large engineering task, and we therefore want the ability to ship these improvements incrementally rather than all at once. We propose continuing to use appearance:base-controlname as a mechanism to allow that incremental shipment, until we get to the point where "the rest" of the controls can all be shipped with appearance:base.

Overview

Form (UI) controls have been a part of the web since the early days. While the form-associated controls provide a good basic set of UI controls for page design, many “table stakes” UI controls still require significant effort to build, often from scratch, such as select menus, tab controls, carousels, etc. In addition to those “large” components, just basic controls such as checkboxes, radio buttons, and range sliders still require outsized time investments from developers in order to make them work in production.

In terms of the existing set of HTML form control elements, there are two related but separate sets of problems:

  • Lack of stylability/interoperability. It should be easy to restyle form control elements without requiring herculean effort. For example, just to change the width or height of an <input type=checkbox>, interoperably, developers have to delete all of the native styles via appearance:none, and then recreate the control from “scratch”, including recreating things like the checkmark glyph. As another more extreme example, see this 7000+ word blog post on how to interoperably style a range slider. Note that often (e.g. for range sliders), enabling stylability requires more than just a standardized UA stylesheet: it also requires standardization of the layout box structure of the control.
  • Lack of composability. Controls should, where applicable, support custom content. For example, the most impactful part of the customizable-<select> work has been the ability for <option> elements to contain arbitrary content, rather than just plain text. This same missing capability applies to a number of other form controls, such as the in-page portion of an <input type=date>, or <textarea>.

What do “stylability", "interoperability”, and "composability" mean?

We believe “stylability” means that the UI element should respond to all relevant CSS properties, such as width/height, borders, colors, animations, directionality, fonts, grid/flex properties, etc. Basically anything that can be styled on a <div> should also be stylable on UI controls. Also potentially included in “stylability” is the ability to style related bits of UI that come with controls, such as form validation error messages and autofill preview/filled content.

“Interoperability” means that the UA stylesheet and the content model for the control should both be provided as part of the html spec. This ensures that developer CSS will be applied to the control in the same way across browsers, leading to identical rendering. This also provides a mechanism to test the appearance of controls via WPT reference tests.

“Composability” is the ability to insert other HTML elements into UI controls. For example, it should be possible for a developer to use their own <my-button> custom element as the spin-buttons of an <input type=number>.

The Ideal Approach

We’ve reached a consensus that to achieve the goals of stylability, composability, and interoperability, we will add a CSS-based “opt-in” mechanism: appearance:base. Once the entire effort is complete, the desired end-state is that a single line of CSS can be used to opt all form controls (not including pickers) into the new customizable/interoperable mode:

* {appearance: base;}

This must be the end-state only, and not the starting state, because once a single control has been shipped that supports appearance:base, there’s a high risk that developers will simply add *{appearance:base} to their stylesheets, and will subsequently be surprised (in a bad way) when additional controls begin to support this mode. For this reason, we can only support appearance:base when the work is “done” for all controls. If there are incremental shipments prior to that point, they will need to use a named appearance value, such as appearance: base-select.

Note that since we’re close to agreement on #10440, the “pickers” for form controls will have their own opt-in mechanism, via ::picker(control) {appearance: base-control}. So it will be possible to ship the universal appearance:base value when the in-page parts of all controls are done, but potentially before all pickers are done. This is good because pickers are complicated.

Engineering Time

Adding stylability, composability, and interoperability to all form controls is a very large task. We’ve found that even controls that seem like they’ll be easy to improve turn out to take a very long time, particularly for things that require spec changes in multiple standards bodies. For example, we’ve spent >5 years working on the <select>, and >1 year working on <details>/<summary>. Of course, we are quite hopeful that the establishment of the WHATWG/CSSWG/OpenUI task force will speed up these timelines. It already has! But we want to make sure we’re not underestimating the size of the job ahead.

For that reason, we are therefore afraid of committing to wait for all controls to be included in this effort before we’re able to ship any of them. We’d much prefer to have the flexibility to ship improvements to the web platform incrementally, rather than having to wait years (or more) for the entire package to be completed.

Detailed list of UI Controls

One point of contention about the overall plan is likely to be the “years” estimate. Since it’s very hard to generalize a strategy that uses terms like “all of the form controls” without actually looking a bit in detail at the list, I’ve compiled a list. This should contain all form-associated controls, plus others (e.g. meter and progress) that are just UI controls. I’ve included some notes about what might be missing for each, and tried to categorize the work required. Note that this is purely to get the conversation started; many of my comments are just quick thoughts. So please don’t take the specifics for each control as part of the explicit plan, but more of a helpful sketch of why their UI aspects are likely not simple to standardize. I also included links to pre-existing conversations in WHATWG, OpenUI, or elsewhere, as available.

Pickers

  • <select>
    • Users require arbitrary content within options, at a minimum, plus full stylability of the picker.
  • <input type="date|time|etc">
    • Typical requests include the ability to put arbitrary content in each date cell (e.g. flight prices per date), support for date ranges, control over the display of all calendar “options” such as week start date, widgets for selecting today’s date, going back and forth by months or years, etc. Customizability needs to take datalist into account.
  • <input type="color">
    • Alpha channel support, color space support, “2d” selectors for hue/saturation, “1d” sliders for three/four components, current color display, recently used colors area, etc. Customizability needs to take datalist into account.
  • <input type="file">
    • Likely this will not be allowed to be customizable, due to security/spoofing issues.
  • <input type=”text” list=datalist> (see OpenUI)
    • This line item is about the text content suggestion picker for text-based inputs. The date and color pickers can also make use of the list attribute, but those are separate concerns. This item is about allowing custom/arbitrary <options> content within the <datalist> which gets displayed in the text suggestion picker, plus the ability to provide replacement/decoration of the picker itself (similar to the <select> picker).

Need stylability/interoperability, plus potentially composability

  • <select> (in-page component, see above. spec PR. Will eventually also include an in-page picker for <select size=2>)
  • <input type="date|time|etc"> (in-page component)
    • Custom included buttons for “show picker”, “clear”, “today”, perhaps “custom”. Custom slotted content for date/time parts.
    • Needs to work together with the picker, eg. to show custom slotted content such as flight prices.
  • <input type="file"> (in-page component)
    • Provide your own button, provide your own element to receive the filename, perhaps akin to <selectedoption>?
  • <input type="checkbox"> (OpenUI)
    • Custom content for checked, unchecked, indeterminate state glyph. Possibly custom content on the background.
  • <input type="radio"> (OpenUI)
    • Custom content for checked, unchecked, indeterminate state display.
  • <input type="range"> (OpenUI)
    • Custom content along the track or on the thumb (e.g. current value display), including possibly custom content for datalist-provided tickmarks.
  • <meter>
    • Custom content along the track
  • <progress>
    • Custom content along the track
  • <input type="checkbox" switch> (see WHATWG and OpenUI)
    • Custom content on the “on” and “off” sides of the switch.
  • <input type="number">
    • Ability to replace up/down arrow buttons with custom buttons.
  • <textarea>
    • Arbitrary content within the textarea, rather than text-only.

Likely “just” stylability/interoperability (no custom content) needed

  • <input type="text">
  • <input type="email">
  • <input type="tel">
  • <input type="url">
  • <input type="image">
  • <input type="button|reset|submit">
  • <input type="color"> (in-page component, might need to work with picker)
  • <input type="search"> (there is a “clear” button - how to style it?)
  • <input type="password"> (a “reveal” button is common, see Chromium bug)

Likely mostly good as-is?

  • <button>
  • <output>
  • <object>
  • <fieldset> **and** <legend>
  • <img>

Proposed Approach For In-Page Controls

We’d prefer a phased approach:

  1. Agree on the list of form controls, and the categorizations of those controls. Which require composability in addition to stylability?
  2. Agree on an ordering that the controls should be tackled. We feel it makes the most sense to start with the controls that will take the longest, because those are the riskiest.
  3. Ship*, incrementally, the larger/slower controls as they become available. To do this, enable them via appearance: base-controlname so that they can be incrementally shipped to the platform before appearance:base is available for all controls.
  4. Once the remaining list of controls is “small enough” to tackle together as a set, ship all of them together as a group, enabled via appearance:base. At the same time, connect appearance:base to appearance:base-control so that the already-shipped controls can be enabled more easily. Deprecate the base-control values for appearance.

* Everywhere I use the term “ship”, I mean “to the web platform”. That includes landing the changes in standards, and beginning to enable the behavior in browsers.

Future New Controls

One important question is how to handle “new” controls that don’t already exist on the platform. Such a new control doesn’t immediately have the backwards-compatibility problem that requires appearance: base-newcontrol, but it does still risk the general forward-compat problem of developers using *{appearance:base}. For that reason, it seems necessary to also require such a new control to get opted in to “base” mode via appearance:base-newcontrol.

@tabatkins
Copy link
Member

One important question is how to handle “new” controls that don’t already exist on the platform. [...] For that reason, it seems necessary to also require such a new control to get opted in to “base” mode via appearance:base-newcontrol.

This is just while we're in the intermediate phase, right? Once we've finished all the existing controls and can make plain base work, then new controls added after that point would similarly only get base and not get a control-specific value, right?

@mfreed7
Copy link
Contributor Author

mfreed7 commented Aug 30, 2024

This is just while we're in the intermediate phase, right? Once we've finished all the existing controls and can make plain base work, then new controls added after that point would similarly only get base and not get a control-specific value, right?

Great point - yes. After appearance:base is a thing, everything can and should just use that. Assuming, of course, that all new controls that come after that point get appearance:base behavior/styling defined from the start.

@MrHBS
Copy link
Contributor

MrHBS commented Sep 27, 2024

I am proposing to add the <legend> element to the list.

See this section from MDN Styling web forms:

The <legend> element is okay to style, but it can be a bit tricky to control placement of it. By default it is always positioned over the top border of its <fieldset> parent, near the top left corner. To position it somewhere else, for example inside the fieldset somewhere, or near the bottom left corner, you need to rely on positioning. The <fieldset> needs to be positioned too, so that the <legend> is positioned relative to it (otherwise the <legend> would be positioned relative to the <body>).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants