Are form controls replaced elements?
From https://github.com/web-platform-tests/interop/issues/1124 (cc @Loirooriol)
See previously: https://github.com/w3c/csswg-drafts/issues/1024.
CSS 2 says:
CSS 2 does not define which properties apply to form controls and frames, or how CSS can be used to style them. User agents may apply CSS properties to these elements. Authors are recommended to treat such support as experimental. A future level of CSS may specify this further.
CSS 2, defining "replaced element", says:
An element whose content is outside the scope of the CSS formatting model, such as an image, embedded document, or applet.
CSS Display says:
An element whose content is outside the scope of the CSS formatting model, such as an image or embedded document.
CSS Display, defining display: contents, says:
This value computes to display: none on replaced elements and other elements whose rendering is not entirely controlled by CSS; see Appendix B: Effects of display: contents on Unusual Elements for details.
CSS Sizing says:
In addition to the replaced elements listed in HTML§14.4 [HTML], the following HTML elements are also considered to be replaced elements for the purpose of the percentage-sized replaced element rule above, and can have their min-content contribution compressed when their width/height or max-width/max-height is expressed with a cyclic percentage size: [
<input>,<select>,<textarea>,<progress>,<meter>,<marquee>]
CSS UI says:
The term widget in this specification denotes replaced elements that can have native appearance, meaning that they are rendered like analogous native widgets or controls of the host operating system or platform, or with a look and feel not otherwise expressible in CSS.
HTML says:
The following elements can have a native appearance for the purpose of the CSS 'appearance' property.
So:
- CSS 2 explicitly leaves form controls undefined, and "replaced element" definition would presumably include them (because they're not defined by the CSS model),
- CSS Display has a similar definition of "replaced element", but also talks about form controls distinct to replaced elements,
- CSS Sizing implies that a number of HTML elements are to be considered replaced elements (implying they're not in general),
- CSS UI makes it clear that widgets are replaced elements,
- HTML defines them as widgets (per the CSS UI definition).
So on the whole to me it seems like the intention is that they are replaced elements, but we don't make this super obvious?
If they are replaced elements, why does object-position: 100px have no effect on them? object-position applies to replaced elements.
If they are replaced elements (presumably with no natural sizes), then why do they not stretch when assigned a preferred aspect ratio with aspect-ratio?
If they are replaced elements, why do they stretch by default when they are grid items?
On the flip side, if they're not replaced elements, why do their children not render? :)
They aren't replaced elements from the perspective of layout engines anymore. Form controls once behaved more similar to replaced elements, however (at the request of FF I believe) engines moved the rules for form-controls closer to non-replaced (which IMO was a good thing).
Likely we need a definite term for these things, we've previously used "semi-replaced" which IMO is too confusing, likely just "form control" or "widget" is fine.
if they're not replaced elements, why do their children not render?
Having a closed UA shadow DOM explains this.
Something like a checkbox doesn't have quite a well defined place to put its children in, fwiw... But ok, I guess.
To be clear I'm not against saying that widgets shouldn't have a ::before or ::after. It's just that I don't think that the restriction on replaced elements is also covering widgets.
So what's the state of this right now? On a test page like this:
<!DOCTYPE html>
<style>
input, meter, select, button, progress, textarea, video, canvas, img, marquee, svg, br {
width: 50px;
height: 50px;
margin: 5px;
display: inline-block;
position: relative;
.none > & {
background-color: lime;
border: 1px solid;
appearance: none;
}
&::before {
content: "before";
position: absolute;
top: 0;
left: 0;
}
&::after {
content: "after";
position: absolute;
bottom: 0;
right: 0;
}
}
</style>
<div class="auto">
<input type=checkbox>
<input type=radio>
<input placeholder=text type=text>
<input placeholder=number type=number>
<input placeholder=search type=search>
<input type=date>
<input type=month>
<input type=datetime-local>
<input type=color>
<input type=submit>
<input type=image>
<input type=file>
<select><option>select</option></select>
<textarea>textarea</textarea>
<marquee>marquee</marquee>
<progress></progress>
<button>button</button>
<canvas></canvas>
<svg></svg>
<img>
<br>
</div>
<div class="none">
<input type=checkbox>
<input type=radio>
<input placeholder=text type=text>
<input placeholder=number type=number>
<input placeholder=search type=search>
<input type=date>
<input type=month>
<input type=datetime-local>
<input type=color>
<input type=submit>
<input type=image>
<input type=file>
<select><option>select</option></select>
<textarea>textarea</textarea>
<marquee>marquee</marquee>
<progress></progress>
<button>button</button>
<canvas></canvas>
<svg></svg>
<img>
<br>
</div>
It seems:
- Firefox only creates
::before/::afterfor<button>/<input type=submit>and<input type=checkbox/radio>whenappearance: none(when they just followdisplay). - Chrome and WebKit creates
::before/::afterfor everything above plus:- checkbox / radio even when appearance: auto.
-
date/month/datetime-local/color/file/marquee/<progress>
The choices above don't make a lot of sense to me:
- Why
textinputs don't allow generated content but date inputs do? - Why submit inputs don't allow generated contents but color inputs (which are basically a button) do?
I think I'd be ok with saying that we allow generated content on:
- radio / checkbox regardless of appearance (and define them as a plain inline block).
- All button-like things that don't have extra magic like
<select>(so<input type=color/button/submit>). - Marquee, probably, since the author can already put arbitrary content there, and I think engines agree on the internal shadow tree model.
But not on:
- Image / canvas / video /
<input type=image>/<svg>/<iframe>: those are "real replaced" things. -
<br>: very special / not well defined layout model. - Text inputs / textarea / datetime inputs / select /
<progress>/<meter>/ range inputs / (at least when not inappearance: base/base-selectmode): the internal layout details of those are not spec'd / can't be relied on.
Would people agree with such proposal?
To be clear I'm not against saying that widgets shouldn't have a ::before or ::after. It's just that I don't think that the restriction on replaced elements is also covering widgets.
Ah, thanks. Sorry, just read this after posting the wall of text above.
Ok, so can we agree on:
- Defining this new "widget" concept which isn't quite using the same replaced sizing concept as images.
- Define that generated content pseudo-elements work only on some widgets (following the rationale defined above)?
I believe that makes all engines converge (Firefox needs to implement the generated content in a few places, and WebKit / Blink removing it from others), but I think the result is probably more sensible than the current state of things, which feels mostly random.
Certainly not all widgets are fully replaced elements. e.g. for vertical-align: baseline, <input type=text>, <input type=button> and button have baseline alignment like inline-blocks (with text), whereas replaced elements sit on top of the baseline.
Demo: https://software.hixie.ch/utilities/js/live-dom-viewer/saved/14404