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)
- Read lessons in order —
README.md, then1.9.a→1.9.g. - Practice out loud — aim for 1–2 minutes per question, then compare to the model answer.
- Structure answers — definition → example → trade-off / accessibility note.
- Pair with exercises —
1.9-Exercise-Questions.md. - Quick review —
1.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:
| Feature | Example | Purpose |
|---|---|---|
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.
| Value | Behavior |
|---|---|
fill | Stretches to fill (may distort) |
contain | Fits inside preserving ratio (may show gaps) |
cover | Covers entire box preserving ratio (may crop) |
none | Natural size, may overflow |
scale-down | Smaller 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:
| Feature | srcset + sizes | <picture> |
|---|---|---|
| Purpose | Resolution switching | Art direction |
| Who decides? | The browser picks the best file | The author controls which source matches |
| Use case | Same image at different resolutions | Different 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:
- Write base mobile styles.
- Slowly drag the viewport wider.
- When the layout breaks visually, that's your breakpoint.
- 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:
| Aspect | Utility-first (Tailwind) | Component-based (Bootstrap) |
|---|---|---|
| Approach | Small single-purpose classes composed in HTML | Pre-designed components with semantic class names |
| Button example | class="bg-blue-600 text-white py-2 px-4 rounded" | class="btn btn-primary" |
| Customization | Configure design tokens in config file | Override Sass variables or write custom CSS |
| HTML verbosity | High (many classes per element) | Low (1–2 classes per element) |
| CSS output | Very small after purging | Larger unless tree-shaken |
| Design uniqueness | High (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 syntax | New syntax |
|---|---|
(min-width: 768px) | (width >= 768px) |
(max-width: 1023px) | (width < 1024px) |
(min-width: 768px) and (max-width: 1023px) | (768px <= width < 1024px) |
Benefits:
- Readability — reads like natural math, less ambiguous.
- Fewer off-by-one errors —
max-width: 767pxvsmax-width: 768pxconfusion disappears with explicit<and>=. - Range expressions —
(768px <= width < 1024px)is cleaner than twoand-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:
- Content inventory — List everything the page needs to show. Prioritize by importance.
- Mobile layout — Design single-column, stacked layout first. Set typography with
clamp(). - Spacing tokens — Define a spacing scale (
--space-2through--space-16) using CSS custom properties. - Fluid grids — Use
auto-fit+minmax()for grids that adapt without breakpoints. - First breakpoint (~640px) — Where does content visually break? Add a query for two-column layout.
- Second breakpoint (~1024px) — Full desktop: sidebar, wider spacing, multi-column grids.
- Images —
srcset+sizesfor resolution switching,<picture>for art direction,loading="lazy"for below-fold,aspect-ratiofor CLS prevention. - User preferences —
prefers-color-schemefor dark mode,prefers-reduced-motionto disable animations. - 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:
- Run Lighthouse on mobile — check Performance, LCP, CLS, and FID/INP.
- DevTools Network tab — throttle to "Slow 3G," check total transfer size. Are desktop-sized images loading on mobile?
- DevTools Coverage tab — how much CSS is unused on mobile? If using desktop-first CSS, mobile is parsing rules it never applies.
- Check image sizes — any images wider than their display size × device pixel ratio?
Common fixes:
| Problem | Solution |
|---|---|
| Oversized images on mobile | srcset + sizes, serve WebP/AVIF |
| Desktop CSS loaded on mobile | Rewrite mobile-first; complex layout in min-width queries |
| Animations janking | prefers-reduced-motion: reduce; use transform/opacity only |
| Lazy resources not deferred | loading="lazy" on images, defer on scripts |
| No space reserved for images | Add width/height or aspect-ratio to prevent CLS |
| Framework bloat | Purge/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: hoverto avoid "sticky hover" on touch devices. - Use
pointer: coarsefor 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:
| Aspect | clamp() | Breakpoint-based |
|---|---|---|
| Scaling | Smooth — size changes continuously | Stepped — size jumps at breakpoints |
| Code | Single line per element | 2–4 rules per element (base + queries) |
| Predictability | Harder to predict exact size at any width | Exact size known at each range |
| Design match | May not hit exact design comp sizes | Can match comps precisely |
| Accessibility | Good with rem bounds | Good with any unit |
| Browser support | All modern browsers | Universal |
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