ScopedCss class
A compiled scoped CSS stylesheet bundle providing deterministic class name isolation.
Generated via scopedCss or ScopedCss.compile. Parses author CSS and rewrites every
local class selector so that it is suffixed with a unique, deterministic hash derived
from the stylesheet source and an optional component name prefix (e.g. .card becomes
.card__a1b2c3d or .btn_card__a1b2c3d).
Determinism across SSR and Browser Backends
The scoping transformation is a pure function over strings with zero browser DOM or
Flutter dependencies. The exact same ScopedCss instance or identical input string
produces bit-for-bit identical class names, class maps, and CSS text on both the
server (SSR via renderToHtml) and the client (browser DOM mounting via mount),
guaranteeing zero hydration mismatch or style flashing.
Embedding node (or style) in a component tree injects a <style> element into the
DOM in the browser or emits <style>...</style> directly into the SSR HTML stream.
Selector Scoping Rules
- Scoped Local Classes: All local class selectors (
.title,.btn-primary,.item:hover,.nav > .item) are automatically rewritten with the scoped suffix. - Global Escape Hatch (
:global): Class selectors wrapped inside:global(...)(e.g.:global(.theme-dark) .cardor.button:global(.active)) are unwrapped and preserved verbatim without scoping. Use this to style against ambient theme classes, body attributes, or external third-party classes. - Preserved Selectors: Element/type selectors (
div,p,span,h1), ID selectors (#header,#app), root selectors (:root), and universal selectors (*) are deliberately left untouched. - Nested At-Rules: Rules inside
@media,@supports,@container, and@layerblocks are parsed and scoped recursively. - Keyframe Preservation: Animation stops (
from,to, and percentages like0%,50%,100%) inside@keyframesand@-webkit-keyframesblocks are intentionally not rewritten, preserving standard CSS animation definitions. - At-Rule Declarations: Declaration blocks inside
@font-face,@page, and@propertyare preserved verbatim without selector rewriting.
Pragmatic Parser Capabilities & Limitations
ScopedCss is a pragmatic, high-performance selector rewriter rather than a full CSS AST parser or CSS validator:
- It assumes structurally valid CSS with balanced delimiters (
{},(),[],"",'',/* */). - It does not validate CSS property names or values.
- Exotic selectors with unquoted commas inside pseudo-functions may not split cleanly.
final styles = scopedCss('''
.card {
padding: 16px;
background: #14141a;
border: 1px solid #27272a;
border-radius: 8px;
}
.card:hover {
border-color: #6366f1;
}
.title {
font-size: 18px;
font-weight: 600;
color: #ffffff;
}
:global(.theme-dark) .card {
background: #09090b;
}
''', name: 'card');
BloomNode cardWidget(String titleText) => Div(
className: styles['card'],
children: [
styles.node,
H1(className: styles['title'], text: titleText),
],
);
Constructors
Properties
-
classes
→ Map<
String, String> -
Lookup map from author class names (e.g.
'title') to generated scoped class names (e.g.'card_title__a1b2c3d').final - css → String
-
The transformed CSS stylesheet with all local class selectors scoped.
final
- hash → String
-
The deterministic 7-character hex hash derived from the CSS content and name.
final
- hashCode → int
-
The hash code for this object.
no setterinherited
- name → String?
-
The optional human-readable component name prefix (e.g.
'card','button').final - node → StyleNode
-
The StyleNode descriptor containing the transformed css, ready to drop into
a BloomNode tree.
final
- rawCss → String
-
The raw, un-scoped CSS source provided by the author.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- style → StyleNode
-
Alias for node for convenient stylesheet embedding.
no setter
Methods
-
call(
String className) → String -
Functional lookup shorthand — equivalent to
this[className]. -
cx(
List< Object?> parts) → String - Composes a class list resolving author class names to their scoped equivalents.
-
get(
String className) → String -
Looks up the generated scoped class name for author
className. -
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
-
operator [](
String className) → String -
Looks up the generated scoped class name for author
className.