Home Module 17 CSS Interview Questions

Box Model & Layout Fundamentals

1. Explain the CSS box model.

Every HTML element is a rectangular box consisting of four layers from inside to outside: content (the text/image), padding (space between content and border), border (the line around the padding), and margin (space outside the border). The total rendered size of an element depends on the box-sizing property.

2. What is the difference between box-sizing: content-box and box-sizing: border-box?

With content-box (the default), width and height apply to the content area only — padding and border add to the final size. With border-box, width and height include padding and border — the element never grows larger than the declared size. Most modern projects set *, *::before, *::after { box-sizing: border-box; } globally for predictable sizing.

3. What is the difference between margin and padding?

Padding is space inside the element, between the content and the border. It is part of the element's background. Margin is space outside the element, between its border and surrounding elements. Margins can collapse (two adjacent vertical margins become one); padding never collapses.

4. What is margin collapsing?

Vertical margins between adjacent block elements collapse into a single margin equal to the larger of the two values. For example, if element A has margin-bottom: 30px and element B below it has margin-top: 20px, the actual gap between them is 30px, not 50px. Margin collapsing only applies to vertical margins; horizontal margins never collapse.

5. What is the difference between display: none and visibility: hidden?

display: none removes the element from the document flow — it takes up no space, as if it does not exist. visibility: hidden makes the element invisible but it still occupies its original space in the layout. A third option, opacity: 0, also keeps the space but the element remains interactive (clickable), which is usually undesirable.

Selectors & Specificity

6. How does CSS specificity work?

When multiple rules target the same element, the most specific one wins. Specificity is calculated as a three-part value (A, B, C):

  • A — inline styles (highest: 1,0,0)
  • B — IDs: each adds (0,1,0)
  • C — classes, attributes, pseudo-classes: each adds (0,0,1)
  • Elements and pseudo-elements: each adds (0,0,1) (wait, actually 0,0,1 is for type selectors — clarify)

More precisely: inline = (1,0,0,0), ID = (0,1,0,0), class/attribute/pseudo-class = (0,0,1,0), element/pseudo-element = (0,0,0,1). !important overrides all of this but should be used sparingly.

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

:nth-child(n) selects an element that is the nth child of its parent, regardless of type. :nth-of-type(n) selects the nth element of a specific type. They differ when sibling elements are of mixed types: p:nth-child(2) selects the <p> only if it is the second child; p:nth-of-type(2) selects the second <p> regardless of its position among siblings.

8. What are CSS combinators?

Combinators define the relationship between selectors:

  • A B — descendant: B anywhere inside A
  • A > B — child: B that is a direct child of A
  • A + B — adjacent sibling: B immediately after A
  • A ~ B — general sibling: any B after A with the same parent

9. What is the difference between ::before and :before?

Both work, but ::before (double colon) is the CSS3 standard syntax for pseudo-elements, distinguishing them from pseudo-classes (single colon like :hover). The single-colon :before was the CSS2 syntax — it still works in all browsers for backwards compatibility, but ::before is the correct modern form.

Positioning & Display

10. Explain the CSS position property values.

  • static — default. Element is in normal document flow. top/left/bottom/right have no effect.
  • relative — positioned relative to its normal position. The original space is still occupied.
  • absolute — removed from normal flow. Positioned relative to the nearest ancestor with position other than static.
  • fixed — removed from flow. Positioned relative to the viewport. Does not scroll.
  • sticky — behaves like relative until a scroll threshold, then sticks like fixed.

11. What does z-index do and when does it work?

z-index controls the stacking order of overlapping positioned elements — higher values appear on top. It only works on elements with a position value other than static (and flex/grid children). z-index also creates a new stacking context, which isolates child elements' z-indexes from the rest of the page.

12. What is a stacking context?

A stacking context is a self-contained group of elements that are painted together as a unit, in z-order relative to each other. A new stacking context is created by: position + any z-index other than auto, opacity < 1, transform, filter, and several others. Elements in a child stacking context cannot appear between elements in a parent stacking context, regardless of their z-index values.

Flexbox & Grid

13. What is the difference between Flexbox and CSS Grid?

Flexbox is one-dimensional — it distributes items along a single axis (row or column). It is ideal for navigation bars, button groups, card rows, and centring. CSS Grid is two-dimensional — it controls rows and columns simultaneously. It is ideal for page layouts, image galleries, and dashboards. They work well together: Grid for the macro layout, Flexbox for components within that layout.

14. How does flex: 1 work?

flex: 1 is shorthand for flex-grow: 1; flex-shrink: 1; flex-basis: 0%. It tells the item to grow to fill available space. When multiple items have flex: 1, they share the available space equally. flex: 2 on one item and flex: 1 on another means the first gets twice the space.

15. What does align-items vs align-content do in Flexbox?

align-items controls how items are aligned along the cross axis within each row. align-content controls how rows themselves are distributed along the cross axis — it only has effect when flex-wrap: wrap and there are multiple rows. For a single-row flex container, only align-items matters.

16. What is grid-template-areas?

grid-template-areas assigns names to grid areas and then places items by name — making complex layouts very readable:

.layout {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar main"
    "footer footer";
}
header  { grid-area: header; }
.sidebar { grid-area: sidebar; }
main    { grid-area: main; }
footer  { grid-area: footer; }

Responsive Design

17. What is the difference between em, rem, px, and vw?

  • px — absolute unit. 1px on screen (not physical pixel on high-DPI screens).
  • em — relative to the element's own font size (or inherited font size for some properties). Compounds when nested.
  • rem — relative to the root element (<html>) font size. Does not compound. The preferred unit for font sizes.
  • vw/vh — 1% of the viewport width/height. Useful for full-screen sections.
  • % — relative to the parent element's corresponding property.

18. What is a media query and how does it work?

A media query applies CSS rules only when certain conditions are true (e.g. viewport width, orientation, colour depth). The most common form:

@media (max-width: 768px) {
  .sidebar { display: none; }
}
/* Or mobile-first: */
@media (min-width: 768px) {
  .sidebar { display: block; }
}

Mobile-first (using min-width) is the recommended approach — start with styles for small screens, then progressively enhance for larger ones.

19. What is the difference between mobile-first and desktop-first responsive design?

Mobile-first: write base styles for mobile, then use min-width media queries to add complexity at wider breakpoints. Desktop-first: write styles for desktop, then use max-width media queries to simplify at narrower breakpoints. Mobile-first is recommended because it forces you to prioritise the most constrained layout first, resulting in leaner base CSS. It also aligns with how CSS performance works — mobile devices load less CSS if media queries use min-width.

Advanced CSS

20. What are CSS custom properties (variables)?

CSS variables store values that can be reused throughout a stylesheet. They are declared with --variable-name: value; and accessed with var(--variable-name). Unlike Sass variables, CSS custom properties are live — they update in the browser and can be changed via JavaScript. They cascade and inherit like other properties.

:root {
  --color-primary: #3b82f6;
  --spacing-md: 1rem;
}
.button { background: var(--color-primary); padding: var(--spacing-md); }

21. What is the difference between CSS transitions and animations?

Transitions animate a CSS property from one value to another when triggered by a state change (usually :hover or a class being added). They have a start state and end state. Animations use @keyframes to define multiple intermediate states. They can run automatically, loop, alternate, and have more control over timing. Use transitions for simple hover effects; use animations for complex, multi-step, or looping effects.

22. What is will-change and when should you use it?

will-change hints to the browser that an element will be animated so it can be promoted to its own compositor layer in advance. This can improve animation performance. Use it sparingly — only on elements you know will animate, applied just before the animation starts (not permanently on everything). Overuse wastes GPU memory.

23. What is the cascade in CSS?

The cascade is the algorithm that determines which CSS rule wins when multiple rules target the same element. It considers (in order): importance (!important), origin (user-agent, author, user), specificity, and order of appearance. Later rules override earlier ones at equal specificity.

24. What is BEM (Block Element Modifier)?

BEM is a CSS naming convention that keeps styles modular and avoids specificity wars. Block: a standalone component (.card). Element: a part of the block, using double underscore (.card__title, .card__image). Modifier: a variant, using double hyphen (.card--featured, .card__title--large). Each class has low specificity (just one class selector), making styles easy to override.

25. What is the clamp() function?

clamp(min, preferred, max) sets a value that scales between a minimum and maximum. It is perfect for fluid typography: font-size: clamp(1rem, 2.5vw, 2rem) sets the font to 2.5% of the viewport width, but never smaller than 1rem or larger than 2rem — without any media queries.