Skip to content
Chapter 19Lesson 5

Quiz - The cascade, inheritance, and design tokens

Quiz progress

0 / 0

A custom .btn lives at the top level of globals.css (no @layer), and a component renders <button className="btn bg-primary">. The button paints the .btn background, and the caller’s bg-primary is ignored. Both rules are plain CSS, neither uses !important. What does an experienced engineer do first?

Wrap the .btn rule in @layer components. Unlayered CSS is treated as sitting above every Tailwind layer — including utilities, where bg-primary lives — so it wins the layer gate by accident of position. Moving it into a layer drops it below utilities and the utility wins cleanly, no !important and no specificity change.

Rewrite the selector as #app .btn so it outweighs the single-class utility on specificity and the override lands.

Put bg-primary last in the className string so it’s emitted later and wins on source order.

Score the specificity of each selector as the tuple (inline, ID, class/attr/pseudo-class, element/pseudo-element).

a:hover /* selector A */
:where(.dark) .btn /* selector B */

A is (0, 0, 1, 1) and B is (0, 0, 1, 0). A :hover pseudo-class counts in the class slot (one class, one element), and everything inside :where() scores zero — so only the trailing .btn counts in B.

A is (0, 0, 0, 2) and B is (0, 0, 2, 0). a:hover is two element-level pieces, and :where(.dark) .btn is two classes.

A is (0, 0, 1, 1) and B is (0, 0, 2, 0). :hover lands in the class slot, and both .dark and .btn count as classes in B.

Your <body className="font-sans text-foreground"> styles every paragraph below it, but a bare <button> inside renders in the browser’s default font and color. There’s no Preflight yet. Why does the button opt out — and what’s the actual fix?

The browser’s user-agent stylesheet declares font-family and color directly on form controls. An inherited value is the weakest source in the cascade — the mere absence of a declaration — so any real declaration on the element beats it. The fix is Preflight’s button, input, select, textarea { font: inherit; color: inherit }, which re-opens the controls to inheritance.

color and font-family don’t actually inherit, so the body’s values were never candidates for the button. You set them per element with a utility on the button itself.

The button is too deep in the DOM tree for inheritance to reach it; inheritance only flows one level down. Forwarding the font through a wrapper component fixes it.

A few effects look like inheritance but aren’t. Which of these statements are correct? Select all that apply.

opacity: 0.5 on a parent fades the whole subtree, but opacity does not inherit — the subtree flattens into one composited group that’s made translucent as a whole, which is why a child can’t set opacity: 1 to become solid again.

A child with no background shows its parent’s color because background-color defaults to transparent and the child is see-through — not because background inherits.

Nesting elements that each set font-size: 1.25em makes the text compound and run away, because em is relative to the parent’s computed font-size — rem avoids this by being relative to the root.

visibility: hidden doesn’t inherit, which is why a child can never reappear inside a hidden parent.

You’re staring at a fresh Tailwind app with nothing painted yet. Which symptoms are Preflight doing its job — flattened on purpose, fixed by adding a utility — rather than an actual bug? Select all that apply.

Your <h1> renders at the exact size and weight of the paragraph beneath it.

Your <select> shed its chunky native OS look and now reads in your body font.

You stripped the @import "tailwindcss" line out of your CSS to tidy up, and now a border utility draws no line at all.

A heading is the wrong size, and DevTools shows the class text-2xI (capital I) never matched anything.

Your app renders a blob of Markdown-generated HTML — <h2>, <p>, <ul>, <blockquote> — and it all comes out flattened: no heading sizes, no bullets. You want real typographic defaults back, but only here. What does an experienced engineer reach for?

Wrap the content in the prose class from @tailwindcss/typography. It’s a scoped, tokenized typographic system for exactly the subtree whose elements you can’t reach one by one — not an undoing of Preflight.

Strip Preflight globally so the browser’s heading sizes and list bullets come back across the whole app.

Add a global h2, ul { … } rule in globals.css to restore the defaults Preflight removed.

In a color picker, onInput fires on every drag and runs document.documentElement.style.setProperty('--color-brand', value). The page repaints instantly and every bg-brand follows — but a sibling component that reads brand from React state doesn’t update until release. Why?

setProperty writes through the cascade and repaints pixels, but React never finds out — there’s no re-render. The custom property is a one-way visual output; a component that needs the value must also have it in React state, which is what the onChange-on-release handler commits.

setProperty is asynchronous and batches its writes, so the sibling does get notified but only after the browser flushes the queue on pointer release.

Writing on document.documentElement scopes the change to <html> only, so a component mounted deeper in the tree can’t see the new value until a full re-render rebroadcasts it.

A component needs the primary action color. The chapter’s three-tier model (primitive → semantic → component) says one of these is the senior choice and the other is a code smell. Which, and why?

Use bg-primary (semantic), never bg-blue-600 (primitive). Components read the semantic tier so a rebrand re-points one semantic-to-primitive binding in a single place and the whole app follows — hard-coding the primitive turns a rebrand into a never-quite-complete find-and-replace.

Use bg-blue-600 (primitive) directly — it’s one fewer layer of indirection, so it resolves faster and is easier to read than chasing a semantic token through to its value.

Either is fine; the tiers are an organizational convention with no runtime or maintenance consequence, so pick whichever reads more clearly in context.

Quiz complete

Score by topic