Vixen
dd8b0a81
csharp
public static class UtilityComposition

The --tw-* fragments utilities contribute to, and what each one is worth unset.

Read the guide page for this →

Remarks

A composed utility sets a custom property instead of a declaration, and a different utility assembles the pieces. from-accent emits no background-image at all — it emits --tw-gradient-from, and bg-linear-to-r is what reads the fragments and builds the gradient. Twelve of the 328 Tailwind roots in docs/plan/43-web-styling-parity.md are this shape, and the same pattern is how v4 does transforms (translate-x + scale + rotate into one transform), box-shadow and filters. So this is not a gradient feature.

⚠ The composition is resolved by the cascade at use time, not by the generator at emit time, and the reason is variants. from-accent hover:from-accent-hover is two rules with two different selectors, and which one supplies the colour is a question only the cascade can answer — it depends on whether the pointer is over the element *now*. A generator composing when it emits knows neither, so it would have to either drop the variant (silently: the exact failure this programme exists to eliminate) or emit the cross-product of every fragment-bearing class with every assembler class, which needs a selector naming both — .bg-linear-to-r.hover\:from-accent-hover:hover — and grows as assemblers × fragments × variants. CompositionTests holds both halves of that argument as tests rather than as prose.

⚠ An unset custom property poisons the whole declaration, and the initial value here is the answer to it. Per CSS, a var() that resolves to nothing and carries no fallback makes the declaration invalid at computed-value time — VarSubstitution implements exactly that, by returning null. So a naive linear-gradient(var(--tw-gradient-from), var(--tw-gradient-via), var(--tw-gradient-to)) would make from-red to-blue with no via produce no gradient at all rather than a two-stop one. The web's two answers are @property with an initial-value, or a var() fallback chain. Vixen has no @property; it has had the fallback chain since VarSubstitution was written, so every fragment is declared here with its initial value and is only ever referenced through Reference, which welds the two together. A fragment that cannot say what it is worth unset does not belong in this table.

What @property would still buy, so that its absence is a known quantity rather than a discovery. Two things, neither of which blocks this mechanism. Registration carries inherits: false, and Vixen's custom properties all inherit — see IsCustomProperty — so a fragment set on a box is visible to its descendants, and a child carrying an assembler and no fragments of its own picks up its parent's. That is what unregistered custom properties do on the web too, so it is correct CSS and a divergence from Tailwind, which registers them precisely to stop the leak. Registration also gives a fragment a type, which is what lets a browser interpolate one — so a transitioned gradient is out of reach until it exists. Neither is a prerequisite: both are refinements to a mechanism that works without them.

Fields and properties (63)

  • public const string Prefix

    The prefix every fragment name carries.

  • public const string GradientFrom

    The gradient's first stop colour.

  • public const string GradientVia

    The gradient's middle stop colour, when there is one.

  • public const string GradientTo

    The gradient's last stop colour.

  • public const string GradientFromPosition

    Where the first stop sits.

  • public const string GradientViaPosition

    Where the middle stop sits.

  • public const string GradientToPosition

    Where the last stop sits.

  • public const string GradientStops

    The assembled stop list every gradient assembler interpolates.

  • public const string MaskFrom

    The mask ramp's first stop colour. Only its alpha is read.

  • public const string MaskTo

    The mask ramp's last stop colour. Only its alpha is read.

  • public const string MaskFromPosition

    Where the mask ramp's first stop sits.

  • public const string MaskToPosition

    Where the mask ramp's last stop sits.

  • public const string MaskLinearAngle

    A linear mask's direction.

  • public const string MaskConicAngle

    Where a conic mask's sweep starts.

  • public const string ScrollSnapStrictness

    Whether a snapping container must land on a candidate or only may.

  • public const string TransitionDuration

    How long a transition the transition class started runs for.

  • public const string MaskRadialPosition

    Where a radial mask's centre sits, as a CSS <position>.

  • public const string MaskRadialSize

    Which ellipse a radial mask's ramp ends on.

  • public const string MaskRadialShape

    Whether a radial mask's ending shape is a circle or an ellipse.

  • public const string MaskLinear

    The mask-image layer a linear mask, or a set of edge ramps, fills.

  • public const string MaskRadial

    The layer a radial mask fills.

  • public const string MaskConic

    The layer a conic mask fills.

  • public const string MaskOpaque

    A gradient that covers everything, which is the initial value of every mask layer.

  • public static readonly string[] MaskEdges

    The four box edges a mask-t-* ramp and its siblings run from.

  • public const string TranslateX

    How far along x a transform moves the box.

  • public const string TranslateY

    How far along y.

  • public const string ScaleX

    How much a transform scales the box along x.

  • public const string ScaleY

    And along y.

  • public const string RotateZ

    How far a transform spins the box about the axis normal to the screen.

  • public const string SkewX

    How far a transform slants the box along x, as an angle.

  • public const string SkewY

    And along y.

  • public const string Ordinal

    The ordinal flag, which is on or absent.

  • public const string SlashedZero

    The slashed-zero flag, which is on or absent.

  • public const string NumericFigure

    Whichever of lining-nums and oldstyle-nums was written last.

  • public const string NumericSpacing

    Whichever of proportional-nums and tabular-nums was written last.

  • public const string NumericFraction

    Whichever of diagonal-fractions and stacked-fractions was written last.

  • public const string RingWidth

    How thick a ring is, as a length.

  • public const string RingColor

    What colour it is.

  • public const string RingOffsetWidth

    How wide the gap between the element and its ring is, as a length.

  • public const string RingOffsetColor

    What colour the gap is painted in.

  • public const string Shadow

    The shadow-* token, held as a fragment so a ring can be layered over it.

  • public const string InsetShadow

    The inset-shadow-* token, which is a whole inset shadow.

  • public const string InsetRingWidth

    How thick an inner ring is, as a length.

  • public const string InsetRingColor

    What colour it is. RingColor's currentcolor, for its reason.

  • public const string Blur

    How far a filter: blur() spreads, as a Gaussian standard deviation.

  • public const string Brightness

    How much a filter: brightness() scales the colour. One is unchanged.

  • public const string Contrast

    How much a filter: contrast() pushes away from mid grey. One is unchanged.

  • public const string Grayscale

    How far a filter: grayscale() drains the colour. Zero is unchanged.

  • public const string Invert

    How far a filter: invert() flips the colour. Zero is unchanged.

  • public const string Saturate

    How much a filter: saturate() scales the distance from grey. One is unchanged.

  • public const string Sepia

    How far a filter: sepia() ages the colour. Zero is unchanged.

  • public const string HueRotate

    How far a filter: hue-rotate() turns the hue. Zero is unchanged.

  • public const string DropShadow

    A filter: drop-shadow()'s arguments: two or three lengths and a colour.

  • public const string BackdropBlur

    How far a backdrop-filter: blur() spreads. As Blur.

  • public const string BackdropBrightness

    How much a backdrop-filter: brightness() scales the colour. One is unchanged.

  • public const string BackdropContrast

    How much a backdrop-filter: contrast() pushes away from mid grey. One is unchanged.

  • public const string BackdropGrayscale

    How far a backdrop-filter: grayscale() drains the colour. Zero is unchanged.

  • public const string BackdropHueRotate

    How far a backdrop-filter: hue-rotate() turns the hue. Zero is unchanged.

  • public const string BackdropInvert

    How far a backdrop-filter: invert() flips the colour. Zero is unchanged.

  • public const string BackdropOpacity

    How far a backdrop-filter: opacity() fades the backdrop. One is unchanged.

  • public const string BackdropSaturate

    How much a backdrop-filter: saturate() scales the distance from grey.

  • public const string BackdropSepia

    How far a backdrop-filter: sepia() ages the colour. Zero is unchanged.

  • public static IReadOnlyList<string> Fragments

    Every fragment a utility family can set, ordered.

Methods (23)

  • public static string MaskEdge(string edge)

    The whole gradient one edge's ramp assembles to.

  • public static string MaskEdgeFrom(string edge)

    One edge ramp's near colour. Only its alpha is read.

  • public static string MaskEdgeTo(string edge)

    One edge ramp's far colour.

  • public static string MaskEdgeFromPosition(string edge)

    Where one edge ramp's near stop sits.

  • public static string MaskEdgeToPosition(string edge)

    Where one edge ramp's far stop sits.

  • public static bool IsFragment(string property)

    Whether a property is a fragment rather than something a consumer reads.

  • public static string InitialValueOf(string fragment)

    What a fragment is worth when nothing has set it.

  • public static string Reference(string fragment)

    How an assembler refers to a fragment: a var() carrying its initial value.

  • public static string MaskLayers()

    The three-layer mask-image every mask-* utility emits.

  • public static string MaskEdgeLayers()

    The four-layer value the edge ramps give MaskLinear.

  • public static string MaskEdgeImage(string edge)

    One edge's ramp, as a gradient running towards that edge.

  • public static string MaskImage(string shape, string geometry)

    One mask assembler: the shape, its geometry, and the two-stop ramp.

  • public static string StopList(bool via)

    The comma-separated stop list a gradient function takes.

  • public static string Translation()

    The two-axis value a translate declaration takes.

  • public static string Scaling()

    The two-axis value a scale declaration takes.

  • public static string NumericFigures()

    The keyword list a font-variant-numeric declaration takes.

  • public static string Transform()

    The function list a transform declaration takes.

  • public static string Ring()

    The box-shadow a ring is.

  • public static string RingOffset()

    The box-shadow the gap under a ring is.

  • public static string InsetRing()

    The box-shadow an inner ring is: Ring with the keyword.

  • public static string Shadows()

    The one box-shadow that ring-* and shadow-* both emit.

  • public static string Filter()

    The filter declaration the eight filter families assemble into.

  • public static string BackdropFilter()

    The backdrop-filter declaration the ten backdrop families assemble into.

Used by (5)

  • CompositionTestsVixen.Ui.Styling.Utilities.Tests
  • UtilityConsumptionGateTestsVixen.Ui.Styling.Utilities.Tests
  • UtilityConsumptionProbeVixen.Ui.Styling.Utilities.Tests
  • UtilityFamiliesVixen.Ui.Styling.Utilities
  • UtilityFamilyTestsVixen.Ui.Styling.Utilities.Tests