Responsive Design and Modern CSSIntroductionResponsive design is the practice of creating interfaces that adapt to different screen sizes, input methods, pixel densities, operating systems, and user preferences. A responsive interface is not merely a smaller desktop page. It reorganises content, controls, spacing, images, and interaction patterns so that the interface remains usable and understandable in changing conditions. Modern CSS supports this work through media queries, container queries, flexible layout systems, fluid sizing functions, responsive media, custom properties, pseudo-classes, transitions, animations, and preference-aware styling. These features allow developers to describe design rules rather than create a separate page for every device. The central design principle is progressive enhancement: begin with a functional, accessible small-screen experience, then add layout and visual enhancements when the browser and available space support them. Learning ObjectivesBy the end of this chapter, you should be able to: - explain the principles of responsive and mobile-first design;
- build layouts with flexible grids, Flexbox, and Grid;
- use media queries and container queries appropriately;
- apply fluid sizing with
min(), max(), and clamp(); - create responsive images and media;
- use custom properties, pseudo-classes, transitions, and basic animations;
- respect reduced-motion, contrast, and colour-scheme preferences;
- design fallbacks for browsers with incomplete feature support; and
- evaluate responsive interfaces for usability, accessibility, and maintainability.
1. The Responsive Design ModelA responsive page responds to constraints. The relevant constraints include viewport width, available component width, device orientation, pointer accuracy, screen resolution, zoom level, language, and user preferences. A useful model is: Content determines the layout; the layout should not be determined only by popular device dimensions. Older approaches often used fixed desktop layouts and then added special rules for named devices. This is fragile because new phones, tablets, foldable screens, split-screen windows, and browser zoom levels do not fit a small list of device categories. Instead, a design should change when the content begins to fail—for example, when navigation wraps badly or a card becomes too narrow to read. Viewport and component constraintsA viewport query evaluates the browser viewport. A container query evaluates the size of a designated ancestor. These answer different questions: | Query type | Question answered | Typical use |
|---|
| Media query | How large is the viewing environment? | Page navigation, global columns, print, colour scheme | | Container query | How much space does this component have? | Reusable cards, dashboards, sidebars | | Feature query | Does the browser support this CSS feature? | Progressive enhancement and fallbacks |
Responsive design also depends on the viewport configuration in HTML: <meta name="viewport" content="width=device-width, initial-scale=1"> Without this metadata, some mobile browsers may use a virtual desktop-width viewport, making CSS media queries behave unexpectedly. The width=device-width value maps the CSS viewport to the device width, while initial-scale=1 establishes the initial zoom level. 2. Mobile-First LayoutMobile-first CSS starts with the simplest usable layout and adds enhancements using min-width conditions. This approach encourages content prioritisation, reduces unnecessary rules, and provides a sound default for browsers that do not understand newer media features. * {
box-sizing: border-box;
}
body {
margin: 0;
font-family: system-ui, sans-serif;
line-height: 1.5;
}
.page {
width: min(100% - 2rem, 72rem);
margin-inline: auto;
}
.cards {
display: grid;
gap: 1rem;
}
@media (min-width: 48rem) {
.cards {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
@media (min-width: 72rem) {
.cards {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}The box-sizing: border-box rule makes declared width include padding and borders, which makes sizing easier to reason about. The minmax(0, 1fr) pattern prevents long content from forcing a grid track wider than intended. Breakpoints should be selected by testing the design, not by assuming that every device belongs to a particular category. Flexible layout toolsFlexbox is primarily one-dimensional. It is effective for navigation rows, button groups, aligned controls, and content that grows or shrinks along one axis. .toolbar {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 0.75rem;
}
.toolbar .search {
flex: 1 1 16rem;
}Grid is primarily two-dimensional. It is useful when rows and columns must be coordinated. .dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
gap: 1rem;
}auto-fit creates as many tracks as fit, while minmax() supplies a minimum and maximum track size. This can provide responsive behaviour with fewer explicit breakpoints.
Do not use CSS alone to change the logical order of content in a way that conflicts with keyboard or screen-reader order. Visual reordering with order or grid placement can cause confusion. The HTML source should normally follow the meaningful reading and interaction sequence. 3. Media QueriesA media query conditionally applies declarations according to an environment feature. @media (min-width: 50rem) and (orientation: landscape) {
.site-header {
display: grid;
grid-template-columns: 1fr auto;
}
}Important media features include: min-width and max-width for viewport dimensions;orientation for portrait or landscape presentation;prefers-color-scheme for light or dark preference;prefers-reduced-motion for motion sensitivity;hover and pointer for interaction capability; andforced-colors for high-contrast modes in supporting systems.
A coarse pointer should not be treated as proof that a user is on a phone, and a narrow screen does not prove that touch is available. Design controls with adequate target size and visible focus regardless of device assumptions. A feature query tests implementation support: .panel {
display: block;
}
@supports (display: grid) {
.panel {
display: grid;
grid-template-columns: 1fr 2fr;
}
}The fallback should remain useful. @supports is not a replacement for testing the actual result in target browsers. 4. Container QueriesA component may appear in a wide main column, a narrow sidebar, or a modal. A viewport breakpoint cannot reliably describe all these contexts. Container queries allow the component to respond to its own available inline size. .card-list {
container-type: inline-size;
container-name: cards;
}
.card {
display: grid;
gap: 0.75rem;
}
@container cards (min-width: 36rem) {
.card {
grid-template-columns: 10rem 1fr;
align-items: center;
}
}container-type: inline-size establishes a queryable container based on its inline dimension. A component should be usable at its default narrow size; the query should enhance it when more space is available. Container queries improve component portability, but they do not eliminate the need for page-level media queries, such as a change in global navigation.
5. Fluid Sizing and CSS FunctionsFixed values are useful for borders, icons, and minimum touch dimensions, but typography and spacing often benefit from fluid values. CSS provides mathematical functions for constrained fluid sizing. h1 {
font-size: clamp(2rem, 5vw, 4rem);
}
.section {
padding-block: clamp(2rem, 8vw, 6rem);
}The general form is: clamp(minimum, preferred, maximum) The browser selects a value that is at least the minimum and no greater than the maximum, while the preferred expression responds to available conditions. In 5vw, vw means one percent of viewport width. For example, at a 1,000-pixel viewport, 5vw corresponds to 50 CSS pixels before the lower and upper bounds are applied. The result is not necessarily equal to 50 pixels because clamp() may select the minimum or maximum. Other functions include: .sidebar {
width: min(22rem, 100%);
}
.content {
padding-inline: max(1rem, 3vw);
}min() selects the smallest valid value and max() selects the largest. These functions are particularly useful for preventing overflow while preserving readable spacing. Use relative units such as rem, %, vw, and lh when they express the intended relationship. Avoid using viewport width as the sole basis for text because users may zoom or change text settings.
6. Responsive Images and MediaImages should be flexible and should not overflow their containing block. img,
picture,
video {
max-width: 100%;
}
img,
video {
height: auto;
}For a fixed aspect ratio region, use: .hero img {
width: 100%;
aspect-ratio: 16 / 9;
object-fit: cover;
}The aspect-ratio property describes the width-to-height relationship. object-fit: cover fills the region but may crop the image; contain preserves the complete image but may leave empty space. The choice is a content decision, not merely a technical one. Use srcset and sizes when different image resolutions are appropriate: <img
src="photo-800.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1400.jpg 1400w"
sizes="(min-width: 60rem) 50vw, 100vw"
alt="Students collaborating around a laptop"> The width descriptors tell the browser the intrinsic widths of candidates. The sizes attribute estimates the rendered width under layout conditions, allowing the browser to select an efficient file. Art direction—using different crops or compositions—can be implemented with <picture> and <source media="...">. Meaningful images need accurate alternative text; decorative images should generally use an empty alt attribute. 7. Custom Properties and Maintainable CSSCustom properties store reusable tokens and participate in the cascade. :root {
--colour-text: #172033;
--colour-surface: #ffffff;
--colour-accent: #1457b8;
--space-2: 0.5rem;
--radius: 0.75rem;
}
.card {
color: var(--colour-text);
background: var(--colour-surface);
padding: var(--space-2);
border-radius: var(--radius);
}A fallback can be supplied as a second argument: color: var(--colour-accent, blue); Custom properties are inherited by default and can be redefined in a component or theme. They are useful for design tokens, dark themes, spacing systems, and controlled component variations. They are not identical to preprocessor variables: custom properties exist in the browser’s cascade and can change at runtime. @media (prefers-color-scheme: dark) {
:root {
--colour-text: #f2f5fa;
--colour-surface: #151a22;
}
}Colour contrast must be checked rather than guessed. Do not communicate essential status through colour alone; combine colour with text, icons, or structure. 8. Pseudo-Classes and Interaction StatesPseudo-classes select elements according to state or position. Common interaction states include :hover, :focus, :focus-visible, :active, :disabled, and :checked. .button {
background: var(--colour-accent);
color: white;
transition: background-color 160ms ease, transform 160ms ease;
}
.button:hover {
background: #0e3f86;
}
.button:focus-visible {
outline: 3px solid #f4b400;
outline-offset: 3px;
}
.button:active {
transform: translateY(1px);
}:focus-visible helps show a focus indicator when keyboard-style navigation requires it, without removing focus visibility altogether. Never use outline: none without providing a clearly visible replacement. :has() can express relationships in supporting browsers, for example .field:has(input:invalid), but a fallback may be needed for older browsers.
Structural pseudo-classes such as :first-child, :last-child, and :nth-child() can reduce unnecessary classes, but selectors should remain understandable. :where() has zero specificity, while :is() takes the specificity of its most specific argument; these tools can help control cascade complexity. 9. Transitions and Basic AnimationsA transition interpolates a property between two states. An animation uses keyframes and may run independently of a state change. .menu {
opacity: 0;
transform: translateY(-0.5rem);
pointer-events: none;
transition: opacity 180ms ease, transform 180ms ease;
}
.menu.is-open {
opacity: 1;
transform: translateY(0);
pointer-events: auto;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.04); }
}
.status {
animation: pulse 1.5s ease-in-out 2;
}Prefer animating transform and opacity, which generally avoid expensive layout recalculation. Do not animate large areas continuously without a purpose; motion can distract users and consume battery. Ensure that an animated state does not hide essential information or prevent keyboard interaction. Respect the reduced-motion preference: @media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}A good design does not merely make motion faster; it removes nonessential movement while preserving changes of state and information. 10. Applied Case: A Responsive Course CatalogueBackgroundAn illustrative training provider has a course catalogue containing filters, course cards, prices, and enrolment actions. The existing desktop layout uses fixed widths and becomes difficult to use on phones. ProblemOn narrow screens, filters push cards below the fold, images overflow, and hover-only buttons are inaccessible to keyboard and touch users. On a wide screen, the same card must work in a sidebar widget and in the main catalogue. AnalysisThe page requires global viewport adaptation, while the card requires adaptation to its local container. The design team identifies the following priorities: - Search and course title must remain available at every width.
- Filters should collapse into a labelled control on small screens.
- Cards should use a single-column structure when narrow and an image/content structure when wide.
- Enrolment controls must be keyboard accessible and visible without hover.
- Images must preserve an intentional ratio and load an appropriate resolution.
Approach and solutionThe page begins with a one-column grid. At a tested viewport width, the filter panel becomes a second page column. Each card establishes a query container and changes its internal layout according to its own width. Custom properties hold colours and spacing. Focus-visible styles are explicit, and motion is disabled or reduced when requested. .catalog {
display: grid;
gap: 1rem;
}
@media (min-width: 60rem) {
.catalog {
grid-template-columns: 16rem 1fr;
}
}
.course-card {
container-type: inline-size;
display: grid;
gap: 1rem;
padding: 1rem;
border: 1px solid #ccd3df;
border-radius: var(--radius);
}
@container (min-width: 34rem) {
.course-card {
grid-template-columns: 11rem 1fr;
}
}OutcomeThe catalogue remains readable at narrow widths, uses available space efficiently at larger widths, and permits the same card component to be reused in different page regions. Accessibility testing confirms that keyboard users can reach filters and enrolment controls, while image testing confirms that smaller files are selected on constrained connections and displays. Learning pointsThe case illustrates that responsive design is a system of constraints rather than a collection of device-specific patches. Page-level concerns belong in media queries; component-level concerns belong in container queries. Accessibility and performance must be designed together with layout. 11. Browser Support, Testing, and PerformanceModern CSS features have different support histories. Check reliable compatibility documentation and test the actual browsers required by the project. Use a layered strategy: - provide semantic HTML and a usable base layout;
- add broadly supported Flexbox or Grid rules;
- enhance with container queries, advanced selectors, or newer functions;
- provide fallbacks where loss of the enhancement would harm usability; and
- test with zoom, keyboard navigation, touch, slow networks, and different writing directions.
Useful tests include: - viewport widths between, not only at, selected breakpoints;
- browser zoom and large text settings;
- portrait and landscape orientation;
- keyboard focus and visible focus indicators;
- screen readers and accessible names;
- reduced motion, dark mode, and forced-colour settings;
- long words, translated text, and empty or error states; and
- real devices rather than relying solely on browser emulation.
Responsive performance includes image bytes, layout stability, font loading, and script execution. Reserve image space with dimensions or aspect-ratio to reduce layout shift. Avoid hiding large content with CSS when it could have been omitted or loaded conditionally. Use loading="lazy" for suitable below-the-fold images, but do not lazily load the principal above-the-fold image without a reason. 12. Professional and Ethical ConsiderationsResponsive interfaces influence access to education, employment, health information, and public services. A design that works only with a precise screen size can exclude users with disabilities or limited equipment. Developers should treat accessibility as a quality requirement, not a decorative addition. Do not use dark patterns such as hiding cancellation controls on small screens, making consent buttons visually dominant, or relying on motion to attract attention. Respect user preferences and avoid collecting device information unless it is necessary and transparently explained. Testing should include diverse users, browsers, devices, languages, and assistive technologies. Chapter SummaryResponsive design creates interfaces that adapt to viewport and component constraints while preserving content, accessibility, and usability. Mobile-first CSS establishes a robust narrow-screen base and adds enhancements with media queries. Flexbox supports one-dimensional alignment, while Grid supports two-dimensional layouts. Container queries allow reusable components to respond to their own available width. Fluid functions such as min(), max(), and clamp() constrain dimensions without relying solely on fixed breakpoints. Responsive images use flexible sizing, aspect ratios, srcset, and sizes to reduce overflow and unnecessary downloads. Custom properties support maintainable design tokens and themes. Pseudo-classes provide state styling, while transitions and animations should focus on purposeful, efficient motion and respect prefers-reduced-motion. Reliable responsive development combines progressive enhancement, browser testing, keyboard access, readable content, performance awareness, and ethical consideration of diverse users. Key TermsResponsive design: A design approach that adapts an interface to changing environmental and user constraints. Mobile-first: Designing the basic experience for small screens before adding larger-screen enhancements. Viewport: The visible browser area used as a reference by media queries. Media query: A conditional CSS rule based on an environment feature. Container query: A conditional CSS rule based on an ancestor container’s size. Breakpoint: A condition at which layout rules change. Flexbox: A CSS layout system for arranging items along one principal axis. Grid: A CSS layout system for coordinated rows and columns. Fluid sizing: Sizing that changes continuously within defined constraints. clamp(): A CSS function that limits a preferred value between minimum and maximum values.
Custom property: A browser-managed CSS variable written with a double-hyphen prefix. Pseudo-class: A selector describing an element’s state or structural condition. Transition: A gradual interpolation between property values. Keyframe animation: An animation defined by intermediate stages in an @keyframes rule. Progressive enhancement: Building a functional base and adding capabilities when supported. Art direction: Providing different media compositions for different contexts. Intrinsic size: The natural dimensions of an element or resource. Focus-visible: A pseudo-class used to identify when a visible focus indicator is especially needed. Design token: A named value representing a reusable design decision such as colour or spacing. Forced-colours mode: A user or system mode that replaces author colours to improve visibility. Review QuestionsShort Answer Questions- What is the difference between a media query and a container query?
- Why is mobile-first design commonly implemented with
min-width conditions? - What problem does
minmax(0, 1fr) help prevent in a CSS Grid? - State two benefits of CSS custom properties.
- Why should an interface respect
prefers-reduced-motion?
Long Answer Questions- Explain how Flexbox and Grid differ, and give an appropriate use case for each.
- Describe how
srcset and sizes help deliver responsive images. - Explain progressive enhancement and show how
@supports can be used responsibly. - Discuss the accessibility risks of visual reordering and hover-only interactions.
- Describe a complete testing strategy for a responsive course catalogue.
Analytical / Application Questions- A card works in a wide main column but becomes unreadable in a narrow sidebar. Explain why a container query may be better than adding another viewport breakpoint, and outline the CSS approach.
- A designer proposes
font-size: 5vw for all headings. Evaluate this proposal and recommend a safer fluid-sizing strategy. - An animated notification pulses continuously, but users report distraction and battery drain. Analyse the design and propose an accessible alternative using state-based motion and reduced-motion support.
Multiple Choice Questions with AnswersQuestion 1Which query responds to the size of an element’s query container rather than the browser viewport? A. A media query B. A container query C. A feature query D. A print query Correct Answer: B. A container query Question 2What does clamp(1rem, 3vw, 2rem) guarantee? A. The value is always exactly 3vw B. The value is never below 1rem or above 2rem C. The value is fixed at 2rem on mobile D. The value ignores viewport width Correct Answer: B. The value is never below 1rem or above 2rem Question 3Which layout system is primarily one-dimensional? A. Flexbox B. CSS Grid C. Container queries D. The cascade Correct Answer: A. Flexbox Question 4What is the main purpose of the sizes attribute on a responsive image? A. To provide alternative text B. To describe the image’s expected rendered width C. To crop the image automatically D. To disable image loading Correct Answer: B. To describe the image’s expected rendered width Question 5Which pseudo-class is most appropriate for providing a keyboard-visible focus style? A. :empty B. :visited C. :focus-visible D. :root Correct Answer: C. :focus-visible Question 6Which property commonly supports efficient animation without changing document layout? A. transform B. margin-left C. width D. grid-template-columns Correct Answer: A. transform Question 7What does @supports test? A. Whether a user prefers dark mode B. Whether a browser supports a CSS feature C. Whether an image has alternative text D. Whether a container is wider than the viewport Correct Answer: B. Whether a browser supports a CSS feature Question 8Which approach is most consistent with progressive enhancement? A. Providing only a JavaScript-dependent layout B. Starting with usable HTML and adding supported enhancements C. Using fixed widths for every device D. Removing keyboard focus indicators Correct Answer: B. Starting with usable HTML and adding supported enhancements Question 9Why can order create an accessibility problem? A. It disables all media queries B. It may make visual order differ from reading or keyboard order C. It prevents images from loading D. It changes the browser viewport Correct Answer: B. It may make visual order differ from reading or keyboard order Question 10Which media feature indicates that a user prefers reduced animation? A. prefers-contrast: no-preference B. prefers-reduced-motion: reduce C. orientation: reduce D. pointer: reduced Correct Answer: B. prefers-reduced-motion: reduce
|