You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
text-opacity-{x} is a Windi rule that introduces an extra variable to control text opacity.
This variable could enable us to control text opacity separately from color, which would be useful, but implementation is lacking. We can only use this variable as an alternate syntax for Tailwind text-{color}/{opacity}:
<divclass="text-red text-opacity-50">Windi, uses variable</div><divclass="text-red/50">Tailwind, single class, doesn't require variable</div>
Separation of color and opacity is quite interesting if we could change them separately. For example reduce opacity to de-emphasize some text while preserving the current color.
<divclass="text-red">
Useful idea: dim text.
This is <spanclass="text-opacity/50">NOT 50%.</span></div><divclass="text-opacity/50">
Less useful, but also an idea.
This is <spanclass="text-red">NOT 50% either.</span></div>
Intuitively you could expect these to work, but neither does. Let's see why.
First the generated CSS:
The outer text-opacity does not apply to inner text-red, because text-red resets --un-text-opacity to 1.
I don't think this is a very useful use-case, so for compatibility purposes I'd say we could keep it unchanged.
The other scenario is useful and the reason why it doesn't work is subtle:
CSS properties inherit their computed value, not their source expression!
So the span.text-opacity-50 inherits the computed color: rgb(248 113 113 / 1). It does not have a dependency on any variable and changing --un-text-opacity at this level has no effect.
Setting both rules on the same element only works because text-opacity-50 is declared after text-red in CSS stylesheet, so it's declaration of --un-text-opacity "wins". Using both class on the same element seems a little wasteful when we can use a single class, constant text-red/50.
Suggested solution
I tweaked the rules as follow:
/* Variant 1: full support for independent opacity control top-down and bottom-up */
.text-red {
/* removed: --un-text-opacity: 1 */--un-color:rgb(248113113); /* added */color:rgb(248113133/var(--un-text-opacity));
}
.text-red/50 {
--un-color:rgb(248113113); /* added as well, to be able to use /opacity syntax and still tweak color inside */color:rgb(248113113/0.5);
}
.text-opacity-50 {
--un-text-opacity:0.5;
color:rgb(from var(--un-color) r g b /0.5); /* added, force re-computing the color */
}
/* Variant 2: text-red resets opacity to 1 for back-compat, so controlling opacity higher up in DOM is not possible */
.text-red {
/* removed: --un-text-opacity: 1 */--un-color:rgb(248113113); /* added */color:rgb(248113133); /* removed / var(--un-text-opacity) */
}
.text-red/50 {
--un-color:rgb(248113113); /* added */color:rgb(248113113/0.5);
}
.text-opacity-50 {
color:rgb(from var(--un-color) r g b /0.5); /* added */
}
Removing --un-text-opacity from text-red enables top-down cascade of opacity.
As I said it's not the most useful use case so might be kept in if we want to minimize breakage.
Notice that if we keep this backward compatible behavior, --un-text-opacity is not necessary at all and can be dropped. When both text-red text-opacity-50 are declared on the same element, the new color rule of the later takes over (as it's declared after text-red, same reasoning as previously).
Introducing a new variable --un-color to text-color rules lets us re-compute the color property in child elements that use text-opacity, enabling opacity to affect colors picked higher up.
Alternative
If you want to be able to dim elements by reducing their opacity, while keeping any current color, I don't see any other way to achieve this.
You might think that this style could be a cheap solution: rgb(from currentColor r g b / 0.5).
It's actually valid CSS that works when assigned to any property... except color.
The problem is that using currentColor inside color property creates a circular reference that doesn't work :(
Additional context
Other rules work identically, in particular bg-red and bg-opacity-50.
I'd say they would benefit from the same change.
It also opens up new uses cases, for example I'd love being able to darken a background when mouse is pressed (e.g. on a button, or a clickable items).
If there was a variable --un-bg-color then I could create a rule active:bg-darken-10.
Clear and concise description of the problem
text-opacity-{x}
is a Windi rule that introduces an extra variable to control text opacity.This variable could enable us to control text opacity separately from color, which would be useful, but implementation is lacking. We can only use this variable as an alternate syntax for Tailwind
text-{color}/{opacity}
:Separation of color and opacity is quite interesting if we could change them separately. For example reduce opacity to de-emphasize some text while preserving the current color.
Intuitively you could expect these to work, but neither does. Let's see why.
First the generated CSS:
The outer
text-opacity
does not apply to innertext-red
, becausetext-red
resets--un-text-opacity
to 1.I don't think this is a very useful use-case, so for compatibility purposes I'd say we could keep it unchanged.
The other scenario is useful and the reason why it doesn't work is subtle:
CSS properties inherit their computed value, not their source expression!
So the
span.text-opacity-50
inherits the computedcolor: rgb(248 113 113 / 1)
. It does not have a dependency on any variable and changing--un-text-opacity
at this level has no effect.Setting both rules on the same element only works because
text-opacity-50
is declared aftertext-red
in CSS stylesheet, so it's declaration of--un-text-opacity
"wins". Using both class on the same element seems a little wasteful when we can use a single class, constanttext-red/50
.Suggested solution
I tweaked the rules as follow:
Removing
--un-text-opacity
fromtext-red
enables top-down cascade of opacity.As I said it's not the most useful use case so might be kept in if we want to minimize breakage.
Notice that if we keep this backward compatible behavior,
--un-text-opacity
is not necessary at all and can be dropped. When bothtext-red text-opacity-50
are declared on the same element, the newcolor
rule of the later takes over (as it's declared aftertext-red
, same reasoning as previously).Introducing a new variable
--un-color
totext-color
rules lets us re-compute thecolor
property in child elements that usetext-opacity
, enabling opacity to affect colors picked higher up.Alternative
If you want to be able to dim elements by reducing their opacity, while keeping any current color, I don't see any other way to achieve this.
You might think that this style could be a cheap solution:
rgb(from currentColor r g b / 0.5)
.It's actually valid CSS that works when assigned to any property... except
color
.The problem is that using
currentColor
insidecolor
property creates a circular reference that doesn't work :(Additional context
Other rules work identically, in particular
bg-red
andbg-opacity-50
.I'd say they would benefit from the same change.
It also opens up new uses cases, for example I'd love being able to darken a background when mouse is pressed (e.g. on a button, or a clickable items).
If there was a variable
--un-bg-color
then I could create a ruleactive:bg-darken-10
.Validations
README.md
of using the package.The text was updated successfully, but these errors were encountered: