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
-
Intro
The
@workday/canvas-kit-styling-transform
both optimizes runtime and can optionally extract out CSS into files.@emotion/css
createStyles
andcreateStencil
function calls and saved in.css
files 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 likestring
ornumber
, the value cannot be statically parsed. The exception to this rule is variables created bycreateVars
orvars
increateStencil
. 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 const
on the type instead of more general types likeCSSObject
orReact.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,
focusRing
has a special transform function to use the runtimefocusRing
function with statically analyzed values to produce a static result.Naming
Note: Naming is very important when authoring styles via
createStyles
orcreateStencil
when 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"slugify
on the name (dash-case): The above will becomefoo-bar
css-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".createStyles
orcreateStencil
?Both functions produce static CSS. However,
createStencil
should 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 thebase
styles 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
vars
config:TypeScript
CSS
CSS variables are set by the rules of specificity. The
style
attribute has a higher specificity than the single class name. Remember this when doing CSS variable value overrides. Adding a psuedo-selector like&:hover
is a higher specificity than the single class name and will override the base variable declaration.Beta Was this translation helpful? Give feedback.
All reactions