True Encapsulation
In front-end development, styling relies on agreement.
- “We agree to use BEM.”
- “We agree not to use global selectors.”
- “We agree to pass props for theming.”
As long as everyone follows the rules, things work. When they don’t, styles leak, specificity escalates, and !important, ::ng-deep, or global overrides become inevitable.
Maple removes the need for agreement by moving selector logic into the class name itself. It supports full CSS selector syntax inline, transforming every element into a strictly self-contained unit of styling logic that requires zero external coordination.
Parent-state Selector: Inversion of Control
Usually, a parent controls a child: .card button { color: green }. This breaks encapsulation because the Card must know about the internal structure of the Button.
Maple uses the caret ^ to invert this relationship, allowing the child to define its own styles based on the ancestral context it lives in:
<button class="c-red ^.card:c-green ^.nav:c-blue">
Smart Button
</button>Because the element defines its own contextual behavior, it becomes a truly encapsulated, self-contained unit.
- No prop drilling: You don't need to pass a
<Button variant="card" />prop just to change its background. - Zero coupling: The parent component doesn't need to write CSS targeting its children.
- Total portability: You can drag and drop this button anywhere in your application, and it will adapt perfectly.
Self Selector: Complex State
Maple supports self selectors via &, allowing components to express complex, compound state logic directly on the element.
When you need to combine multiple states or target specific attribute combinations alongside parent context, the & references the current element within the selector string:
<button class="&:hover:c-black">
The text becomes black on hover
</button>
<button class="^.dark&:hover:c-white">
When in a parent having dark class,
the text becomes white on hover
</button>
Child Selector: Uncontrolled Markup
Often, you need to style HTML that you do not directly control—such as CMS-generated content, parsed Markdown, or third-party widget injections.
Maple allows you to apply inline child selectors using the forward slash /, effectively styling nested descendants without writing global CSS:
<div class="/>span:fw=700">
<span>This text is bold</span>
</div>
<article className="/p:mb-4 /a:c-primary /h1:fs-2xl">
{cmsContent}
</article>An element styled with Maple is a self-contained unit of styling logic that behaves identically across frameworks and environments.
Guideline: Component Boundaries
- To maintain a clean codebase, prefer using the Parent-state ^ and Self & selectors to let components style themselves.
- Reserve the Child / selector exclusively for boundaries where you cannot physically add classes to the HTML (like raw Markdown or CMS output). This ensures your components remain fully self-contained while giving you the flexibility to style external content.