html icon indicating copy to clipboard operation
html copied to clipboard

Allow <input type="color"> to give an alpha channel and/or colors beyond sRGB?

Open domenic opened this issue 7 years ago • 49 comments
trafficstars

Or some new related input type.

Suggested in https://twitter.com/jashkenas/status/956321122684878848. It does seem like for a large class of color inputs, e.g. image editors, this would be a good idea.

domenic avatar Jan 25 '18 00:01 domenic

With the normalized format being defined as a simple color, it's quite likely that both clientside and serverside logic have come to depend on this for processing the value. There are likely also use cases where only accepting opaque colors is desirable.

Taking that into consideration, it's probably necessary to introduce a new alpha-color (or color-alpha) type which takes a CSS <color> as its value to avoid breaking existing expectations. This can potentially be normalized to the eight-digit hexadecimal notation to make the two color types consistent and easier to transition between.

Zirro avatar Jan 25 '18 08:01 Zirro

Just adding some references here to other disucssion as I just became aware of this limitation. Could hardly believe that didn't support the CSS3 transparency stuff. Seems like a serious inconsistency in the the cooperating language specs.

References:

Discussion at https://github.com/w3c/html/issues/1422 which was closed, suggesting further discussion here.

https://bugzilla.mozilla.org/show_bug.cgi?id=1613301 My bug report on Firefox, before I became aware this was a spec issue.

@Zirro is probably correct that a new type would be required.

v-python avatar Feb 06 '20 18:02 v-python

Agree that a new input type is likely necessary due to the existing consumers that likely depend on the 6-hex format. I also agree that just using the 8-hex format for this type="color-with-alpha" (or whatever) is the easiest way to go about this.

Thinking a little further, tho, CSS has grown colors beyond what the hex format can describe, both with wider gamuts than the 0-255 range and with more precision than those integers can provide. We might want to instead consider a format that allows more expansive color definitions; this would require more impl support promises than the seemingly-obvious addition of just throwing in alpha, but it has promise.

In particular, the most general format of built-in colors that we could use for serializing the value is, I believe, the lab() function. (Ignoring things like imported color profiles, which requires more support than I think would be reasonable for an input type.) @svgeezus might have more details on that.

tabatkins avatar Feb 06 '20 19:02 tabatkins

There was a link in one discussion I found to a tool used in DevTools of the "big 3" browsers already: https://bgrins.github.io/spectrum/ but it doesn't seem to have lab() function output.

It might be a good model to follow for a picker, if it can be extended to support the broadest CSS color spaces, and I agree that there is no point in making an extension one step at a time.

One thing that seems nice about this picker is the conversion functions so that you can obtain the colors in a variety of formats. While a new picker implementation should probably support the broadest currently-planned or standardized color spaces, perhaps the new HTML input type should have a way of specifying what format is desired for output, which would not only serve the purpose of allowing compatibility with the current type=color (which could be revised ot use the same picker, if practical implementation-wise), but would cover the case of future additions to color-spaces, should any happen: while the picker could get improved to handle even broader color-spaces, the input type could have a way to specify the format it wants back, for compatibility with the usage it is put to, avoiding the need to invent more new input types for future color-space expansion.

v-python avatar Feb 06 '20 21:02 v-python

In particular, the most general format of built-in colors that we could use for serializing the value is, I believe, the lab() function. (Ignoring things like imported color profiles, which requires more support than I think would be reasonable for an input type.) @svgeezus might have more details on that.

Paging @svgeesus because of the earlier username typo.


Lack of alpha channel support in <input type=color> is the main reason we have a custom color picker implementation in Chrome DevTools at this point. We'd love to get rid of our custom color picker in favor of the platform!

mathiasbynens avatar Mar 31 '20 16:03 mathiasbynens

Thanks @mathiasbynens :)

I agree that the addition of alpha has merit; note that now in CSS Color 4, the rgb() form can also have an optional alpha and rgba is legacy.

Also agree with @tabatkins that a new input type will be required to avoid breaking code that assumes 6-digit hex, only.

If a new input type is defined now, to add alpha, how likely is it that another one could be added further down the line? Do we only get one shot at this? Some considerations:

  • other, wider gamut RGB(A) colorspaces are coming, notably display-p3 which corresponds to the wide gamut screens already shipping on phones, laptops and external monitors
  • because of that, greater bit-depth that 8 bits per component is desirable (for a wider space you need more bits to avoid banding). display-p3 really needs 10 bits per component; rec2020 requires a minumum of 10 and really needs 12. CSS already has a way to specify arbitrary precision, for example rgb(87.234% 23.123% 6.987654321%) but existing implementations tend to truncate this to 8 bits per component.

So, when minting a new color input type that accepts alpha, being able to accept a) a higher bit depth than 8-per-component and b) being able to accept other RGB spaces than sRGB should at least be considered, as useful future proofing.

Looking further forward, CIE Lab (and LCH, the polar form) are coming, CSS Color 4 specifies them and there is implementer interest; CSS Color 5 uses these to do color modification such as color mixing. These types really need to use 3 floats. LCH is also a nice model for a color picker because it is perceptually uniform unlike, say, HSL.

I would love to see Lab and LCH added but, if now is not the time, their likely impact should be considered when making a new RGB(A) input type.

While a new picker implementation should probably support the broadest currently-planned or standardized color spaces, perhaps the new HTML input type should have a way of specifying what format is desired for output

That would be a very useful, and nicely future proof, addition which would lessen the impact when it gets extended because developers would already be asking for the specific format their scripts are expecting.

svgeesus avatar Apr 02 '20 16:04 svgeesus

the most general format of built-in colors that we could use for serializing the value is, I believe, the lab() function. (Ignoring things like imported color profiles, which requires more support

Not specific to a color input type, but just for clarification: color profiles, such as for CMYK, take as input a Lab value so the lab() function would be just fine there too. I agree though that a color input type should probably not be offering CMYK etc choices (and in particular, should not offer them if it is doing naive conversion).

svgeesus avatar Apr 02 '20 16:04 svgeesus

Chiming in from the sidelines here, I think two of the general API design considerations for this sort of thing are:

  • <input> is already a mess. We could add more to the mess (e.g. a new type="" value, or a format="" that applies only to type="color", or valueWithAlpha/valueAsWideGamut getters, or...). Or we could start over with a new input type (e.g. like switch attempted). Although it'd be nice to avoid extending the mess, it sure is convenient and expedient.

  • Reusing <input> also has a better backward-compatibility story. For example if we did <input type="alphacolor"> then in browsers that don't implement the user would get a text box, which might be better than nothing. Or, if we reused <input type="color"> and added some of the additions mentioned above, we could have sites which accept alpha-less colors in older browsers and alpha-ful colors in new ones.

So overall, I guess I'd urge thinking about what you want your story to be for web developers, when they are trying to support both browsers that implement the new type, and browsers that don't. That guides whether to reuse <input> or not, and if so, how to extend it.

domenic avatar Apr 02 '20 16:04 domenic

By the way, an example of an LCH color picker, with alpha (which I have been using to help me make examples for CSS Color 4). Not that this helps the design of an HTML input control, just that people who have not come across Lab and LCH might find it interesting to play with.

svgeesus avatar Apr 02 '20 17:04 svgeesus

So overall, I guess I'd urge thinking about what you want your story to be for web developers, when they are trying to support both browsers that implement the new type, and browsers that don't. That guides whether to reuse <input> or not, and if so, how to extend it.

For new input types, the web developer story has always been detecting support, and loading a custom fallback implementation if needed, à la:

function supportsInputType(type) {
  const input = document.createElement('input');
  input.type = type;
  return input.type === type;
}

if (!supportsInputType('color')) {
  enhanceColorInputs();
}

In my opinion, adding a new input type, separate from color, seems like the way to go.

mathiasbynens avatar Apr 03 '20 11:04 mathiasbynens

While a new picker implementation should probably support the broadest currently-planned or standardized color spaces, perhaps the new HTML input type should have a way of specifying what format is desired for output

That would be a very useful, and nicely future proof, addition which would lessen the impact when it gets extended because developers would already be asking for the specific format their scripts are expecting.

So, something like:

<input type="color-2.0" colorspace="display-p3">
input.value; // -> 'color(display-p3 1 1 1 / 0.42)'

<input type="color-2.0" colorspace="srgb">
input.value; // -> 'color(srgb 1 1 1 / 0.42)'

We could also provide input.valueAsColor(colorspace) (similar to input.valueAsNumber() and input.valueAsDate()), which lets developers programmatically get a serialized CSS <color> of the form 'color(colorspace 1 1 1)' in the colorspace of their choosing.

@svgeesus Is my assumption that any CSS color can be represented as color(...) correct? Will this be true going forward? In that case, color(...) seems like the ideal serialization.

mathiasbynens avatar Apr 07 '20 16:04 mathiasbynens

Is my assumption that any CSS color can be represented as color(...) correct? Will this be true going forward? In that case, color(...) seems like the ideal serialization.

This is currently true, and there's a good chance it will remain true in the future. However, CSS has made the affirmative decision to serialize with the more specific functions when we can; sRGB colors with rgb(), lab colors with lab(), etc., and we would presumably match that here.

I actually rather like the .valueAsColor() idea, because it lets us separate the ideas of colorspace and serialization format (so we could serialize as hsl() or lch() if the author wanted, which could def be useful).

The colorspace="" attribute would still be useful on the input itself, so it knows what color range to show in the picker; presumably it would default to sRGB if unspecified.

tabatkins avatar Apr 07 '20 22:04 tabatkins

I'm not a huge fan of introducing another input type. Input type="color" has pretty low usage overall and I think as long as we by default return what we do today we shouldn't need a new input. Can we do progressive enhancement here, such that adding in the attribute of colorspace will result in the value being changed?

gregwhitworth avatar Apr 16 '20 19:04 gregwhitworth

@gregwhitworth You’d need at least one attribute for the colorspace and another attribute to enable the alpha-channel. Personally I’d rather avoid the combinatorial explosion of options if we can avoid it.

mathiasbynens avatar Apr 17 '20 05:04 mathiasbynens

I actually rather like the .valueAsColor() idea, because it lets us separate the ideas of colorspace and serialization format (so we could serialize as hsl() or lch() if the author wanted, which could def be useful).

Another idea would be to expose a Color constructor as CSS.Color (although this would be specified in CSSOM, not HTML), which could programmatically represent CSS color values and convert them to various formats and across color spaces. (It’s not either-or; we could do .valueAsColor as well if that seems useful.) cc @zcorpan

mathiasbynens avatar Apr 17 '20 05:04 mathiasbynens

valueAsColor() doesn't help with submission.

annevk avatar Apr 17 '20 08:04 annevk

For submission, the regular .value would be used, which for a new <input type="css-color"> could be the serialized CSS color.

If we decide to extend <input type="color"> instead, e.g. <input type="color" alpha widegamut>, we could do the same thing, except that if none of the new attributes are present the current "valid simple color" serialization is used.

mathiasbynens avatar Apr 17 '20 12:04 mathiasbynens

If we decide to extend instead, e.g. , we could do the same thing, except that if none of the new attributes are present the current "valid simple color" serialization is used.

This is exactly what I had in mind. One aspect that I would be open to entertaining that I've been wanting to explore but haven't dug into the HTML parser too far is doing away with the input type within HTML (not the API extension) altogether for complex inputs. Color is actually a prime example of this, while yes it can be represented as a string, very few end user scenarios are actually going to enter them in as such so PE for this doesn't make much sense in the majority of use cases. Even for pros they'll normally have them separated out where the color input is actually represented by different inputs using a text field - photoshop being a prime example of this:

image

What if, color 2.0 is actually just <color>? It would then get its own HTMLColorInputElement which we would hopefully be able to have a base interface from HTMLInputElement (maybe this is already the case in IDL form as well) as we would of course still need to support value, validation, etc.

gregwhitworth avatar Apr 17 '20 16:04 gregwhitworth

What if, color 2.0 is actually just <color>?

I would prefer a new tag, though one completely unrelated to HTMLInputElement. (You can't have that as a base class without inheriting all of its complexity.)

There are no parser concerns if it parses like any unknown/custom element. (I.e., the end tag is required.)

See my above comment at https://github.com/whatwg/html/issues/3400#issuecomment-607954731.

domenic avatar Apr 17 '20 16:04 domenic

@domenic that's great - sorry I missed that statement but I would really prefer to have a new control altogether with HTML tag and input element. My only hesitation is while HTMLInputElement is a mess we may have to duplicate a lot of the properties that do overlap still. I'm going to float this by our devs though just in case I'm missing something here.

gregwhitworth avatar Apr 17 '20 16:04 gregwhitworth

I don't quite understand what you mean by "have a new control altogether with HTML tag and input element". But in general I'd encourage you to look at https://github.com/tkent-google/std-switch/, or just at <select> or <textarea>, which are existing examples of form controls that don't use <input>. The overlap is basically:

  • Validity stuff
  • form, labels
  • name, type
  • disabled

Additionally the following apply to some controls but not others: required, placeholder, readonly, autocomplete, minlength, maxlength. One of the major benefits of using a new element (like select/textarea/std-switch) is to only include the ones from that list which apply to your case.

domenic avatar Apr 17 '20 16:04 domenic

@domenic my concern was only the duplication of that overlap; if it's relatively straight forward then I am even more interested in this approach.

gregwhitworth avatar Apr 17 '20 16:04 gregwhitworth

Awesome. The main downside of a new control is the fallback story being less automatic, but @mathiasbynens seems to indicate that most developers use JavaScript for fallbacks anyway, so maybe it's less of a concern.

domenic avatar Apr 17 '20 16:04 domenic

Yeah, fallback to text, while barely acceptable for color input, is still pretty terrible, so a JS-driven fallback is pretty much required for a decent UX.

I need to finally get the Typed OM story together for CSSColorValue objects, so this could return one of those...

tabatkins avatar Apr 17 '20 16:04 tabatkins

Yeah, fallback to text, while barely acceptable for color input, is still pretty terrible, so a JS-driven fallback is pretty much required for a decent UX.

I don't want to hijack this thread but has there been a general discussion around ALL inputs and which should get the same treatment? If not I'll fork this one as I'd like to do that in one fell swoop and possibly in alignment with the folks doing research at Open UI.

gregwhitworth avatar Apr 17 '20 16:04 gregwhitworth

Specific to naming, it's surprising to see how few component frameworks actually create a color picker (name matrix here). But it seems that if we're going to create a new element then it should either be <color> or <colorpicker>. Colorpicker has 2 usages where as color has 1.

gregwhitworth avatar Apr 17 '20 16:04 gregwhitworth

In hindsight, I think it was a mistake to extend input for the cases where text input fallback isn't useful enough (like color, date/time, range). To continue to add new types or extensions to existing types to represent new controls will add to the complexity further.

A downside to creating a new element for colorpicker is that there would be 2 ways to create a colorpicker. We already have this situation with buttons, without it causing much trouble, as far as I can tell.

zcorpan avatar Apr 17 '20 21:04 zcorpan

Since this discussion has evolved beyond just alpha channels, and is now about choosing colors beyond sRGB, could someone please edit the title accordingly?

LeaVerou avatar Jan 14 '21 11:01 LeaVerou

Hello,

I am creating a HDR version of TestUFO

Which works great in 2 browsers, with moving AVIF sprites

  1. Safari Ventura and Safari 16.1 iOS/iPadOS for display-p3
  2. Chrome Canary (Experimental Features) for rec2100-pq

So I am already working on cross-platform HDR.

However, some of the tests need a HDR color picker of some kind -- even if it is a genericized version (gamut XYZ selector or a copycat of the Unity HDR color picker)

Here's an example test that requires a HDR color picker: https://www.testufo.com/chase and https://www.testufo.com/blurtrail which is used for testing display technologies. (this is the public SDR TestUFO)

For those unaware of Blur Busters audience

My popular display motion testing website impacts 500+ content creators with over 100 million people total.

See credit proof: Includes RTINGS (9M), LinusTechTips (14M) as two examples, https://www.blurbusters.com/reviewers-using-pursuit-camera ... so I have about 500 content creators (that is totalling well north of 100 million viewers/subscribers -- probably woefully huge underestimate; I'm being conservative here) who use the Blur Busters TestUFO. Blur Busters is well known in the hardcore gaming/esports communities, where display motion blur can interfere with high performance gaming, and they come to testufo/blurbusters as a textbook reference.

I am cited in over 25 peer reviewed papers related to display performance (including parties such as NVIDIA and Samsung referencing us) -- www.blurbusters.com/area51 -- and display reviewers/manufacturers use many tests that I invented.

Some tests such as https://www.testufo.com/ghosting is used by many display reviewers

So, I have a gigantic need for a HDR color picker API. Right now I use rec2100-pq canvas for Chrome Canary, and I use display-p3 canvas for Safari Ventura and iOS 16.1 .... HDR AVIFs work on both, as does artifically creating HDR colors via a 2nd canvas (get/put bytes workaround, until CSS color is introduced).

So I need some eventual movement in a HDR color picker API similar to ... however I will go with roll-my-own JavaScript colorpicker, while waiting for all web consortiums to standardize.

I need cross-platform sharing of HDR colorpicker data.

Here's an example: TestUFO links are sharable.

  1. Visitor to www.testufo.com/chase on Chrome (rec2100-pq <CANVAS> working) configures a HDR color on our working internal HDR version of TestUFO

  2. Visitor bookmarks URL and shares it on Internet

  3. Visitor on Safari Ventura/16.1+ with Apple XDR display views the same URL (display-p3 <CANVAS> working)

I already have implemented rec2100-pq canvas (Canary+Experimental) and display-p3 canvas (newest Safaris), in our experimental HDR version of TestUFO, that works with the very same AVIF files.

The AVIF library has its own built in colorspace conversion so they look (roughly) similar in both rec2100-pq canvas and display-p3 canvas, at least for colors within the overlapping area of venn diagram of the two HDR standards.

But I need a URL encoding method to share HDR colors in a cross platform manner.

I am going to have to invent my own (+useragent detection) until the web consortiums can standardize on some rough equivalent. But if y'all can get some standardization movement on suggesting how you're going to communicate HDR colors in shareable URLs -- (e.g. xyz numbers)

I suggest that ALL HDR colorpicker APIs have the ability to communicate generic xyz numbers (pre-tonemapping, default origin). That will map just fine between display-p3 and rec2100-pq. I can urlencode it instead of #FF00FF type arguments that I currently use for sharing colors between users:

https://www.testufo.com/chase#background=0000ff&leading=008080&trailing=ffff00

So I have to migrate away from 6-digit hex into a universal method that works with all HDR colorspaces in a generic manner (pre-tonemapping, common 0-origin).

Generic xyz numbers or rgbi numbers are acceptable, will upcoming platform-specific HDR color pickers be able to give generic HDR xyz/rgbi data for crossplatform communications? Will such API be standardized?

Questions

When I create my hacked implementation (my own custom color picker, my own custom HDR-communication method),

  • should I standardize on xyz or rgbi?
  • Which will be more commonalty to future color pickers?
  • Will future APIs easily pull generic HDR numbers (xyz or rgbi) from HDR-colorspace-specific colorpickers?
  • Will it be a standard URLencode of a 48-bit FP16? Will it be hex format?

I really need my future HDR-equivalent of URLs like: https://www.testufo.com/chase#background=0000ff&leading=008080&trailing=ffff00 To be successfully shareable between users using different HDR colorspaces ("best-effort", linear, pre-tonemapping, 0-origin, preferably floating point instead of integers). I can simply communicate triads like "(0.321,0.664,0.531)" if xyz is going to be standardized method of communicating across browsers.

I will for now use a Javascript HDR colorpicker (based off the DevTools version / based off the Unity version) initially, until using the web-standardized version of color picker, probably using "data" parameter to to trigger an automatic override of the standard colorpicker with a custom JavaScript HDR colorpicker.

But I need to permanently finalize the URL sharing format, and I need to figure out the best format that will most closely match the predicted standardized replacement for 6-digit hex, while preserving full cross-platform floating point precision of HDR. That way, I don't have to re-change my URL sharing format again.

Use Me as a Trailblazer Use Case

This impacts CSS color heavily, as while I am still using the getbytes/putbytes workaround (in a 2nd <CANVAS> being used as a swatch from a JavaScript-powered HDR colorpicker that uses quad RGBI for now, a JavaScript copycat of the DevTools HDR colorpicker). This is my hacky workaround to create custom HDR colors on some browsers that don't yet support CSS color in canvas (yet).

So I'm jumpstarting things, much as I did in year 2012 for 120Hz browser support -- right on the bleeding edge of HDR, just like I was on the bleeding edge of refresh rates. As the world's first HDR motion test website, we're already very bleeding edge, ahead of standards.

I want to remove as many hacks as possible as quickly as possible, and as many useragent-string if-statement hacks as possible, once more standrdization movement occurs.

Access to HDR Version of TestUFO

Launching it by CES 2023. But I can grant access to any web standardizers / web browser developers to test HDR things. Contact me mark [at] blurbusters [dot] com

mdrejhon avatar Nov 23 '22 18:11 mdrejhon

Heya, the WebKit team would be interested in driving this issue forward. We've come around to favoring the initial idea expressed in this thread of adding a single attribute to express a color space. For us that resonates with many design principles we value, such as backwards compatibility, avoiding needless complexity, and evolution not revolution. Opting in through that would then simultaneously allow for selecting a color in that color space as well as an alpha channel. We do not think that alpha channel needs a separate control point.

This would be an enumerated attribute that is reflected to allow for feature testing. And we'd like it to minimally support "srgb" and "display-p3" as values for parity with canvas, but are open to supporting more color spaces defined in CSS Color. Not sure if the current "simple color" value space needs its own attribute value or if that should be the fallback.

When the attribute is used and has one of those values the color would be serialized per the rules in CSS Color. This will make it slightly more involved to deal with on the server, if any, but that seems acceptable. This does not depend on the UI the user agent decides to expose for the control (although user agents should be aware that if they have a UI for picking Display P3 colors and the page wants sRGB there will be information loss, so they probably want to account for that somehow). The opposite is also true, a page might want "display-p3" (and will get it if the attribute is supported), but that does not mean the end user is able to select a Display P3 color necessarily. (This follows from not being able to dictate UI and also has some nice privacy properties.)

We also see valueAs[CSS]Color() as a natural extension here.

For this addition we're not interested in tackling the overall styling problem. While that is something we'd like to see addressed as well and are happy to collaborate on in parallel, we don't think it's worth blocking on that as this would provide a very meaningful improvement of color pickers to web developers on a much shorter timeframe. And this addition doesn't change the styling problem in a meaningful way. The exact same challenges remain.

Thanks to @patrickangle & @pxlcoder for their help on this proposal!

Curious to hear your thoughts!

annevk avatar Mar 12 '24 16:03 annevk