@@ -3139,65 +3139,103 @@ an implicit value of 1 (fully opaque) is the default.
31393139 Serializing color-mix()
31403140</h3>
31413141
3142- The serialization of the declared value of a ''color-mix()'' function
3143- is the string "color-mix(in ",
3144- followed by the specified <<color-space>> in all-lowercase,
3145- followed by ", ",
3146- followed by the first specified color,
3147- followed by a space,
3148- followed by the serialization of the first percentage (see below)
3149- followed by ", ",
3150- followed by the second specified color,
3151- followed by the serialization of the second percentage (see below),
3142+ The serialization of the declared value of a ''color-mix()'' function is
3143+ the string "color-mix(",
3144+ followed by, unless the <<color-space>> is ''oklab''
3145+ (whether explicitly specified or defaulted):
3146+ the string "in ",
3147+ followed by the <<color-space>> in all-lowercase,
3148+ followed by, if a <<hue-interpolation-method>> was specified
3149+ and is not ''shorter hue'' ,
3150+ " " and the <<hue-interpolation-method>> in all-lowercase,
3151+ followed by ", ",
3152+ followed by the serialization of each color argument (see below),
3153+ separated by ", ",
31523154followed by ")".
31533155
3154- The serialization of the <strong> first</strong> percentage of a declared value of a ''color-mix()'' function is defined as:
3155-
3156- - If BOTH the first percentage |p1| and second percentage |p2| are specified:
3157- - if both |p1| equals 50% and |p2| equals 50%, nothing is serialized. <!-- (a) -->
3158- - else, |p1| is serialized as is. <!-- (b) -->
3159- - else if ONLY the first percentage |p1| is specified:
3160- - if |p1| is equal to 50%, nothing is serialized. <!-- (c) -->
3161- - else, |p1| is serialized as is. <!-- (d) -->
3162- - else if ONLY the second percentage |p2| is specified:
3163- - if |p2| equals 50%, nothing is serialized. <!-- (e) -->
3164- - if |p2| is not ''calc()'' , the value of 100% - |p2| is serialized. <!-- (f)-->
3165- - else, nothing is serialized. <!-- (g) -->
3166- - else if NEITHER is specified:
3167- - nothing is serialized. <!-- (h) -->
3168-
3169- The serialization of the <strong> second</strong> percentage of a declared value of a ''color-mix()'' function is defined as:
3170-
3171- - If BOTH the first percentage p1 and second percentages p2 are specified:
3172- - if neither p1 nor p2 is calc(), and p1 + p2 equals 100%, nothing is serialized. <!-- (i) -->
3173- - else, p2 is serialized as is. <!-- (j) -->
3174- - else if ONLY the first percentage p1 is specified:
3175- - nothing is serialized. <!-- (k) -->
3176- - else if ONLY the second percentage p2 is specified:
3177- - if p2 equals 50%, nothing is serialized. <!-- (l) -->
3178- - if p2 is not calc(), nothing is serialized. <!-- (m) -->
3179- - else, p2 is serialized as is. <!-- (n) -->
3180- - else if NEITHER is specified:
3181- - nothing is serialized. <!-- (o) -->
3182-
3183- Note: ''calc()'' values are consider to be unknown,
3184- so are <strong> never</strong> equal 50%,
3185- and never sum with something else to equal 100%.
3156+ Each color argument is serialized as
3157+ the serialized <<color>> ,
3158+ followed by, if a percentage is serialized for this argument (see below),
3159+ " " and the serialized percentage.
3160+
3161+ Each color argument is serialized individually;
3162+ in particular,
3163+ identical colors are not collapsed into a single argument.
3164+
3165+ The serialized percentages
3166+ of the declared value of a ''color-mix()'' function
3167+ are determined as follows.
3168+ Let |N| be the number of color arguments.
3169+
3170+ For each argument,
3171+ let its <dfn>effective percentage</dfn> be:
3172+ - its specified <<percentage>> ,
3173+ if one was explicitly provided
3174+ and is not a ''calc()'' expression;
3175+ - if its <<percentage>> was omitted,
3176+ and none of the other specified <<percentage>> s
3177+ are ''calc()'' expressions:
3178+ <code> (100% − |specified sum|) / |omitted count|</code> ,
3179+ where |specified sum| is the sum of the explicitly specified <<percentage>> s
3180+ and |omitted count| is the number of arguments
3181+ with omitted <<percentage>> s;
3182+ - otherwise, unknown.
3183+
3184+ If all [=effective percentage=] s are known
3185+ and equal to <code> 100% / |N|</code> ,
3186+ no percentages are serialized.
3187+ Otherwise, each argument's percentage is serialized as follows:
3188+ - If a <<percentage>> was explicitly specified,
3189+ it is serialized as-is.
3190+ - If a <<percentage>> was omitted
3191+ and none of the other specified <<percentage>> s
3192+ are ''calc()'' expressions:
3193+ the value
3194+ <code> (100% − |specified sum|) / |omitted count|</code>
3195+ is serialized,
3196+ where |specified sum| and |omitted count| are as defined above.
3197+ - Otherwise (a <<percentage>> was omitted
3198+ but another argument has a ''calc()'' <<percentage>> ):
3199+ nothing is serialized.
3200+
3201+ Note: ''calc()'' values are considered unknown,
3202+ so are <strong> never</strong> equal to <code> 100% / |N|</code> ,
3203+ and prevent computation of omitted <<percentage>> s.
31863204
31873205<div class="example" id="ex-serial-specified-mix">
31883206 For example, the serialized declared value of
31893207 <pre> color-mix(in oklab, teal, peru 40%)</pre>
3190- would be the string "color-mix(in oklab, teal 60%, peru)".
3208+ would be the string "color-mix(teal 60%, peru 40%)":
3209+ the color space is omitted because it is the default (''oklab'' ),
3210+ and all percentages are serialized
3211+ because they are not all equal to 100%/2 = 50%.
31913212
31923213 The serialized declared value of
31933214 <pre> color-mix(in oklab, teal 50%, peru 50%)</pre>
3194- would be the string "color-mix(in oklab, teal, peru)".
3215+ would be the string "color-mix(teal, peru)":
3216+ both percentages equal 100%/2 = 50%, so they are all omitted.
31953217
31963218 The serialized declared value of
31973219 <pre> color-mix(in oklab, teal 70%, peru 70%)</pre>
3198- would be the string "color-mix(in oklab, teal 70%, peru 70%)"
3199- because the fact that these normalize to 50% each
3200- is only discovered after percentage normalization.
3220+ would be the string "color-mix(teal 70%, peru 70%)":
3221+ the specified percentages are 70%, not 50%,
3222+ so they are not omitted,
3223+ even though they normalize to 50% each during computation.
3224+
3225+ The serialized declared value of
3226+ <pre> color-mix(in oklch longer hue, red, green, blue)</pre>
3227+ would be the string "color-mix(in oklch longer hue, red, green, blue)":
3228+ the color space (''oklch'' ) is not the default,
3229+ the hue interpolation method (''longer'' ) is not the default (''shorter'' ),
3230+ and all percentages equal 100%/3, so they are all omitted.
3231+
3232+ The serialized declared value of
3233+ <pre> color-mix(red 50%, green, blue)</pre>
3234+ would be the string "color-mix(red 50%, green 25%, blue 25%)":
3235+ the percentages are not all equal to 100%/3,
3236+ so all are serialized,
3237+ including the omitted ones
3238+ which each get (100% − 50%) / 2 = 25%.
32013239</div>
32023240
32033241The serialization of the result of a ''color-mix()'' function
@@ -3829,6 +3867,14 @@ This specification adds a way to ensure adequate contrast for text whose backgro
38293867 (<a href="https://github.com/w3c/csswg-drafts/issues/12513">Issue 12513</a> )
38303868 </li>
38313869 <li> Added a color-mix() example with three colors, now that it is no longer restricted to just two.</li>
3870+ <li> Updated color-mix() serialization:
3871+ omit color space when it is the default (oklab),
3872+ serialize hue interpolation method when non-default,
3873+ generalize percentage rules for N colors
3874+ (omit all when equal to 100%/N, otherwise serialize all),
3875+ and clarify that identical colors are not collapsed
3876+ (<a href="https://github.com/w3c/csswg-drafts/issues/13320">Issue 13320</a> )
3877+ </li>
38323878</ul>
38333879
38343880<h3 id="changes-20250318">
0 commit comments