Ad – 728×90
💼 Interview Prep

CSS Interview Questions – Top 30 with Expert Answers

These are the CSS questions you will actually face in front-end developer interviews — at companies ranging from startups to FAANG. Each question includes a thorough answer and, where relevant, code examples. Work through these before any interview that involves front-end development, and make sure you can explain each concept out loud, not just recall it.

⏱️ 35 min read 🎯 Intermediate 📅 Updated 2026

Fundamentals

1 What is the CSS box model? Explain each component.

Every HTML element is rendered as a rectangular box. The box model describes the four layers that make up that box, from inside out:

  • Content — the area where text and images appear. Sized by width and height.
  • Padding — transparent space between the content and the border. Increases the element's visual size.
  • Border — a line around the padding. Has width, style, and color.
  • Margin — transparent space outside the border. Pushes other elements away.
CSS
/* box-sizing: content-box (default) — width/height applies to content only */
.box { width: 200px; padding: 20px; border: 2px solid; }
/* total rendered width: 200 + 20+20 + 2+2 = 244px */

/* box-sizing: border-box — width/height includes padding AND border */
.box { box-sizing: border-box; width: 200px; padding: 20px; border: 2px solid; }
/* total rendered width: 200px exactly */

Always use *, *::before, *::after { box-sizing: border-box; } as a global reset — it makes sizing predictable.

2 What is CSS specificity and how is it calculated?

Specificity is the browser's algorithm for deciding which CSS rule wins when multiple rules target the same property. It's expressed as a three-column score (a, b, c):

  • a — count of ID selectors (#id)
  • b — count of class selectors (.class), attribute selectors ([attr]), pseudo-classes (:hover)
  • c — count of element selectors (div, p) and pseudo-elements (::before)

Inline styles beat all selector specificity. !important overrides inline styles. When scores are equal, the last rule in source order wins (the cascade).

CSS
p             /* (0,0,1) */
.intro        /* (0,1,0) */
#header       /* (1,0,0) */
#header .nav li a:hover  /* (1,1,2) */
3 What is the difference between display: none, visibility: hidden, and opacity: 0?
PropertySpace in layoutClickableScreen reader
display: noneRemovedNoHidden
visibility: hiddenPreservedNoHidden
opacity: 0PreservedYesVisible
4 Explain the difference between position: relative, absolute, fixed, and sticky.
  • relative — element stays in normal flow; top/left/right/bottom offsets it visually from its normal position. Creates a positioning context for absolutely positioned children.
  • absolute — removed from normal flow; positioned relative to the nearest positioned ancestor (or <html> if none). Overlaps other elements.
  • fixed — removed from normal flow; positioned relative to the viewport. Stays in place during scrolling (sticky headers, modals).
  • sticky — hybrid: acts like relative until it reaches a scroll threshold, then acts like fixed. Common for sticky table headers and navigation bars.
Ad – 336×280

Layout

5 When would you use CSS Flexbox vs CSS Grid?

Flexbox is one-dimensional — it lays items out in a single row or column. Best for: navigation bars, button groups, aligning items within a component, any linear sequence of items.

Grid is two-dimensional — it manages rows AND columns simultaneously. Best for: page-level layouts, image galleries, card grids, any component where items need to align across both axes.

Rule of thumb: if you're thinking in one direction (row or column), use Flexbox. If you're thinking in both directions at once, use Grid. They work great together — a Grid for overall layout, Flexbox inside each Grid cell for component-level alignment.

6 How do you center an element both horizontally and vertically in CSS?
CSS – Centering methods
/* Method 1: Flexbox (most common) */
.parent {
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Method 2: CSS Grid */
.parent {
  display: grid;
  place-items: center;   /* shorthand for align-items + justify-items */
}

/* Method 3: Absolute + transform (works without known dimensions) */
.child {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
}

/* Method 4: Absolute + inset + auto margins */
.child {
  position: absolute;
  inset: 0;
  margin: auto;
  width: fit-content;
  height: fit-content;
}
7 What is the difference between em, rem, vw/vh, and px?
  • px — absolute pixels. Does not respect user's browser font-size preference.
  • em — relative to the element's own font-size. Compounds through nesting (a nested element with 1.2em inside another 1.2em element = 1.44em at root).
  • rem — relative to the root element's (:root / <html>) font-size. No compounding. Use for typography to respect user preferences.
  • vw / vh — 1% of viewport width / height. Use for full-screen sections, large hero elements.
  • % — relative to the parent's value for the same property.

Best practice: use rem for font sizes, padding, margins; px for borders and fine details; vw/vh for viewport-relative sizes; em for component-internal spacing that should scale with the component's font size.

8 What is CSS z-index and what is a stacking context?

z-index controls the stacking order of elements on the Z axis (front to back). Higher values appear in front. It only works on positioned elements (relative, absolute, fixed, sticky).

A stacking context is an isolated layer in the stacking order. Elements inside a stacking context are stacked relative to each other within that context — they cannot overlap elements outside it regardless of their z-index. A new stacking context is created by: position + z-index ≠ auto, opacity < 1, transform, filter, will-change, and several other properties.

Responsive Design

9 What is mobile-first CSS design and why is it preferred?

Mobile-first means writing the base CSS for small screens, then using min-width media queries to add styles for larger screens. Contrast with desktop-first, which writes for large screens and overrides with max-width queries.

Mobile-first is preferred because: (1) it forces you to prioritize core content and functionality, (2) the CSS base is smaller and faster on mobile devices which typically have slower connections and processors, (3) it's easier to add complexity than to subtract it, and (4) Google's indexing is mobile-first.

10 What is the difference between min-width and max-width in media queries?
CSS
/* min-width — applies when viewport IS AT LEAST this wide (mobile-first) */
@media (min-width: 768px) { /* tablet and above */ }
@media (min-width: 1024px) { /* desktop and above */ }

/* max-width — applies when viewport IS AT MOST this wide (desktop-first) */
@media (max-width: 767px) { /* tablet and below */ }
@media (max-width: 480px) { /* mobile only */ }

Effects & Performance

11 Why should you use transform instead of top/left for animations?

Changing top or left triggers layout reflow — the browser must recalculate the position of every element affected. This is the most expensive rendering operation and causes jank (stuttering) at even 100ms intervals.

Changing transform (and opacity) only triggers the compositor — a separate GPU thread. The browser skips layout and paint entirely. The result is consistently smooth 60fps animation even on mobile. Always animate transform: translateX/Y instead of left/top.

12 What is will-change in CSS and when should you use it?

will-change: transform tells the browser that this element will be animated soon — allowing the browser to create a separate compositor layer in advance, preventing janky first-frame rendering. Use it only on elements you know will animate (modals about to open, elements with hover transitions). Overusing it consumes significant GPU memory and can degrade overall performance.

13 What is the difference between CSS transitions and CSS animations?
  • Transitions — animate a property from one state to another, triggered by a state change (hover, focus, class toggle). Simple A → B. Defined with a transition property on the element.
  • Animations — multi-step, looping, or self-starting. Defined with @keyframes and applied with animation property. Don't require user interaction to start.
Ad – 336×280

Advanced Topics

14 What are CSS custom properties (variables) and how are they different from Sass variables?

CSS custom properties are declared with --name: value and read with var(--name). They are runtime variables — the browser keeps them live and they can be changed with JavaScript, media queries, or by overriding in a nested scope.

Sass variables are compile-time — they are resolved during the build step and replaced with their values in the output CSS. They are more like constants. CSS variables also cascade and inherit; Sass variables do not.

15 What is BEM and why is it useful?

BEM (Block–Element–Modifier) is a CSS naming convention: .block__element--modifier. Block is the standalone component (.card), Element is a part of it (.card__title), Modifier is a variation (.card--featured). BEM is useful because it keeps all selectors at a single-class level (zero specificity wars), makes the relationship between CSS and HTML explicit, and prevents name collisions between components.

16 What does box-sizing: border-box do and why is it commonly applied globally?

By default (content-box), width applies only to the content area — padding and border are added on top, making the total rendered size larger than specified. With border-box, width includes the padding and border, so width: 200px is always exactly 200px rendered regardless of padding. Applied globally as *, *::before, *::after { box-sizing: border-box; } it makes sizing predictable everywhere.

17 What is the difference between :nth-child() and :nth-of-type()?

:nth-child(n) counts all siblings regardless of type, then checks if the counted element matches the selector. :nth-of-type(n) counts only siblings of the same element type. If a <div> contains <h2>, <p>, <p>: p:nth-child(2) matches the first <p> (it's the 2nd child); p:nth-of-type(2) matches the second <p>.

18 What is a CSS pseudo-element? Name five and give a use case for each.
  • ::before — decorative icons, quote marks, badges — content inserted before the element.
  • ::after — clearfix hack, tooltip arrows, ribbon corners.
  • ::first-letter — magazine-style drop cap on the first paragraph letter.
  • ::placeholder — style input placeholder text color and font.
  • ::selection — change the highlight color when a user selects text.
19 What is the CSS cascade and what are its layers?

The cascade is the algorithm that determines which CSS declaration wins when multiple rules target the same property. Priority order (highest wins): user !important → author !important → author inline styles → author stylesheet rules (by specificity, then source order) → user stylesheet → browser defaults.

Modern CSS adds @layer — named cascade layers where later-declared layers always win over earlier ones regardless of specificity, giving developers explicit control over override order without fighting specificity.

20 What is the difference between min-content, max-content, and fit-content?
  • min-content — the smallest size that avoids overflow. For text, it's the width of the longest word.
  • max-content — the ideal unconstrained size. For text, no wrapping — all on one line.
  • fit-content — uses max-content up to the available space, then wraps. Like min(max-content, available-width).

Bonus Questions

21 How would you implement a dark mode toggle with CSS only (no JavaScript)?
CSS
/* Automatic dark mode based on user OS preference */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #121212;
    --text: #f1f1f1;
    --primary: #4fc3f7;
  }
}

/* CSS-only toggle using a hidden checkbox */
#dark-toggle:checked ~ body { /* or ~ .app */
  background: #121212;
  color: #f1f1f1;
}
22 What is the purpose of @keyframes in CSS? Write a simple spinning loader.
CSS
@keyframes spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

.loader {
  width: 40px;
  height: 40px;
  border: 4px solid #e0e0e0;
  border-top-color: #1572B6;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
23 What does contain: layout do and when is it useful?

contain: layout tells the browser that layout changes inside this element don't affect elements outside it. This allows the browser to skip recalculating the rest of the page's layout when a contained element changes, which can significantly improve performance for dynamic widgets, infinite scroll lists, and frequently updating components.

24 What is aspect-ratio in CSS and how do you use it?
CSS
/* Maintains a 16:9 ratio as width changes */
.video-wrapper { aspect-ratio: 16 / 9; width: 100%; }

/* Square avatars */
.avatar { width: 48px; aspect-ratio: 1; border-radius: 50%; }

/* Old technique (before aspect-ratio) — padding hack */
/* No longer needed in modern CSS */
25 How does CSS Grid's fr unit work?

fr (fractional unit) represents a fraction of the available space in the grid container after fixed and min-content tracks are sized. grid-template-columns: 1fr 2fr 1fr gives the middle column twice the space of each side column. 1fr is equivalent to minmax(0, 1fr) — the track can shrink to zero. Extremely useful for responsive layouts that distribute remaining space proportionally.

26 What is clamp() in CSS?

clamp(min, preferred, max) clamps a value between a minimum and maximum. font-size: clamp(1rem, 2.5vw, 2rem) sets a font size that grows with the viewport but never goes below 1rem or above 2rem. Eliminates many media query breakpoints for typography and spacing by making values naturally fluid.

27 What is the ::before pseudo-element and what property is required for it to render?

::before inserts a virtual node as the first child of the element. The content property is required — without it, the pseudo-element box is not generated. Use content: "" for decorative shapes. The inserted node is inline by default; change with display: block or position: absolute as needed.

28 How would you make a CSS-only tooltip?
CSS
[data-tooltip] { position: relative; }
[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  bottom: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  background: #333;
  color: #fff;
  padding: 4px 10px;
  border-radius: 4px;
  white-space: nowrap;
  font-size: 0.8rem;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s;
}
[data-tooltip]:hover::after { opacity: 1; }
29 What is the :focus-visible pseudo-class and why should you use it instead of removing focus outlines?

:focus-visible applies only when the browser determines the element was focused by keyboard navigation (Tab key), not by mouse click. This lets you show clear focus rings for keyboard users (critical for accessibility — WCAG 2.1 requires visible focus indicators) while not showing the ring when a mouse user clicks a button. Never use * { outline: none } — it makes your site inaccessible to keyboard users.

30 What is @layer in CSS and what problem does it solve?

@layer (CSS Cascade Layers) groups CSS declarations into named layers with an explicit priority order. Later-declared layers win over earlier ones regardless of specificity. This solves the problem of integrating third-party CSS (resets, component libraries): put them in low-priority layers so your application styles always win without needing !important. Example: @layer reset, base, components, utilities; — utilities always wins, reset always loses, all without specificity battles.