Html: Allow <input type="color"> to give an alpha channel?

Created on 25 Jan 2018  Â·  27Comments  Â·  Source: whatwg/html

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.

additioproposal needs implementer interest forms

Most helpful comment

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?

All 27 comments

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.

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.

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.

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.

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!

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.

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).

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.

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.

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.

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.

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.

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 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.

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

valueAsColor() doesn't help with submission.

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.

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.

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 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.

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 my concern was only the duplication of that overlap; if it's relatively straight forward then I am even more interested in this approach.

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.

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...

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.

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.

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.

Was this page helpful?
0 / 5 - 0 ratings