Styling with static CSS extraction in mind #2560
NicholasBoll
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Intro
The
@workday/canvas-kit-styling-transformboth optimizes runtime and can optionally extract out CSS into files.@emotion/csscreateStylesandcreateStencilfunction calls and saved in.cssfiles based on values statically extractedLimitations
Styles have to be statically analyzed by the style transformer. The transform utilizes the TypeScript type checker for greater flexibility when compared to the static extraction process in Vanilla Extract. If the transform cannot statically analyze a style property, an error will be thrown.
For example:
General rule of thumb for if a property will be understood by the static style transform: if you mouse over the property value, it should be a numeric literal (i.e.
10) or a string literal (i.e.10px,1rem, etc). If the type is something likestringornumber, the value cannot be statically parsed. The exception to this rule is variables created bycreateVarsorvarsincreateStencil. The static style transformation will create a string literal for the variable names, cache that name, and apply statically during the transform.The biggest impact will be externalized style objects and functions that return style objects. For example, the following will result in an error:
For objects, the best way to fix to use
as conston the type instead of more general types likeCSSObjectorReact.CSSProperties.For functions, generics will have to be used:
If a function is more complex, consider using a custom transformation in your styling.config.ts function. For example,
focusRinghas a special transform function to use the runtimefocusRingfunction with statically analyzed values to produce a static result.Naming
Note: Naming is very important when authoring styles via
createStylesorcreateStencilwhen CSS is extracted into CSS files.The runtime optimization will still use CSS class names based on the hash to avoid collisions. This hash is the same hash created via
@emotion/css. However, CSS extraction needs a human readable name to apply for authoring. The name of the CSS variable or CSS class name is extracted from the variable name itself. This means we need to be conscious of what that name is.The naming algorithm goes something like this:
const Foo = createStyles({})will be "Foo"const Foo = { Bar: createStyles({}) }will be "Foo-Bar"slugifyon the name (dash-case): The above will becomefoo-barcss-foo-bar('css' is the default)--to the class name and dash-case the modifier name/value pair:For example,
const buttonStyles = createStyles({})will produce the name "css-button".createStylesorcreateStencil?Both functions produce static CSS. However,
createStencilshould be the preferred styling function. It better organizes styles and creates a cascade barrier for variables. A cascade barrier means if you declare a variable, it's default will be inlined into thebasestyles which prevents nested CSS classes that use the same variable from cascading.An example of CSS variable cascade:
CSS:
HTML:
Stencils prevent component variables from cascading by adding in the default declared in the
varsconfig:TypeScript
CSS
CSS variables are set by the rules of specificity. The
styleattribute has a higher specificity than the single class name. Remember this when doing CSS variable value overrides. Adding a psuedo-selector like&:hoveris a higher specificity than the single class name and will override the base variable declaration.Beta Was this translation helpful? Give feedback.
All reactions