6 · Component recipes
Lesson 6 of 8 — name a group of rules once in the config and reuse it everywhere, with variants.
The button from lesson 1 has twelve rules. You do not want to repeat them. A recipe gives them a name.
You will learn: defining recipes · extending one recipe from another · overriding per instance · applying a recipe at a breakpoint.
Define a recipe#
// nibcss.config.ts
export default defineConfig({
tokens: { /* from lesson 5 */ },
components: {
btn: "d=inline-flex; ali=center; jsc=center; g=8px; p=10px 18px; bd=none; bdrd=$radius.md; ftw=600; cur=pointer; ts=all .15s; focus-visible:otl=3px solid #A8ABF4; focus-visible:otlo=2px; disabled:opc=.5",
"btn-primary": "btn; bgc=$color.brand; cl=#fff; hover:bgc=$color.brand-hover",
"btn-outline": "btn; bgc=transparent; cl=$color.brand; bd=1px solid $color.border; hover:bgc=#EEEFFE",
},
});A recipe is written in exactly the same syntax as an attribute. A name with no = is a recipe reference,
so btn-primary includes everything in btn and adds its own colours.
Use it#
<div nib="d=flex; g=10px; flxw=wrap">
<button nib="btn-primary">Primary</button>
<button nib="btn-outline">Outline</button>
<button nib="btn-ghost">Ghost</button>
</div>Override per instance#
Rules after a recipe add to it, and a later rule for the same property wins:
<button nib="btn-primary; w=100%; mt=16px">Full-width primary</button>Recipes and modifiers#
A modifier before a recipe applies to every rule inside it:
<!-- The card styles only apply from 768px up -->
<article nib="md:card">…</article>One class per recipe#
However many rules a recipe contains, the element gets one class for it, so markup stays clean in DevTools.
When to make a recipe#
- The same group of rules appears in three or more places.
- It represents a concept designers name: button, card, badge, input.
- You want to change it everywhere at once.
Keep one-off layout on the element (mt=24px, gc=span 2) — recipes are for identity, not position.