Skip to content
Laviyx Learn

Try

CSS course menu

Advanced CSS Interview Questions and Answers

Advanced CSS interview questions with answers: the full cascade and cascade layers, block formatting contexts, containing blocks, rendering performance (layout, paint, composite), container queries, :has(), CSS-in-JS vs utility CSS, critical CSS, and accessibility in CSS.

Advanced5 min readUpdated
On this page

Advanced questions explore how browsers apply CSS, how to keep large codebases maintainable, and how CSS affects performance and accessibility.

1. Describe the full order of the cascade.#

Show solution

For competing declarations, the browser compares, in order:

  1. Origin and importance: normal user-agent styles, then user styles, then author (your) styles; for !important the order reverses, so important user styles beat important author styles.
  2. Context: for Shadow DOM, styles from the outer context versus inside the component.
  3. Element-attached styles: inline style attributes beat selector-based rules.
  4. Cascade layers: later @layers win; unlayered styles beat layered ones (reversed for !important).
  5. Specificity.
  6. Order of appearance: the last declaration wins.

2. What is a block formatting context (BFC) and how do you create one?#

Show solution

A BFC is a region where block boxes are laid out independently of the outside. Inside it, floats are contained, and margins of its children do not collapse through it. It is created by the root element, floats, absolutely positioned elements, display: flow-root, inline-block, flex and grid items, and overflow values other than visible or clip. display: flow-root is the clean way to create one on purpose.

3. What is the containing block, and how is it determined?#

Show solution

The containing block is the rectangle that percentages and offsets are resolved against. For static and relative elements it is the content box of the nearest block ancestor. For position: absolute it is the padding box of the nearest ancestor whose position is not static. For position: fixed it is the viewport, unless an ancestor has a transform, filter, perspective, backdrop-filter or certain contain / will-change values, in which case that ancestor becomes the containing block.

4. Explain layout, paint and composite, and which properties are cheapest to animate.#

Show solution

After styles are calculated, the browser runs layout (geometry of boxes), paint (filling pixels) and composite (combining layers). Changing geometry (width, top, margin, font-size) triggers layout, then paint and composite. Changing color or background triggers paint and composite. Changing transform and opacity can often be handled by the compositor alone, so they are the cheapest to animate. Reading layout values in JavaScript right after changing styles forces synchronous layout ("layout thrashing").

5. What are cascade layers and what problem do they solve?#

Show solution

@layer groups styles into named layers whose order is declared once, for example @layer reset, base, components, utilities;. A later layer wins over an earlier one regardless of selector specificity, and unlayered styles win over all layers. This removes specificity wars between parts of a codebase and makes third-party CSS easy to keep below your own styles.

6. When do container queries beat media queries?#

Show solution

Media queries respond to the viewport; container queries respond to the size of an ancestor declared with container-type: inline-size. Reusable components (cards, widgets) placed in containers of different widths on the same screen can then adapt to their actual space. Media queries remain right for page-level layout and user preferences such as prefers-color-scheme.

7. What can :has() do that was impossible before?#

Show solution

:has() selects an element based on its descendants or following siblings, effectively a parent selector: .card:has(img), label:has(input:checked), form:has(:user-invalid) .submit, h2:has(+ p). Styling based on child state used to require JavaScript. Overly broad :has() selectors on large DOMs can cost performance, so keep them targeted.

8. Compare CSS Modules, CSS-in-JS and utility-first CSS.#

Show solution
  • CSS Modules scope class names at build time; you write normal CSS files with no runtime cost.
  • CSS-in-JS libraries write styles in JavaScript next to components; dynamic styling is easy, but runtime solutions add JavaScript work, so many teams prefer zero-runtime variants.
  • Utility-first (Tailwind) composes small classes in markup; no naming, tiny generated CSS, but busy HTML.

All solve global-scope conflicts; the choice depends on the framework, team and performance needs.

9. What is critical CSS?#

Show solution

The minimal CSS needed to render the above-the-fold content, inlined in the <head> so the first paint does not wait for the full stylesheet, which then loads without blocking. It improves First Contentful Paint and Largest Contentful Paint, at the cost of build complexity, since inlined CSS is not cached separately.

10. How does CSS affect accessibility?#

Show solution
  • Never remove focus outlines without a visible replacement; use :focus-visible.
  • Ensure colour contrast (4.5:1 for normal text) and do not convey meaning by colour alone.
  • Respect prefers-reduced-motion, and support zoom and text resizing with relative units.
  • Keep visual order consistent with DOM order; order, grid-area placement and flex-direction: row-reverse change only visual order.
  • Hide content correctly: display: none hides from everyone, a visually-hidden class hides only visually.
  • Check Windows forced-colors mode, where background images and box-shadows may disappear.

11. What is the difference between :is() and :where()?#

Show solution

Both accept a selector list and match if any selector matches. :is() takes the specificity of its most specific argument; :where() always has zero specificity. Use :where() for library defaults and resets so they are easy to override.

12. How would you build a theme system that supports light, dark and the user's system preference?#

Show solution

Define colour tokens as custom properties on :root, override them in @media (prefers-color-scheme: dark), and add explicit [data-theme="light"] and [data-theme="dark"] overrides for a manual toggle. Set color-scheme so built-in controls match (or use light-dark()). Store the user's choice and apply it with a tiny inline script in the head before first paint to avoid a flash of the wrong theme.

Keep going#

Browse every question with hints on the CSS interview page, then continue with the JavaScript course.

Finished this lesson?