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

[css-ui?] Allow <input> and <select> to be sized by contents #7552

Closed
LeaVerou opened this issue Aug 1, 2022 · 12 comments
Closed

[css-ui?] Allow <input> and <select> to be sized by contents #7552

LeaVerou opened this issue Aug 1, 2022 · 12 comments

Comments

@LeaVerou
Copy link
Member

LeaVerou commented Aug 1, 2022

As I pointed out in #7542, one often wants to size single-line form controls by contents. Primary use cases are UIs which look like regular content with some parts are editable (e.g. form letters). Here's an example from Google Sheets using select-like controls.

image

This is currently insanely difficult to do well with native form controls due to things like spinner arrows, date input picker triggers, dropdown arrows etc. It would be nice if we could just do width: fit-content. A lot of the issues with height: max-content that were mentioned in #7542 only apply to textareas and thus shouldn't apply here. Placeholders do still apply, but I don't see why they wouldn't be considered "content", they are shadow DOM descendants. On a regular element shadow DOM descendants absolutely take part in calculating it's intrinsic size. So this should do the right thing for placeholders anyway.

@emilio did some preliminary research on implementability of this in Gecko and said it should be fairly easy to implement (he made a prototype for <select> in 2 minutes and for <input> in another 10!).

@dbaron
Copy link
Member

dbaron commented Aug 1, 2022

Is the difference between what you propose here for combobox <select>s (i.e., those with display size == 1) and their current default behavior that:

  • the current default behavior sizes to all of the <option>s
  • with what you propose, the <select> would size only to the currently-selected <option>?

@LeaVerou
Copy link
Member Author

LeaVerou commented Aug 2, 2022

Is the difference between what you propose here for combobox <select>s (i.e., those with display size > 1) and their current default behavior that:

  • the current default behavior sizes to all of the <option>s
  • with what you propose, the <select> would size only to the currently-selected <option>?

Correct.

@bfgeek
Copy link

bfgeek commented Aug 2, 2022

This does have similar issue to #7542 in that all these form elements already have some algorithm for defining their min-content, and max-content sizes. E.g. its roughly interoperable if you size various input elements as width:min-content today.
These min-content / max-content sizes are using directly within the flexbox algorithm. E.g. used for the content-size suggestion, flex-basis:content, etc.

E.g. the <select> min/max content algorithm considers children. Above is just a different min/max content algorithm.

@emilio What happens when you trigger the min-content behaviour in flexbox (a zero width row flex should trigger, or do flex-basis:content).

@emilio
Copy link
Collaborator

emilio commented Aug 2, 2022

@bfgeek behavior changes as you'd expect, I agree this is just a different min/max algo

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed Allow <input> and <select> to be sized by contents.

The full IRC log of that discussion <emilio> topic: Allow <input> and <select> to be sized by contents
<emilio> github: https://github.com//issues/7552
<emilio> lea: so this is related to the <textarea> issue
<emilio> ... this is about sizing the width of <input> and <select> of form controls to match the contents
<emilio> ... it's insanely difficult to do right today
<emilio> ... you need to use a span to measure, or measure scrollHeight if you have overflow, etc
<emilio> ... you don't know how big the icons in date / time / number inputs
<emilio> ... it'd be nice to size these based on their contents
<emilio> ... it'd be elegant if you could just say "width: fit-content" or so
<emilio> ... not sure if that's web-compatible
<emilio> ... a lot of the issues re. <textarea> are not present
<emilio> iank_: not strictly true
<fantasai> emilio: It's not hard to implement
<fantasai> emilio: but there's a lot of different considerations
<fantasai> emilio: for example, the most obvious one after going through this code, is if you odn't want to size it to the size of, for example, autofill suggestions
<fantasai> emilio: if you multiple options to choose from, right now when you hover over the option we preview it
<fantasai> emilio: but we dont' expose that to the page until you actually interact with it
<fantasai> lea: I think it's fine to ignore autofill
<fantasai> lea: never seen a use case that involved passwords
<astearns> ack dbaron
<emilio> dbaron: few thoughts, one of them is "what counts as contents": does placeholder count?
<iank_> q+
<emilio> ... one of the other things you might run into is that for text inputs and you wanna resize as people type you might find the performance of it to be suboptimal
<emilio> ... and that's gonna be a little unpleasant
<astearns> ack iank_
<emilio> ... but I guess people will deal with it if that's what they want
<lea> q+ wrt placeholders
<emilio> iank_: this has the same issue as textarea
<emilio> ... where min/max-content are used directly within the flexbox algorithm
<astearns> ack wrt
<astearns> ack place
<emilio> ... I don't think we can ship anything that changes min-content in these
<astearns> qq+ lea
<emilio> q+
<emilio> iank_: sounds like what emilio implemented yesterday would've changed all of those
<emilio> fantasai: you mean the automatic minimum size?
<astearns> ack fantasai
<Zakim> fantasai, you wanted to ask if it's min-content or the automatic minimum size
<emilio> iank_: also the content size if you use flex-basis: content
<emilio> ... also somewhere else
<emilio> fantasai: I think we could say that the automatic minimum size is whatever size we currently get from html attributes
<emilio> ... but if you use min-width: 0 then you won't be using these
<emilio> s/these/ams
<emilio> ... and then width: max-content to remove the influence of automatic preferred sizes
<emilio> ... and these are both things that you need to do and shouldn't cause a compat issue
<lea> q+ you cannot use min-width: 0; with this, as that would make the input tiny when you delete all content.
<emilio> fantasai: I'm proposing changing the meaning of max-content
<emilio> ... so there's a preferred size
<emilio> ... currently entering flexbox via ams and automatic preferred size
<emilio> ... these are tied to keywords, `min-width: auto`, etc
<fantasai> emilio: but in terms of actual behavior changes
<fantasai> emilio: basically, how do you change the min- or max-content
<fantasai> emilio: what I'm imagining you're saying is, make this change to the max-content size
<fantasai> emilio: so max-content on an input follows the content
<fantasai> emilio: but in flexbox either special case and not call it max-content for inputs
<emilio> fantasai: flexbox doesn't use max-content, it works in terms of contributions
<emilio> iank_: it does work in terms of max-content
<emilio> fantasai: it only does if width is auto, right?
<emilio> iank_: so to opt into this you'd need to change min-width and flex size
<emilio> fantasai: because of ams is tied to this you need to remove it in min-width and so
<emilio> iank_: I agree it'd work but I don't think that'd be a great solution, we already have compat issues with <input> using min-content and stuff like that
<fantasai> emilio: so you're proposing for auto size to be as-is
<fantasai> emilio: and split max-content from preferred size
<fantasai> emilio: which right now are the same
<fantasai> emilio: I'm not a huge fan of adding more intrinsic width types, but maybe it's not too much of a pain
<emilio> iank_: when we were changing the min-width/height: auto behavior, we found that lots of people that set min/max-width: 0
<emilio> ... also common to use flex: 1 1 0 and so
<lea> q?
<dholbert> s#min/max-width:0#min-width/min-height#
<emilio> ... and there you'd change a lot of stuff, seems scary
<astearns> ack lea
<Zakim> lea, you wanted to react to placeholders
<emilio> lea: Wanted to say that placeholders should be considered for calculating the width
<emilio> ... it's implemented as shadow dom descendant
<emilio> ... but also what if we say that this only works if min-width is >0
<TabAtkins> Also very hesitant to override any of the existing content size keywords for this, but am happy to have a new keyword (or two?)
<emilio> ... in most cases you do need to specify min-width of zero
<emilio> ... it's user-hostile to not have that
<iank_> q+
<emilio> fantasai: it's user-hostile to do that ~everywhere
<emilio> ... but we can't do that because it'd be discontiguous
<emilio> nous*
<emilio> fantasai: we could introduce a new max-content-no-i-really-mean-it
<emilio> ... but I'd rather avoid that
<bkardell_> this-is-my-final-answer-max-content
<emilio> TabAtkins: I'd rather do that, I share iank_'s concerns
<astearns> ack emilio
<fantasai> emilio: for select in particular, I don't think it's so problematic
<fantasai> emilio: because it's almost never empty by default
<fantasai> emilio: but for input it seems very sketchy
<dholbert> `max-form-content` or `max-field-content`?
<fantasai> emilio: I also recall Firefox, in terms of select intrinsic sizing
<TabAtkins> oooh yeah i like dholbert's ideas
<fantasai> emilio: because we actually consider the option styles
<fantasai> emilio: I fixed that
<TabAtkins> since these keywords won't mean anything for non-form controls
<fantasai> emilio: it was not an easy change
<astearns> ack iank_
<TabAtkins> (we'll just define them to resolve to min-content or something)
<emilio> iank_: re. placeholder I'm not convinced that it's feasible because we remove the placeholder from the dom when the field is focused
<emilio> ... so you don't want the input to shrink down
<lea> q?
<lea> q+
<emilio> ... when looking into textarea, people let the placeholder overflow sometimes etc
<emilio> ... there's something to consider
<emilio> ... for <select> I think the real usecase it's a different min/max-content algorithm
<emilio> ... all browsers match the current behavior of longest option
<astearns> ack lea
<emilio> ... so you really want a different intrinsic sizing algorithm
<emilio> lea: you say that you remove the placeholder from the dom when you focus
<emilio> ... but it's still visible
<emilio> iank_: when you actually enter content
<emilio> lea: yeah but then you want the input to be sized to the content
<emilio> iank_: I don't think that's what users would expect
<emilio> bramus: I think I agree
<emilio> ... if you have a placeholder with your name then it'd snap
<emilio> lea: in such a form then you wouldn't use this feature
<emilio> ... also you'd define the placeholders with that in mind
<emilio> bramus: but if you have a long place-holder then...
<emilio> lea: that's what min-width is for
<astearns> this is a much different use of an input that was considering
<astearns> s/was/I was/
<emilio> iank_: I think then people wouldn't consider the placeholder and it might get cropped
<emilio> q+
<emilio> lea: they can always use min-width
<emilio> ... for other use cases it's weird to have so much space around your control
<astearns> ack emilio
<dholbert> q+
<fantasai> emilio: I agree that you should be able to use something like input:not(:placeholder-shown) { min-width: .. } and it will be discontinuous when you start hiding it
<fantasai> emilio: in FF we don't remove the placeholder from the DOM, we just hide it with visibility:hidden
<fantasai> emilio: so the min-width of the input is the width of the placeholder
<fantasai> emilio: it is implementable, but ...
<fantasai> iank_: we might have some of ours out-of-flow so they don't contribute to baselines or something like that
<fantasai> emilio: it woudl be great to be interoperable on how we impleemtnt these as well
<fantasai> iank_: this is why I wanted to focus on textarea
<fantasai> iank_: developer need is very clear
<fantasai> iank_: Ideally, we'd standardize on internal structures so we can get exact correct thing
<fantasai> emilio: regarding select, agree that it's effectively a different intrinsic sizing algorithm
<fantasai> emilio: the current one, max-content and new one can be min-content
<fantasai> emilio: it's not amazing, it can be useful
<fantasai> emilio: I was a bit skeptical about this until Lea showed me some slides
<fantasai> emilio: I agree that just changing the meaning of min- or max-content might not be great
<fantasai> emilio: maybe a new property like form-intrinsic-size: legacy ?
<fantasai> emilio: and a new keyword?
<fantasai> emilio: that could work
<fantasai> emilio: and could also work for textarea sizing
<fantasai> emilio: change it so it makes sense
<fantasai> iank_: I agree that would be a nice thing
<fantasai> iank_: my only concern then is, doesn't allow us to ???
<fantasai> iank_: it doesn't allow us to do this in a piecemeal fashion, we have to get everything correct once
<fantasai> iank_: which is a big undertaking
<fantasai> s/once/at once/
<fantasai> emilio: on the flip side, you end up adding one property instead of one per element
<fantasai> emilio: and it has a name that may make more sense
<fantasai> emilio: and not specific for this particular kind of element
<fantasai> emilio: but I agree
<fantasai> iank_: that's why with textarea one I really focused on changing how you multiply lh unit nternally
<fantasai> iank_: but I see what you're saying
<emilio> fantasai: we have an intrinsic-sizing property
<emilio> ... which was intended to fix some of the problems with the way we calculate intrinsic sizing
<emilio> ... so we have a place to put it
<fantasai> https://www.w3.org/TR/css-sizing-4/#intrinsic-contribution-override
<emilio> min-intrinsic-sizing
<emilio> ... names are not amazing, suggestions welcome
<emilio> ... this was about the compressible stuff
<emilio> ... so the reason why everybody puts min-width: 0 on everything is because of this
<astearns> ack dholbert
<emilio> dholbert: two thoughts: first one is that if we have a unified keyword / property for input and textarea
<emilio> ... you might end up with a textarea sizing the line greedily
<emilio> ... sort of the fit-content for textarea vs. max-content with single-line input
<emilio> ... we might need to be a bit careful there
<emilio> ... the first screenshot shows a <select>-like input, but less convinced about <input>
<emilio> ... would be good to collect the use cases for these
<emilio> ... willing to believe there are good use cases though the one on the issue seemed a bit abstract
<emilio> iank_: if I had to rank what devs would use
<emilio> ... auto-expanding textarea is the most common I've seen. I agree <select> is probably common as well, but I haven't seen many auto-growing <input>
<emilio> bramus: I've seen those in settings-like pages, like newsletter subscription, with a paragraph with two or three text-fields inside
<emilio> astearns: should we go back to the issue, add examples, possible ways of specifying this
<emilio> *?

@bramus
Copy link
Contributor

bramus commented Aug 2, 2022

The forms I was talking about in the meeting are named “natural language forms”.

image

It might have been a fashion thing because most articles I find date from 2013-2015. Nonetheless, that would be a use-case.

@SebastianZ
Copy link
Contributor

... auto-expanding textarea is the most common I've seen. I agree is probably common as well, but I haven't seen many auto-growing

There are definitely some auto-growing <input>s out there. One I can think of is the editor for CSS properties and values in the browser DevTools. I don't have a website example at hand, though there are surely several ones that do the same.

Sebastian

@LeaVerou
Copy link
Member Author

LeaVerou commented Aug 3, 2022

Several use cases, posted as a reply to my tweet:

Google image search options (not implemented with <select> but totally could be):

ezgif-4-a9f1f850b9

Random design system: (source)

ezgif-4-8d87f8ff89

Datadog:

ezgif-4-e8adf8bc29

OSX Contacts app:
image

At https://app.sendcash.africa/home (source)
image

Inputs at https://matrixcalc.org/ (source)

image

Several people also mentioned tag UIs like:

image

Filter with text-align: center; and autosized <select>
https://area.at/de/expertise-ueberblick

image

This has both:
image

natto.dev does this for editable node titles (source):

image

Select elements are not used here in part because the the width of the differing options. (source)
https://peoplecare.com.au:

image

Another natural language form (source):

image

And another one: (source)

image

"For <select>, there is this breadcrumb scenario which would be great to have auto-sized widths (with a max-width, of course) based on current selection. Currently, I'm forced to make my best guess for width and then text-overflow:ellipsis." (source):

image

And several more examples mentioned in the thread without links or visuals. Several other people saying how they've wanted to do this, but the difficulty of doing it today deterred them.

Last but not least, dev tools:
image

And some of mine:

To-do list:

image

Editable talks list:

image

Invoicing app demo:

image

@emilio
Copy link
Collaborator

emilio commented Aug 17, 2022

For my own reference, here's the Gecko changes lea is talking about in the OP: https://gist.github.com/emilio/7affed0677dd1a26caf482a025a60635

@yisibl
Copy link
Contributor

yisibl commented Sep 1, 2023

Add a case: Ant Design's textarea component is height-adaptive and can set the maximum number of lines.

https://ant-design.antgroup.com/components/input#components-input-demo-autosize-textarea

@LeaVerou
Copy link
Member Author

LeaVerou commented Feb 6, 2024

Should we close this now that we have field-sizing? (I cannot find the WG resolution for it, it must have linked to some other issue)

@astearns
Copy link
Member

astearns commented Feb 6, 2024

@LeaVerou #7542 (comment)

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

No branches or pull requests

9 participants