CSS & Styling
CSS fundamentals for front-end work — the box model, spacing with gap, selector specificity, CSS-in-JS, and design tokens.
5 questions
JuniorTheoryVery commonWhat is the CSS box model, and what does box-sizing change?
What is the CSS box model, and what does box-sizing change?
Every element has four box layers: content, padding, border, and margin (inside out). By default (box-sizing: content-box), width/height size only the content, so padding and border add to the total. With box-sizing: border-box, width includes all three, keeping the box at its declared size.
Common mistakes
- ✗Forgetting that padding and border add to width under content-box
- ✗Thinking border-box is the browser default (it is content-box)
- ✗Confusing margin (outside spacing) with padding (inside spacing)
Follow-up questions
- →Why do vertical margins between block elements sometimes collapse?
- →Why do many CSS resets set
box-sizing: border-boxon everything?
JuniorTheoryCommonHow do you space flex items, and why prefer gap over margins?
How do you space flex items, and why prefer gap over margins?
Use gap (or row-gap/column-gap) on the flex container — supported for flexbox in all major browsers since ~2020. Unlike margins, gap puts space only between items, never at container edges, eliminating last-child hacks and margin-collapse surprises. Spacing is declared once on the parent instead of per child.
Common mistakes
- ✗Believing
gapworks only in Grid, not flexbox - ✗Thinking
gapadds space against the container edges too - ✗Adding per-item margins and then hacking the last child
Follow-up questions
- →How do
row-gapandcolumn-gaprelate to the shorthandgap? - →What spacing techniques did developers use before flexbox
gapexisted?
MiddleTheoryCommonHow is CSS selector specificity calculated, and what wins on a tie?
How is CSS selector specificity calculated, and what wins on a tie?
Specificity is a tuple: inline styles, IDs, classes/attributes/pseudo-classes, elements/pseudo-elements (left-to-right comparison). Higher tuple wins. On a tie, the last rule wins (source order). Universal selector and combinators add nothing. !important overrides the cascade; inline styles outrank selectors.
Common mistakes
- ✗Treating specificity as one flat number instead of a tuple
- ✗Thinking attribute selectors weigh less than classes (they are equal)
- ✗Believing source order beats a higher-specificity selector
Follow-up questions
- →Where do
:where()and:is()fit in the specificity calculation? - →Why is overusing
!importantconsidered a code smell?
MiddleTheoryOccasionalWhat are design tokens, and how do they differ from plain variables?
What are design tokens, and how do they differ from plain variables?
Design tokens are named, platform-agnostic design decisions — color, spacing, typography, radii — held as semantic single source of truth (e.g. color.brand.primary). Often layered (primitive → semantic → component) and exported to many platforms (web, iOS, Android). A plain CSS variable is just a value alias in one tech; a token carries design intent, is platform-independent, and governed by the design system.
Common mistakes
- ✗Equating a token with a raw CSS variable, ignoring the semantic layer
- ✗Thinking tokens are browser-only rather than platform-agnostic
- ✗Missing the primitive→semantic→component layering of token sets
Follow-up questions
- →Why layer tokens as primitive, semantic, and component levels?
- →How does a tool like Style Dictionary export one token set to many platforms?
MiddleTheoryOccasionalWhat are the pros and cons of the CSS-in-JS library styled-components?
What are the pros and cons of the CSS-in-JS library styled-components?
Pros: styles are component-scoped (no global leakage), dynamic from props, colocated with code, and support theming. Cons: runtime cost (styles injected and recomputed at render), larger bundle, SSR/hydration complexity, and weaker caching than static CSS. Modern trend is toward zero-runtime CSS-in-JS (vanilla-extract, Linaria) or utility CSS.
Common mistakes
- ✗Assuming styled-components has no runtime or bundle cost
- ✗Thinking its styles are global rather than component-scoped
- ✗Ignoring the SSR/hydration complexity it introduces
Follow-up questions
- →How does zero-runtime CSS-in-JS like vanilla-extract avoid the runtime cost?
- →Why can runtime CSS-in-JS hurt server-side rendering performance?