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-text] Provide CSS support for automatic spacing (or other separators) in text input field #4875

Open
marvindanig opened this issue Mar 14, 2020 · 19 comments

Comments

@marvindanig
Copy link

marvindanig commented Mar 14, 2020

This is a feature request to allow styling of the text input field for formatted inputs like credit card or date or phone number with an area code. Currently this is not possible without using javascript.

Shown below is an example where a credit card number is split into groupings of four digits each:

image

In general, people tend to use comma separation or spaces between large numbers (like a credit card) to pin for accuracy of input. So in some ways this is an accessibility issue as well.

At this point all of the solutions out there require using javascript to format the inputted string by listening to the onblur event. There are even libraries from large providers to style the information fields such as this one from Stripe. Linked here is the Twitter thread that prompted this proposal.

@AmeliaBR AmeliaBR changed the title [css-text-input] Proposal to allow basic formatting of the text input field. [css-text] Provide CSS support for automatic spacing (or other separators) in text input field Mar 15, 2020
@AmeliaBR
Copy link
Contributor

I agree that this is a common design need. I don't have references right now, but I remember reading somewhere that editing the input on blur (to add hard-coded spaces or other separators) can be an accessibility issue.

My rough strawman proposal (from the Twitter thread) was that spacing could be supported by extending the letter-spacing property to support a sequence of spaces, like 0 0 0 1ch for a space after every fourth character.

But that wouldn't help with things like automatically adding dashes to phone numbers or automatically formatting numbers with commas, so maybe a more dedicated number-format approach would be better.

I still think it's useful to talk about this in CSS (as opposed to something like a format attribute on an HTML <input>), so that the same approach works for custom inputs or general number formatting (e.g., in a data table).

@Loirooriol
Copy link
Contributor

Something like a custom text-transform that replaces every 4th character with itself and a space or dash? The spec already says

A future level of CSS may introduce the ability to create custom mapping tables for less common text transforms, such as by an @text-transform rule similar to @counter-style

@Crissov
Copy link
Contributor

Crissov commented Mar 16, 2020

This be #3132 then.

With @frivoalʼs proposal, authors could change the separators and grouping characters, but they could not add them at arbitrary places or intervals.

@tabatkins
Copy link
Member

Yeah, I agree that this is a pretty common and reasonable thing to want. Scoping the design will be interesting, but I suspect it's doable.

@plinss
Copy link
Member

plinss commented Mar 16, 2020

Note that not all credit cards use a 4/4/4/4 format. Other common formats are 4/4/4, 4/4/5, 4/4/4/2, 4/6/5, 6/11, 6/12, 6/13, and 4/4/4/3. A proper credit card input implementation will look at the card digits to determine the issuer and switch formats as the user is typing. Similar issue for phone numbers. Whatever we do here has to be dynamic, at the least letting the author change formats in a non-destructive manner in response to input events.

@AmeliaBR
Copy link
Contributor

@plinss That's a good point. But considering that all existing implementations use dynamic JS anyway, it might still be an improvement if they could preserve the distinction between the input characters and the formatting adjustments.

@plinss
Copy link
Member

plinss commented Mar 16, 2020

I’m not saying that odd cases like credit cards and phone numbers should be doable without JS entirely, a small amount of code in an oninput to swap formats is fine, and IMO desirable because there’s no way we can predict all the ways this will be used. Just that an author should be able to swap the formatter dynamically without interfering with user input.

I wrote a CC input that does the dynamic formatting by adjusting the value, and it was a PITA and still likely misbehaves in some circumstances. I’d love to be able to throw that away for something that works gracefully.

@tabatkins
Copy link
Member

Ah yup, a script that just adjusts input.style.formatPattern on the fly would be big improvement over that.

@ByteEater-pl
Copy link

Per the principle of least power, could regular expressions be a viable alternative to scripting? (Events could be fired anyway in case the author wants to do something more than declaratively possible, as with animations and much other CSS stuff.)

@fantasai
Copy link
Collaborator

fantasai commented May 1, 2020

I think this request makes a lot of sense, but I think it probably belongs at the HTML layer. @ByteEater-pl’s suggestion to use regex makes sense: we already have a pattern attribute to validate input, maybe a format attribute that, using captured substrings, describes the output formatting?

@ByteEater-pl
Copy link

While validation is indeed a host language concern, displaying transformed text seems more like a generalization of text-transform and applicable regardless of if it's HTML being styled or something else.

@faceless2
Copy link

This seems to be another variation of "I need to apply a transform to text styled with CSS to modify spacing, or change it in a way more complex than what we can currently do with text-transform".

It's a problem that keeps coming up. it's been solved so many times and in so many ways, it seems odd that a more generalised "text-fixup" option isn't part of CSS. Here's my partial list of references.

https://www.w3.org/TR/css-text-4/#text-spacing-property
https://www.w3.org/Style/2013/paged-media-tasks#text-fix
https://www.princexml.com/doc/css-props/#prop-prince-text-replace
https://www.antennahouse.com/product/ahf66/ahf-ext.html#axf.text-replace
https://specs.rivoal.net/css-custom-tt/
https://books.idea.whatwg.org/#character-substitution
#4246

All of these proposals relate primarily* to changing the formatted value of the text, rather than the logical value: this proposal included (I don't think there request is that spaces are included as part of the submitted credit card number, just that they're included when the value is displayed on screen).

For this reason I think it's a styling issue and part of CSS's domain.

(*) this is a slightly blurred distinction - first because although that seems to be how it's normally used, it doesn't have to be (see for example https://lists.w3.org/Archives/Public/www-style/2008Sep/0013.html), and second because of #3775

@AmeliaBR
Copy link
Contributor

AmeliaBR commented May 5, 2020

I am currently filling out a PDF form & I noticed that after I edit, it is automatically formatting the numbers with commas for thousands separators. Here are Adobe docs for the types of formats that are supported:
https://helpx.adobe.com/ca/acrobat/using/pdf-form-field-properties.html#format_tab_for_form_field_properties

Might be worth further investigation to see if that model could be adapted in a consistent yet CSS-compatible way.

@faceless2
Copy link

faceless2 commented May 5, 2020

In PDF that's all done with JavaScript.

PDF has "keypress" events which fire as you type into the field, and a "format" event which fires when the value of the field changes. It also makes a distinction between the actual value of the field and the formatted value as it appears on screen - the two can be different, which is how you can get commas in the values you see on screen, but not in the submitted value.

@TimeTerminal
Copy link

It's been a year and half since this issue was opened. Any further discussion or proposal on this?

@SebastianZ
Copy link
Contributor

So far there wasn't any further discussion, obviously.

I really like the idea of an @text-transform rule as proposed in #3132 and mentioned earlier by @Crissov. Though that proposal would need to be extended to also cover adding characters at specific positions and other more complex transformations than simple character replacements.

Sebastian

@Crissov
Copy link
Contributor

Crissov commented Jan 30, 2024

text-transform, for now, is about using the glyphs of other characters, so it could only apply if there already was a grouping character. Therefore, I think this feature should be handled by a different property, e.g.:

text-segmentation := <segment-pattern> 
                  || from [start | end | word-start | word-end | <string>] 
                  || by <separator>
<segment-pattern> := scientific | engineering | indic | iban | isbn | issn | ismn | ean | ip-4 | ip-6 | phone
                   | <digit>+[, <digit>+]? ; before <string> (e.g. integer) and, if different, after <string> (fraction)
<separator> := period | dot | comma | hyphen | underscore | apostrophe | colon | slash
             | space | tab | invisible | none | name | <string>
text-trim := [space || zero || punctuation | none | <string>]{1,2} ; start and, if different, end
text-pad := [start | end | both | none] 
         || to [<number> | <length> | line | group] 
         || by [zero | space | underscore | <string>]
/* <data class="number">123456.7890</data> */
.number:lang(en)     {text-segmentation: 3, 0 from period by comma;}   /*  123,456.7890 */
.number:lang(en-IN)  {text-segmentation: 2 3, 0 from period by comma;} /* 1,23,456.7890 */
.number:lang(ko)     {text-segmentation: 4 from period by comma;}      /*  12,3456.7890 */
.number:lang(en-ISO) {text-segmentation: 3 from period by space;}      /*  123 456.789 0 */
.number:lang(de)     {text-segmentation: 3 from period by period;      /*  123.456,789.000 */
                      text-transform: decimal-comma; text-pad: zero to group}
.number:lang(de-CH)  {text-segmentation: 3 from period by apostrophe;  /*  123’456.789 */
                      text-trim: zero;}
/* <data class="coupon-code">AB12CD34EF</data> */
.coupon-code {text-segmentation: 4 from end by hyphen;}  /* AB-12CD-34EF */
.coupon-code {text-segmentation: 5 from start by slash;} /* AB12C/D34EF */
.coupon-code {text-segmentation: 2 by space;}            /* AB 12 CD 34 EF */

Transformation between number formats like these would be in scope for text-transform or a future sub-property if it was turned into a shorthand:

  • 123.456,789
  • 123,456.789
  • 123’456·789
  • 123 456.789

… as would be transformation between code formats like these:

  • 123-456-789
  • 123_456_789
  • 123:456:789
  • 123/456/789
  • 123 456 789
  • 123⁣456⁣789 U+2063 Invisible Separator
  • 123​456​789 U+200B ZWSP
  • 123 456 789 U+0009 Tab

… and the digit style itself of course #9877 ;)

PS: If the CSSWG decided that this should in fact be in scope of text-transform, I would suggest to turn it into a shorthand property with text-transform-replace and text-transform-segment expansions.

Example use cases

  • IBAN: group by four alphanumerical characters from the left, e.g. XY12 3456 7890 1234 5678 90
  • ISBN: [3:]1:2:6:1 with hyphen as separator, e.g. 978-1-23-456789-0 or 1-23-456789-0
  • EAN-13: : 1:6:6 with space as separator, e.g. 9 781234 567890
  • ISSN: 4:4 with hyphen as separator (without issue number), e.g. 1234-5678
  • ISMN: [3:]1:4:4:1 with hyphen as separator, e.g. 979-0-1234-5678-9 or M-1234-5678-9

@tszyuloveyou
Copy link

May I know which time can use.

@tomwhoiscontrary
Copy link

I wonder if the interaction with copy and paste should to be considered.

For example, in the UK, bank accounts have sort codes which are conventionally written 01-23-45. I'd like to be able to type into a sort code field using only digits, and have it displayed conventionally. But i would also like to be able to copy from a conventionally formatted source, say a PDF invoice, and paste that into a sort code field, hyphens and all, and get the right result.

Then what happens if i select all and copy from such a field? Should i get back what i typed, or what i see? What if the application populated the field, and i never typed anything?

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