CSS Fundamentals
CSS is the presentation layer of the web — it controls how every element looks and lays out. Most CSS frustration isn't about obscure properties; it's about three foundations: the box model, the cascade and specificity, and the layout modes (Flexbox and Grid).
Get those right and modern CSS is genuinely pleasant. Custom properties, clamp(), container queries, and logical properties have removed most of the old hacks — you rarely need floats or positioning tricks anymore.
TL;DR
- Set
box-sizing: border-boxglobally so width includes padding and border. - Understand specificity and avoid
!importantand deep selector nesting. - Use Flexbox for one-dimensional layout, Grid for two-dimensional.
- Use custom properties for theming and
clamp()/min()/max()for fluid sizing. - Animate
transform/opacity(cheap), not layout properties (expensive).
Quick Example
A responsive grid that fits as many ≥250px columns as the space allows — no media queries needed:
Core Concepts
The box model
Every element is content + padding + border + margin. Make sizing intuitive by including padding and border in declared widths:
The cascade & specificity
When rules conflict, the more specific selector wins. Specificity is ranked by (inline, IDs, classes/attributes/pseudo-classes, elements):
⚠️ Avoid
!important— it overrides the cascade and turns debugging into a specificity arms race. Fix the selector instead.
Selectors
Layout: Flexbox vs Grid
Modern CSS
Positioning, Transitions & Animation
Best Practices
- Global
border-box; design with the box model in mind. - Theme with custom properties instead of hard-coded values.
- Keep selectors shallow and class-based; let the cascade work for you.
- For animation, prefer
transformandopacity(compositor-only) over width/top/left (which trigger reflow). - Use
will-changesparingly and remove it after the animation.
Common Mistakes
Specificity wars
Animating layout properties
Other classics
- Margin collapse — adjacent vertical margins merge (the larger wins); padding/border on the parent prevents it.
- z-index only works on positioned elements, and is scoped to its stacking context.
- Float clearing — clear floated children with a clearfix or, better, switch to Flexbox/Grid.
FAQ
When should I use Flexbox vs Grid?
Use Flexbox for one-dimensional layouts — a row or column of items that should distribute or align (navbars, button groups). Use Grid for two-dimensional layouts where you control both rows and columns (page scaffolding, card galleries). They compose well together.
How does CSS specificity work?
The browser scores each selector by inline styles, then IDs, then classes/attributes/pseudo-classes, then elements. The highest score wins; ties go to the rule declared last. Keep specificity low and flat so overrides stay predictable.
Why isn't my z-index working?
z-index only applies to positioned elements (position other than static) and is scoped to its stacking context. If a parent creates a new stacking context (via transform, opacity, etc.), a child's high z-index can't escape it.
Should I use px, em, or rem?
Use rem for font sizes and spacing so everything scales with the user's root font size (better accessibility). Use px for borders and tiny fixed details, and em when you want sizing relative to the element's own font size.
Container queries or media queries?
Media queries respond to the viewport; container queries respond to a component's parent width. Use container queries for reusable components placed in different-sized contexts, and media queries for overall page structure.
Related Topics
- Tailwind CSS — Utility-first styling
- Sass/SCSS — CSS with variables and nesting
- Responsive Design — Adapting across screens
- Web Performance — Cheap vs expensive style changes
- HTML Fundamentals — The markup CSS styles