Open bfgeek opened 2 years ago
Why not field-size: fit-content
?
/* expand vertically */
textarea {field-size: fit-content}
/* expand horizontally */
input[type=text] {field-size: fit-content}
This property:value combo has a few benefits:
fit-content
also appears in other sizing properties like width
)Then, if a wrapping input
field were to be specced by CSS, it could automatically start expanding it vertically instead.
/* expand vertically */
input {
wrap-property-tbd: wrap;
field-size: fit-content;
}
They would need to be specified together just like overflow:hidden; white-space:nowrap; text-overflow:ellipsis
@LeaVerou
What are we bikeshedding? Is it the naming of the form-sizing property? A max-content value on another property? If so, which one?
We are bikeshedding the (current) form-sizing
property, and the two values auto
and normal
.
Is this intended to eventually also control width autosizing, which is also a common request (though not equally common)? I really hope we don't introduce two entirely separate bits of syntax for these very similar things.
This is in the above resolution, and you can test the behaviour in Chrome Canary with experimental web platform features enabled.
Various bikeshedding suggestions:
@tabatkins suggests legacy | auto
for the values in https://github.com/w3c/csswg-drafts/pull/9251#issuecomment-1696234210
I've also seen people suggest form-sizing: content
.
(personally I also don't mind field-size
or field-sizing
for the property name).
I prefer field
over form
, because I can already see people thinking it's related to <form>
. I don't like terms like legacy
only because it doesn't actually describe what's going on. Basically, people would have to research externally what it used to do to then decide not to use it. But if there's no way to sum up the legacy behavior in one or two words, I can understand.
Thanks both @bfgeek and @clshortfuse!
Then discussion come about the complexities of making
<input>
multiline.
Yeah, that's not going to happen, but autosizing width is still very useful! I've written a lot of fragile custom code to facilitate this.
We are bikeshedding the (current)
form-sizing
property, and the two valuesauto
andnormal
.
Not sure if this is still on the table, but I would really, really prefer a value on width
and height
for this instead of a new property. Reasons:
width
and height
. How isform-sizing: normal; height: 2lh;
supposed to behave? Does the height override the size-by-contents height? Does it function as a fallback for browsers that don't support form-sizing
and do nothing in browsers that do? In general, we've seen time and time again that having features that disable other features is the root cause of a lot of author pain.height: from-input
makes it clear that this is some kind of height sizing. Whereas form-sizing
could be about anything that affects the control's box model (e.g. think of box-sizing
which by naming sounds related). Even if it's clear that it's about adapting the control's dimensions to its content, is it adapting the width or the height? Not to mention it's conceivable to eventually want to allow both on the same control.<input>
width autosizing is unclear. If this feature launches working only for <textarea>
then it may not be web compatible to also allow it to work for <input>
. So then what do we do? Introduce a separate property for input? And what about <select>
even later? Another one? Yikes!width
or height
allows future granularity, rather than generic terms like normal
. E.g. if we wanted to expand this to <select>
, does normal
size by currently selected option or the option with the maximum size? These could be different keywords.If this is entirely a non-starter for <reasons>, the new property should at least make it clear what dimension is being altered (width/height/block/inline).
I also agree about the arguments against legacy
as a value. Also, legacy
implies this is not useful and only exists for legacy reasons, but there are plenty of use cases where you don't want to size form fields by their contents.
If this is entirely a non-starter for reasons, the new property should at least make it clear what dimension is being altered (width/height/block/inline).
We discussed this at length previously (see previous discussion), the concerns you've described above were considered, in particular see the discussion about compressibility, and interactions with percentages. This is agenda+ for a bikeshedding discussion.
Compat: The upgrade path to supporting width autosizing is unclear. If this feature launches working only for
<textarea>
then it may not be web compatible to also allow it to work for<input>
. So then what do we do? Introduce a separate property for input? And what about<select>
even later? Another one? Yikes!
I'm unclear what you are describing here - but the implementation in Chrome Canary (with the experimental web platform features enabled) sizes both <input>
and <select>
based on their contents. Please file implementation bugs if this doesn't work as you expect.
If this is entirely a non-starter for
, the new property should at least make it clear what dimension is being altered (width/height/block/inline).
I believe we discussed this previously, and people thought that it was better just to control both axes simultaneously.
The CSS Working Group just discussed [css-ui] ? Allow <textarea> to be sized by contents.
, and agreed to the following:
RESOLVED: Values will be fixed | content
Please edit this comment, add your at-username next to the option you support and update the count next to it. Votes have been pre-added for people that have expressed a clear preference already here or in the telcon. If you don't have permissions to edit this comment, please add your vote using reactions (emoji indicated in the beginning of each option)
field-sizing: content | fixed
(8): @leaverou @mirisuzanne @astearns @bfgeek @chrishtr @SebastianZ @jfkthame @bramusform-sizing: content | fixed
(2): @frivoal @tabatkins I lean towards contents
instead of content
.
Content is an uncountable noun. We use it when referring to the ideas or subject matter of something (e.g., the “content of a speech”). Contents is a plural countable noun. We use it for things in a container or for sections of a publication (e.g., book chapters in a “table of contents”).
Also I wonder if the property name should have intrinsic-size
in it, since it only affects intrinsic-sizing. The concept is already exposed to web devs with contain-intrinsic-size
, so it should be OK.
I think either content
or contents
could work here, both functionally and grammatically, but between the two, I think content
is more familiar to other property/value names (e.g. align-content
, justify-content
, fit-content
).
Those three cases, and this one, could arguably be considered uncountable and will fit their contained content(s) regardless of the count of "how many contents" there are.
Again, just my 2 cents. Either is fine.
contents
is good in natural language, "sized by its contents" but it would be the only use case I know of where plural is used and I'd lean on content
for uniformity.
The group discussed control
in relation to property names. I'm old and remember when we called them controls decades ago probably from "knobs and controls" like mechanical items. Then came widgets. But while I think of them as Form Controls, so are checkboxes, radio buttons, and buttons. Even labels and legend. field
is more specific to what we're doing here since you're unlikely to think this relates to checkboxes or labels, or even consider it would affect those. You don't have to explain that "this is for controls, but only the controls that are text fields".
I'll state my biases. I've worked on Material Design elements for about a decade now and they're called "Text Fields" there. Before, in Android it was "widgets". And before that, in WinForms, it was "controls".
contents
is already used in CSS with display: contents
fwiw.
However, in the context of sizing, content
is more common than contents
, see content
, especially with similar min-content
, max-content
, and fit-content
.
Yeah. contents
in display refer to the element tree. content
in flex and sizing refers to the same as the objective here. It would be consistent with the singular.
The DOM is inconsistent here too: node.textContent
, but range.selectNodeContents()
. Good times.
Don't complicate it for people not native in English. Content or contents, sign up or sign in… It is true, it's not consistent already, but why adding more cognitive load.
So content
for me everywhere.
I don't see anyone talking about the fact that we already have minmax()
.
Can't we find a way to make use of it, when the first value of minmax is a the unitless number of row//columns depending on the axis ? (vertical for textarea, horizontal for input)
Exemple:
minmax(4, 8)
would give a <textarea>
with 4 rows when there is no content, grow up to 8 rows when there is more than 8 rows of content.
minmax(4, auto)
would be the same but always expand with no upper limit.
@mrleblanc101 The current solution is better: which does not limit the authors to just a grid layout; does not tie a change of size mode to something that should not essentially differ from a simple synonym for length with lh
unit; and does not introduce a potential compatibility issue with the existing web in the case of both auto
, of course only if we want to cover all use cases with it.
I posted a poll on Mastodon to bikeshed the name: https://front-end.social/@jensimmons/111212178918345738
Someone replied with the suggestion of input-sizing
, which is a good idea.
I posted a poll on Mastodon to bikeshed the name: https://front-end.social/@jensimmons/111212178918345738
Someone replied with the suggestion of
input-sizing
, which is a good idea.
form-sizing, input-sizing
, kinda similar.
I like resizing-behavior: content | fixed
I posted a poll on Mastodon to bikeshed the name: front-end.social/@jensimmons/111212178918345738
Is this the correct link? I get a 404.
Someone replied with the suggestion of
input-sizing
, which is a good idea.
This was discussed in the call (proposed independently by both me and @fantasai ), people thought it sounds like it refers to <input>
only which is a fair argument.
That is the correct link.
Here's the current screenshot, but also be sure to read the replies. There's a lot of conversation happening.
Against input-sizing
, which makes it look like it only works on <input>
elements.
form-control-sizing
? (After HTMLFormControlsCollection
.)
There was a nice suggestion in the Twitter discussion:
How about "dynamic-sizing" to represent what it does instead of what element it applies to?
Another option, assuming it can apply to inline size of inputs and, potentially, to both dimensions of textareas: what about auto-size: none (default) | inline | block | both
?
Another poll on twitter, including all three options of form-sizing
, field-sizing
, and input-sizing
; the comments are interesting also: https://twitter.com/csswg/status/1711816620534886464
Open UI list of how different libraries call input text: https://open-ui.org/components/inputtext.research/
Doesn't exactly differentiate <input>
form <textarea>
though
The CSS Working Group just discussed [css-ui] ? Allow <textarea> to be sized by contents.
, and agreed to the following:
RESOLVED: field-sizing: content | fixed
On the call, @fantasai said people preferred field-sizing
over input-sizing
in her poll... so the working group moved quickly past input-sizing
and resolved to choose field-sizing
. But then I looked at Elika's poll, screenshotted above ^. Actually people really preferred input-sizing
.
So I created a new poll on Mastodon just to see what happens: https://front-end.social/@jensimmons/111217420404388282
We are still resolved on field-sizing
, but maybe we should reconsider. Or at least confirm our resolution knowing what developers actually prefer (in these very unscientific quick polls).
@jensimmons My recollection is that @fantasai did say that input-sizing
was winning, but that field-sizing
still had a sizeable percentage, and those opposed to input-sizing
feel much stronger than those opposed to field-sizing
.
No, Jen's right, I got it backwards on the call... they are pretty close though, and we did have comments about how input-sizing
would be confusing for something that applies to textarea
.
Since this actually affects how the intrinsic size is used, why isn't the property named intrinsic-size?
In other parts of CSS, resizing according to content in one or more axes is the default mode. Having a new property called field-sizing
which only applies to form controls and has different behaviour to input / select (auto-resize in inline direction) vs textarea (auto-resize in block direction) also feels too magical and is introducing even more specific sizing behaviour.
It also doesn't address the pain points around special sizing behaviour for other replaced elements like img and video which have their own width and height even when you set display: block
, nor for iframes which have this weird 300px x 150px size even if you set it to display: block
.
I suggest this property be called intrinsic-size
, and instead of content
and fixed
, it should be none
and auto
.
When none
is coupled with display: block
, it causes all replaced elements and form controls to assume the width of the container and resize its height to fit the content (if height
is auto
). This would disable the default width of iframe of 300px, ignore the platform defined width for select, input and textarea, and cause video, img, select, input, iframe etc to actually behave like block elements everywhere else in CSS.
(For iframe maybe dynamically resizing its height according to content is too difficult to implement and/or introduces security risks. But at least the width should behave like all other display: block elements. Potentially the height should just resolve to 0px as if there were no contents?)
When coupled with display: inline
, this will cause the textarea, video, img, select or input to shrink according to its content (i.e. use the natural width as it is for video and img, and just resize itself according to the content for textarea, select or input). This should also cause them to overflow the containing block without resizing itself, behaving as if there was just one long line of text.
(For iframe it may not be feasible to actually resize the width according to its contents. Potentially it should just resolve to 0px as if there were no contents?)
When intrinsic-size
is set to auto
, all the crazy sizing behaviours for img, video, input, select, textarea and iframe are kept as they are currently defined, with img and video sized to their natural width, input, select and textarea to platform defined widths, and iframe to be 300px x 150px, regardless of whether they are block or inline.
I would like the idea to choose on which axis the field gets (re)sized. So a property with multiple values might be an idea...
Also, shouldn't this be more consistent with a "resize" terminology?
field-resize-type: content; field-resize-direction: inline/block/x/y
Resulting in a field-resize: content block. Yes, the use case for inline will be a lot less, but I don't think we should exclude this completely.
Also: Could we do this by updating the resize property? resize: vertical; would still do what it does today. But upgrading it to have more possible values and possibly create a shorthand from it. Not sure if that last one is even slightly possible. But just putting it out there.
Then the new properties would be: resize-type: content; resize-direction: horizontal, vertical, inline, block
And shorthand: resize: content vertical; While making sure that resize: vertical; is still allowed and keeps working
I am not an expert on the matter, but wanted to make sure that options like this were considered. Not sure if it's possible, but going this route feels a bit more consistent.
@brechtDR This is just about the intrinsic size, so you can always set e.g. width
to some explicit value, and that will take precedence over the contents. So individual axis control may not be needed.
The resize
property seems an entirely different functionality, so I would be against conflating the two.
@hfhchan wrote:
I suggest this property be called
intrinsic-size
, and instead ofcontent
andfixed
, it should benone
andauto
....
(For iframe maybe dynamically resizing its height according to content is too difficult to implement and/or introduces security risks. But at least the width should behave like all other display: block elements. Potentially the height should just resolve to 0px as if there were no contents?)
...
(For iframe it may not be feasible to actually resize the width according to its contents. Potentially it should just resolve to 0px as if there were no contents?)
When
intrinsic-size
is set toauto
, all the crazy sizing behaviours for img, video, input, select, textarea and iframe are kept as they are currently defined, with img and video sized to their natural width, input, select and textarea to platform defined widths, and iframe to be 300px x 150px, regardless of whether they are block or inline.
Resizing iframes based on their contents is discussed in #1771. And it was resolved on adding a contain-intrinsic-size: from-element
.
So that somewhat overlaps with your suggested intrinsic-size
property. And I wonder whether that should be reused for this use case.
In any case, I like the idea of introducing something that covers all the mentioned cases, as they are related.
Sebastian
I gave this some more thought of how this should play with intrinsic sizes of replaced elements, and I suggest renaming my previous proposal to intrinsic-sizing
to make it clearer that the intrinsic size isn't the thing being changed, but how the intrinsic size affects the layout is being changed.
Suppose you have an <img src="file.jpg" width="1600" height="900">
. Assuming we apply display: block
and intrinsic-sizing: none
, and the containing block had 800 pixels, the img
tag should occupy the space of 800 x 450 pixels. So the intrinsic size of the replaced element is still 1600 x 900, but the intrinsic size now only contributes to the intrinsic aspect ratio, and not directly to the width and/or height.
For form elements (input, select, textarea), it works either way to describe it as the intrinsic size no longer being platform defined but relying on the content, or the platform defined intrinsic size no longer applies and the element is laid out like a normal element.
@hfhchan The width="1600"
will set width: 1600px
as a presentational hint, see https://html.spec.whatwg.org/multipage/rendering.html#attributes-for-embedded-content-and-images. So the width should be 1600px, not 800px.
Now there is a problem, when field-sizing: content
is set, the cursor is missing. See
https://bugs.chromium.org/p/chromium/issues/detail?id=1523248
https://github.com/w3c/csswg-drafts/assets/2784308/16e12026-a7dc-47b3-bdc6-8badce1fa2a3
That's an implementation issue, not a spec issue.
See: https://github.com/whatwg/html/issues/6807 for more context about the problem we'd like to solve. The TL;DR is that we'd like to allow the
<textarea>
element to be sized to its contents a little easier. I.e.We explored different solutions in the whatwg thread. Folks seem to prefer a CSS solution to this problem - hence this issue!
One way to achieve the "minrows"/"maxrows" in that issue is to use the "lh" unit. (Fortunately the "lh" unit works exactly the same way textareas are implemented today - in that they use the first available font to calculate the line-height).
E.g.
The only thing we are missing is the ability to use the "actual"[1] intrinsic size of the textarea. There are a few different potential solutions here.
Today the intrinsic-size of a textarea will (roughly) read the "rows" attribute, and multiply this by the "lh" unit. We need a switch to instead read the "rows" attribute to be based on the actual number of lines. One potential solution is:
textarea-rows: auto | <number>
If "auto" was set the user-agent would read the number of lines, then multiply this by "lh" to get the intrinsic block-size for the text-area.
We could then map the rows attribute to a presentation style hint to this property.
cc/ @tabatkins @lilles