Episode 1 — Fundamentals / 1.9 — CSS Responsive Design

Interview Questions: CSS Responsive Design

Practice questions with model answers for mobile-first strategy, media queries, breakpoints, responsive images, fluid typography, spacing systems, and CSS frameworks — topics commonly asked in front-end and full-stack interviews.

How to use this material (instructions)

  1. Read lessons in orderREADME.md, then 1.9.a1.9.g.
  2. Practice out loud — aim for 1–2 minutes per question, then compare to the model answer.
  3. Structure answers — definition → example → trade-off / accessibility note.
  4. Pair with exercises1.9-Exercise-Questions.md.
  5. Quick review1.9-Quick-Revision.md.

Beginner (Q1–Q6)

Q1. What does "mobile-first" mean in responsive design?

Why interviewers ask: Tests whether you understand the CSS authoring strategy, not just the buzzword.

Model answer:

Mobile-first means your base CSS (outside any media query) targets the smallest viewport. You then add complexity for larger screens using min-width media queries. This is a form of progressive enhancement — every user gets a working experience, and capable browsers get a richer one.

/* Base: mobile */
.grid { display: block; }

/* Tablet and up */
@media (min-width: 768px) {
  .grid { display: grid; grid-template-columns: repeat(2, 1fr); }
}

The opposite — desktop-first — writes wide-screen styles first and overrides downward with max-width queries, which tends to produce larger CSS and more overrides on mobile devices.

Key distinction: Mobile-first is not about "designing for phones only" — it's about starting with the simplest layout and layering on complexity.


Q2. What is a media query? Give three examples of media features.

Why interviewers ask: Fundamental responsive CSS — should be instant recall.

Model answer:

A media query is a CSS @media rule that applies styles conditionally based on the user's device or environment. The syntax is:

@media <type>? and (<feature>: <value>) { /* rules */ }

Three common media features:

FeatureExamplePurpose
min-width(min-width: 768px)Apply above a viewport width
prefers-color-scheme(prefers-color-scheme: dark)Detect OS dark mode
hover(hover: hover)Detect if device supports hover

Others include orientation, pointer, prefers-reduced-motion, and the Level 4 range syntax (width >= 768px).


Q3. What is object-fit and when would you use it?

Why interviewers ask: Tests practical CSS for image handling — a daily task in front-end work.

Model answer:

object-fit controls how a replaced element (<img>, <video>) fills its container box — similar to background-size for background images.

ValueBehavior
fillStretches to fill (may distort)
containFits inside preserving ratio (may show gaps)
coverCovers entire box preserving ratio (may crop)
noneNatural size, may overflow
scale-downSmaller of contain or none

Most common use case: object-fit: cover on images inside fixed-height card containers. Pair with object-position to control which part of the image stays visible when cropped.

.card-img {
  width: 100%;
  height: 200px;
  object-fit: cover;
  object-position: center top;
}

Q4. What is clamp() and how does it help with responsive typography?

Why interviewers ask: Modern CSS skill — shows you know how to build fluid layouts without breakpoint soup.

Model answer:

clamp(min, preferred, max) returns a value that:

  • Never goes below min
  • Never goes above max
  • Uses the preferred value when it falls between the bounds

For typography, it creates smooth scaling between viewport sizes:

h1 {
  font-size: clamp(1.5rem, 2.5vw + 0.5rem, 3rem);
}

At narrow viewports, the heading is 1.5rem. As the viewport grows, it scales with 2.5vw + 0.5rem. It caps at 3rem on wide screens. No breakpoint jumps.

Accessibility key: Use rem for min/max so the values scale when users change their browser's base font size.


Q5. Why should you always set width and height on images?

Why interviewers ask: Tests awareness of CLS (Cumulative Layout Shift) — a Core Web Vital.

Model answer:

Without explicit dimensions, the browser doesn't know how much space to reserve until the image downloads. When the image arrives, surrounding content shifts — this is CLS.

Setting width and height attributes (or the aspect-ratio CSS property) lets the browser calculate the aspect ratio and reserve the correct space immediately, even before the image loads.

<img src="photo.jpg" width="800" height="600" alt="…" loading="lazy" />
img {
  max-width: 100%;
  height: auto; /* preserves ratio while constraining width */
}

The browser computes: "This image is 4:3 → at 400px wide, reserve 300px height." No shift.


Q6. What is a spacing system and why use one?

Why interviewers ask: Shows design thinking — consistency, maintainability, and speed.

Model answer:

A spacing system defines a fixed set of spacing values based on a base unit (typically 4px or 8px). Every margin, padding, and gap in the project uses a value from this scale.

:root {
  --space-2: 0.5rem;   /*  8px */
  --space-4: 1rem;     /* 16px */
  --space-6: 1.5rem;   /* 24px */
  --space-8: 2rem;     /* 32px */
}

Benefits:

  • Visual consistency — spacing follows a rhythm, making the design look intentional.
  • Faster decisions — developers pick from the scale instead of inventing values.
  • Easy global changes — update a token, and all spacing adjusts.
  • Eliminates magic numbers — every value has a clear origin.

Intermediate (Q7–Q11)

Q7. Compare srcset with <picture>. When do you use each?

Why interviewers ask: Tests understanding of resolution switching vs art direction — a nuanced distinction.

Model answer:

Featuresrcset + sizes<picture>
PurposeResolution switchingArt direction
Who decides?The browser picks the best fileThe author controls which source matches
Use caseSame image at different resolutionsDifferent crops, formats, or entirely different images per breakpoint
<!-- srcset: same photo, different sizes -->
<img srcset="photo-400.jpg 400w, photo-800.jpg 800w"
     sizes="(min-width: 1024px) 50vw, 100vw"
     src="photo-800.jpg" alt="…" />

<!-- picture: different crop at each breakpoint -->
<picture>
  <source media="(min-width: 1024px)" srcset="hero-wide.webp" />
  <source media="(min-width: 640px)" srcset="hero-square.webp" />
  <img src="hero-tall.jpg" alt="…" />
</picture>

<picture> is also used for format switching — serving AVIF/WebP with JPEG fallback via the type attribute.


Q8. How do content-driven breakpoints differ from device-driven breakpoints?

Why interviewers ask: Reveals whether you think about responsive design in a sustainable way.

Model answer:

Device-driven: Pick breakpoints matching popular device widths (375px iPhone, 768px iPad). Breaks when new devices ship with different dimensions.

Content-driven: Resize the browser and add a breakpoint where the content looks bad — where text lines get too long, cards squish, or images distort. These breakpoints survive device changes because they follow the content.

Practical approach:

  1. Write base mobile styles.
  2. Slowly drag the viewport wider.
  3. When the layout breaks visually, that's your breakpoint.
  4. Often you only need 2–3 breakpoints.

Using fluid techniques (auto-fit, clamp()) can eliminate breakpoints entirely for many components.


Q9. How does prefers-reduced-motion work, and how should you implement it?

Why interviewers ask: Accessibility awareness — distinguishes thoughtful developers.

Model answer:

prefers-reduced-motion is a media query that detects whether the user has requested reduced motion in their OS settings (common for users with vestibular disorders, epilepsy, or motion sensitivity).

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }
}

Best practice: Default to no animation and add motion for users who haven't opted out:

/* Safe default: no animation */
.card { transition: none; }

/* Only animate if user is okay with motion */
@media (prefers-reduced-motion: no-preference) {
  .card { transition: transform 0.3s ease; }
}

This "motion-safe" pattern is more inclusive because users who haven't set a preference still benefit from a working (non-animated) baseline.


Q10. What is the difference between a utility-first framework and a component-based framework?

Why interviewers ask: Tests architectural understanding of CSS tooling choices.

Model answer:

AspectUtility-first (Tailwind)Component-based (Bootstrap)
ApproachSmall single-purpose classes composed in HTMLPre-designed components with semantic class names
Button exampleclass="bg-blue-600 text-white py-2 px-4 rounded"class="btn btn-primary"
CustomizationConfigure design tokens in config fileOverride Sass variables or write custom CSS
HTML verbosityHigh (many classes per element)Low (1–2 classes per element)
CSS outputVery small after purgingLarger unless tree-shaken
Design uniquenessHigh (you compose everything)Lower (default Bootstrap look)

Trade-off: Utility-first gives more control but requires composing styles manually. Component-based is faster to start but harder to customize deeply.


Q11. Explain the Media Queries Level 4 range syntax. Why is it better?

Why interviewers ask: Tests awareness of modern CSS features and their benefits.

Model answer:

Level 4 range syntax replaces min-width / max-width with comparison operators:

Old syntaxNew syntax
(min-width: 768px)(width >= 768px)
(max-width: 1023px)(width < 1024px)
(min-width: 768px) and (max-width: 1023px)(768px <= width < 1024px)

Benefits:

  1. Readability — reads like natural math, less ambiguous.
  2. Fewer off-by-one errorsmax-width: 767px vs max-width: 768px confusion disappears with explicit < and >=.
  3. Range expressions(768px <= width < 1024px) is cleaner than two and-combined conditions.

Supported in all modern browsers (Chrome 104+, Firefox 102+, Safari 16.4+).


Advanced (Q12–Q15)

Q12. Walk through designing a fully responsive page from scratch.

Why interviewers ask: Tests end-to-end responsive design thinking — not just isolated techniques.

Model answer:

  1. Content inventory — List everything the page needs to show. Prioritize by importance.
  2. Mobile layout — Design single-column, stacked layout first. Set typography with clamp().
  3. Spacing tokens — Define a spacing scale (--space-2 through --space-16) using CSS custom properties.
  4. Fluid grids — Use auto-fit + minmax() for grids that adapt without breakpoints.
  5. First breakpoint (~640px) — Where does content visually break? Add a query for two-column layout.
  6. Second breakpoint (~1024px) — Full desktop: sidebar, wider spacing, multi-column grids.
  7. Imagessrcset + sizes for resolution switching, <picture> for art direction, loading="lazy" for below-fold, aspect-ratio for CLS prevention.
  8. User preferencesprefers-color-scheme for dark mode, prefers-reduced-motion to disable animations.
  9. Test — Slow-drag viewport from 320px to 2560px, test browser zoom at 200%, test on real devices, test with screen reader.

Q13. A client complains their site is "slow on mobile." How do you diagnose and fix responsive performance issues?

Why interviewers ask: Tests real-world problem-solving beyond theoretical knowledge.

Model answer:

Diagnosis:

  1. Run Lighthouse on mobile — check Performance, LCP, CLS, and FID/INP.
  2. DevTools Network tab — throttle to "Slow 3G," check total transfer size. Are desktop-sized images loading on mobile?
  3. DevTools Coverage tab — how much CSS is unused on mobile? If using desktop-first CSS, mobile is parsing rules it never applies.
  4. Check image sizes — any images wider than their display size × device pixel ratio?

Common fixes:

ProblemSolution
Oversized images on mobilesrcset + sizes, serve WebP/AVIF
Desktop CSS loaded on mobileRewrite mobile-first; complex layout in min-width queries
Animations jankingprefers-reduced-motion: reduce; use transform/opacity only
Lazy resources not deferredloading="lazy" on images, defer on scripts
No space reserved for imagesAdd width/height or aspect-ratio to prevent CLS
Framework bloatPurge/tree-shake unused CSS classes

Q14. How would you implement a responsive navigation that works on both touch and mouse devices?

Why interviewers ask: Combines media queries, touch targets, hover behavior, and progressive enhancement.

Model answer:

/* Base: mobile — hamburger menu */
.nav-links { display: none; }
.menu-btn  { display: block; min-height: 48px; min-width: 48px; }

/* Desktop: full nav */
@media (min-width: 768px) {
  .nav-links { display: flex; gap: 1.5rem; }
  .menu-btn  { display: none; }
}

/* Hover effects only on hover-capable devices */
@media (hover: hover) {
  .nav-links a:hover {
    color: var(--accent);
    text-decoration: underline;
  }
}

/* Larger touch targets on coarse pointers */
@media (pointer: coarse) {
  .nav-links a {
    padding: 0.75rem 1rem;
    min-height: 48px;
    display: flex;
    align-items: center;
  }
}

Key points:

  • Use hover: hover to avoid "sticky hover" on touch devices.
  • Use pointer: coarse for enlarged touch targets.
  • JavaScript handles the hamburger toggle — keep it progressively enhanced (nav links should be reachable without JS, e.g., skip link to footer nav).

Q15. Compare clamp() for fluid typography vs breakpoint-based font sizing. When would you choose one over the other?

Why interviewers ask: Tests nuanced understanding — both approaches are valid.

Model answer:

Aspectclamp()Breakpoint-based
ScalingSmooth — size changes continuouslyStepped — size jumps at breakpoints
CodeSingle line per element2–4 rules per element (base + queries)
PredictabilityHarder to predict exact size at any widthExact size known at each range
Design matchMay not hit exact design comp sizesCan match comps precisely
AccessibilityGood with rem boundsGood with any unit
Browser supportAll modern browsersUniversal

When to use clamp(): Most projects — it's simpler, smoother, and reduces CSS.

When to use breakpoints: When the design requires specific font sizes at specific widths (e.g., designer hands you a 3-size spec: mobile 18px, tablet 24px, desktop 32px — no in-between scaling desired).

Hybrid approach: Use clamp() as the default and override at a specific breakpoint if a design comp requires an exact jump.


Navigation: ← 1.9 Overview · 1.9-Exercise-Questions · 1.9-Quick-Revision