String Output
ColorAide supports serializing colors in the same formats that it accepts as inputs. This includes all CSS formats for the associated color spaces, and if a color space is not supported in CSS, the color(space ...)
format. ColorAide exposes various options to allow users to serialize in the form they most prefer.
Convert to Strings
Colors can be serialized to strings by using the to_string
method. The color class will convert the current color into one of the many of CSS formats supported for the given color space.
>>> Color("srgb", [0.5, 0, 1], 0.3).to_string()
'rgb(127.5 0 255 / 0.3)'
There are a number of options that are common among all color spaces, but there are also some color space specific options. We will only cover the color spaces shipped with ColorAide. It is possible to write a color space plugin that uses very different options.
Common Options
All color spaces support the following parameters.
Alpha
alpha
is set to None
by default and controls whether the alpha channel is shown in the serialized output. When in the default state, alpha
will only be shown if the alpha channel has a value less than 100%, but if set to True
, alpha will always be shown. Setting to False
will cause alpha to be ignored in the output.
Precision
precision
controls the precision of the output values. The name is a little misleading as it will actually adjusts the precision and scale of the values. The default is 5. In some cases, like the sRGB hex output, precision may not really come into play as hex values are rounded to the nearest whole number.
>>> Color("rgb(30.3456% 75% 100%)").to_string(precision=5, percent=True)
'rgb(30.346% 75% 100%)'
>>> Color("rgb(30.3456% 75% 100%)").to_string(precision=4, percent=True)
'rgb(30.35% 75% 100%)'
>>> Color("rgb(30.3456% 75% 100%)").to_string(precision=3, percent=True)
'rgb(30.3% 75% 100%)'
>>> Color("rgb(30.3456% 75% 100%)").to_string(precision=2, percent=True)
'rgb(30% 75% 100%)'
>>> Color("rgb(30.3456% 75% 100%)").to_string(precision=1, percent=True)
'rgb(30% 80% 100%)'
Providing a precision of 0
will enable simple rounding to the nearest whole number.
>>> Color("rgb(30.3456% 75% 100%)").to_string(precision=0, percent=True)
'rgb(30% 75% 100%)'
Providing a precision of -1
is a special input that will give the highest, useful precision that can be given. Precision will be given out to double precision. Higher can be used, but will most likely be unhelpful.
>>> Color("rgb(30.3456% 75% 100%)").to_string(precision=-1, percent=True)
'rgb(30.345600000000001% 75% 100%)'
One note though, format of the value matters. Here we output in the range of 0 - 255. We can see that a precision of 1
, in this case, can throw the color out of gamut. So remember to use a sufficient precision for what you are doing and the values you are working in.
>>> Color("rgb(30.3456% 75% 100%)").to_string(precision=1)
'rgb(80 200 300)'
There are some times where the channel coordinates need to have different precision, for instance the alpha channel which always has values between 0 - 1 may be a very different scale than CIELab which scales lightness between 0 - 100. In these cases, it may be desirable to use a different precision for alpha, especially when rounding other channels to integers.
If needed, users can control precision per channel by providing a list of precision, each index in the list corresponding to the channel at that index.
>>> Color("rgb(30.3456% 75% 100% / 0.75)").to_string(precision=[0, 0, 0, 3])
'rgb(77 191 255 / 0.75)'
If a channel is omitted, the default precision is assumed for that channel.
>>> Color("rgb(30.3456% 75% 100% / 0.75)").to_string(precision=[0, 0, 0])
'rgb(77 191 255 / 0.75)'
New in 4.0: Per Channel Precision Control
Fit
fit
is set to True
by default and controls whether colors are fit to their gamut or not. Some color spaces are technically unbounded, so no fitting may occur in those color spaces. Additionally, some color formats, like sRGB hex, are always fitted (regardless of this setting) as they must fit into the gamut or they cannot be translated.
>>> Color("rgb(30% 105% 0%)").to_string()
'rgb(107.26 255 58.5)'
>>> Color("rgb(30% 105% 0%)").to_string(fit=False)
'rgb(76.5 267.75 0)'
Additionally, we can choose a different fitting method by passing fit
the name of the method we would like.
>>> Color("rgb(30% 105% 0%)").to_string()
'rgb(107.26 255 58.5)'
>>> Color("rgb(30% 105% 0%)").to_string(fit='clip')
'rgb(76.5 255 0)'
Some gamut mapping plugins may expose more options. To set these options, you can use a dictionary. Specify the method via the method
and any other options by their name.
>>> Color("rgb(30% 105% 0%)").to_string(fit={'method': 'oklch-chroma', 'jnd': 0.002})
'rgb(144.58 255 123.58)'
Color
color
, for some color spaces, is the default output, but for others this format can be explicitly requested by setting color
to True
. If set to True
, this will take priority over other format options.
>>> Color("rebeccapurple").to_string(color=True)
'color(srgb 0.4 0.2 0.6)'
None
Colors that have undefined channels are internally represented with NaN
. On output, these can be displayed as none
per the most recent CSS spec. These are very new, so most browsers do not support them. This is disabled by default until a time when this behavior is common enough. NaN
values will not survive fitting unless a color channel is naturally undefined. An example would be a hue when the color has saturation or chroma set to zero.
>>> Color('hsl(none 0% 30%)').to_string(none=True)
'hsl(none 0% 30%)'
The one exception is that legacy rgb()
, rgba()
, hsl()
, and hsla()
forms (comma separated) do not support none
per the CSS spec.
Percent
Color formats can serialize channels with percents by using percent
.
>>> Color("rebeccapurple").to_string(percent=True)
'rgb(40% 20% 60%)'
>>> Color("rebeccapurple").convert('lab').to_string(percent=True)
'lab(32.393% 30.738% -38.153%)'
By default, only HSL and HWB output channels with percents by default to match browser expectations which do not yet support colors with non-percent output for their non-hue channels. This is specifically only true for the named color function formats: hsl()
and hwb()
.
>>> Color("rebeccapurple").convert('hsl').to_string()
'hsl(270 50% 40%)'
>>> Color("rebeccapurple").convert('hsl').to_string(percent=False)
'hsl(270 50 40)'
If serializing with the CSS legacy format (comma format), percentage will be forced for saturation and lightness when serializing HSL.
>>> Color("rebeccapurple").convert('hsl').to_string(comma=True)
'hsl(270, 50%, 40%)'
>>> Color("rebeccapurple").convert('hsl').to_string(comma=True, percent=False)
'hsl(270, 50%, 40%)'
Percent output is supported for the color()
function output as well.
>>> Color("rebeccapurple").convert('srgb').to_string(color=True, percent=True)
'color(srgb 40% 20% 60%)'
If it is desired, explicit control over each channel can be achieved by passing in a sequence containing booleans.
>>> Color('rebeccapurple').convert('lab').to_string(alpha=True, percent=[True, False, False, True])
'lab(32.393% 38.423 -47.691 / 100%)'
Any omitted list values will be assumed False
.
>>> Color('rebeccapurple').convert('lab').to_string(alpha=True, percent=[True])
'lab(32.393% 38.423 -47.691 / 1)'
New 2.12
Boolean sequence support for percent
added in 2.12.
Format Specific Options
These options may occur in various color spaces depending on the CSS output format.
Comma
In CSS, there are a few color spaces that allow a comma format: srgb
and hsl
. ColorAide allows these to be read in and to be output in their legacy comma format. These are the only formats that ship with comma support.
If we want commas, we can force the comma syntax by setting comma
to True
. This can alter some color space output in other subtle ways. As the comma format is the old legacy approach, when sRGB has commas enabled, it will use rgba
instead of rgb
. If using the non-comma syntax, rgb
is always used, even when the color has transparency.
>>> Color("rgb(30 75 100 / 20%)").to_string(comma=True)
'rgba(30, 75, 100, 0.2)'
sRGB Specific Options
These options are currently specific to the sRGB color space.
Hex
sRGB can output colors to a hex format which is unique compared to HSL and others. Simply enable hex
.
>>> Color("rebeccapurple").to_string(hex=True)
'#663399'
Upper
You can force hex to output in uppercase.
>>> Color("red").to_string(hex=True)
'#ff0000'
>>> Color("red").to_string(hex=True, upper=True)
'#FF0000'
Compress
When converting to the hex color format, a color can be compressed in certain cases. Enabling compress
will compress a hex color if possible.
>>> Color("#11223388").to_string(hex=True)
'#11223388'
>>> Color("#11223388").to_string(hex=True, compress=True)
'#1238'
Names
sRGB can also output color names. If a color evaluates to a hex code which also evaluates to a color name in the internal CSS color name mapping, then a color name will be returned. If the color does not match a color name, it will fallback to whatever the other options dictate.
>>> Color("#663399").to_string(names=True)
'rebeccapurple'