Skip to content
Journey to Code

Journey to Web Components: From Fundamentals to Advanced UI Architecture

Responsive Layouts & Advanced CSS Techniques

Adapting design for every device using flexbox, grid, and media queries

· By · Updated · 6 min read

Cover reading "Responsive Layouts" with an auto-fit grid rule and the same cards reflowing into one, two, and three columns

Introduction#

The same page gets opened on a phone held in one hand and on a wide desktop monitor. Responsive CSS lets one page rearrange itself for both, so we do not build two sites. A component dropped into a narrow sidebar has to do the same, which is why these are the layout tools we build components on.

Where we are: the last post covered selectors, specificity (the more specific selector wins, and on a tie the later rule wins) and accessible color, focus and units. We use all of that here.

Picture a row of three cards. On a desktop they sit side by side. On a phone there is no room, so they stack in one column. Responsive CSS is how we say that once:

.cards { display: grid; gap: 1rem; }                 /* phone: one column */
@media (min-width: 600px) {
  .cards { grid-template-columns: repeat(3, 1fr); }  /* wider: three columns */
}

A few terms, one line each:

  • Viewport: the visible area of the page in the browser window.
  • Media query: an @media (…) block whose rules apply only when its condition is true, such as a minimum viewport width.
  • Mobile-first: write the small-screen layout as the default and add min-width media queries that enhance it for bigger screens.
  • Flexbox: lays items out along one line (a row or a column).
  • Grid: lays items out in rows and columns at once.
  • gap: the space between flex or grid items.
  • fr: a fraction of the free space in a grid; 1fr 2fr gives the second column twice the width of the first.
  • minmax(250px, 1fr): a size that is never smaller than 250px and can grow to share the free space.
  • auto-fit: with repeat(), fit as many columns as the width allows and let the rest collapse.

In this article, we will look at techniques that help us build responsive layouts and keep them legible. We’ll cover:

  • Flexbox and Grid: Layout models that simplify complex designs.

  • Media Queries: Creating breakpoints to adapt our design to different viewports.

  • Advanced CSS Techniques: Enhancing typography, spacing, and color contrast for a more accessible experience.


Understanding Responsive Design#

Responsive design means creating layouts that automatically adjust to fit the screen size of the user’s device. The goal is a page that works no matter how it is viewed. This is achieved by using flexible grids, images, and CSS media queries.


Advanced Layout Models: Flexbox and Grid#

Flexbox#

Flexbox is designed for one-dimensional layouts. It allows developers to align and distribute space among items in a container, even when their size is unknown or dynamic.

Key Concepts:

Setting display: flex on a parent turns its children into flex items laid out along one axis, the main axis. Three properties do most of the work:

  • flex-direction picks the main axis: row (left to right) or column (top to bottom).

  • justify-content spaces the items along the main axis (flex-start, center, space-between, …).

  • align-items positions them across it (the cross axis), for example center to center them vertically in a row.

Example:

.flex-container {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}
A flex container has flex-direction: row, three small items and justify-content: space-between. Where do the items end up?

Coding challenge: Two properties, two layouts

Run it first: three boxes sit in a row at the left, and the grid below stacks the same boxes in one column.

Expected result: (1) the flex row has its first box at the far left and its last at the far right; (2) the grid shows three equal columns. When both work, try 1fr 2fr 1fr and check that the middle column is twice as wide as each outer one.

Flexbox then Grid
---html
<div class="row"><b>1</b><b>2</b><b>3</b></div>
<div class="grid"><b>1</b><b>2</b><b>3</b></div>
---css
b { background: #0056b3; color: #fff; padding: 1rem; text-align: center; }
.row, .grid { margin-bottom: 1.5rem; gap: 0.5rem; }

.row {
  display: flex;
  /* TODO 1: spread the boxes to both edges */
  justify-content: flex-start;
}

.grid {
  display: grid;
  /* TODO 2: three equal columns instead of one */
  grid-template-columns: 1fr;
}

Let's see Flexbox in action with a practical navigation menu example. This responsive navigation transforms from a mobile-friendly hamburger menu to a horizontal navbar on larger screens. Try resizing your browser window to see how it adapts to different viewport widths. Notice how just a few Flexbox properties create a completely different layout experience depending on the device.

Responsive Flexbox Navigation
---html
<h1>Responsive Flexbox Navigation</h1>
<p>Resize the browser window to see how this navigation adapts to different screen sizes. On small screens, it displays a vertical menu with a toggle button. On larger screens, it transforms into a horizontal navigation bar.</p>
<br>

<nav class="navbar">
	<div class="navbar-brand">
		<span>FlexNav</span>
		<button class="navbar-toggle" aria-label="Toggle navigation menu" aria-expanded="false">☰</button>
	</div>
	<div class="navbar-menu" id="navbar-menu">
		<a href="#" aria-current="page">Home</a>
		<a href="#">Features</a>
		<a href="#">Pricing</a>
		<a href="#">About</a>
		<a href="#">Contact</a>
	</div>
</nav>
---css
* {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      line-height: 1.6;
      color: #333;
      padding: 20px;
    }
    
    .navbar {
      display: flex;
      flex-direction: column;
      background-color: #4A5568;
      border-radius: 8px;
      overflow: hidden;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    }
    
    .navbar-brand {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 1rem;
      background-color: #2D3748;
      color: white;
    }
    
    .navbar-toggle {
      background: none;
      border: none;
      color: white;
      font-size: 1.5rem;
      cursor: pointer;
      display: block;
    }
    
    .navbar-toggle:focus {
      outline: 2px solid #63B3ED;
      outline-offset: 2px;
    }
    
    .navbar-menu {
      display: flex;
      flex-direction: column;
      max-height: 0;
      overflow: hidden;
      transition: max-height 0.3s ease;
    }
    
    .show-menu {
      max-height: 300px;
    }
    
    .navbar-menu a {
      color: white;
      text-decoration: none;
      padding: 1rem;
      border-top: 1px solid #2D3748;
      transition: background-color 0.2s;
    }
    
    .navbar-menu a:hover, .navbar-menu a:focus {
      background-color: #2D3748;
      outline: none;
    }
    
    .navbar-menu a:focus-visible {
      outline: 2px solid #63B3ED;
      outline-offset: -2px;
    }
    
    /* Media Query for larger screens */
    @media (min-width: 768px) {
      .navbar {
        flex-direction: row;
        align-items: center;
      }
      
      .navbar-brand {
        background-color: transparent;
        padding: 0 1rem;
      }
      
      .navbar-toggle {
        display: none;
      }
      
      .navbar-menu {
        display: flex;
        flex-direction: row;
        max-height: none;
        flex-grow: 1;
        justify-content: flex-end;
      }
      
      .navbar-menu a {
        border-top: none;
        padding: 1.25rem 1.5rem;
      }
    }
---js
// Simple toggle for the mobile menu
const toggleButton = document.querySelector('.navbar-toggle');
const menu = document.getElementById('navbar-menu');

toggleButton.addEventListener('click', () => {
  const expanded = toggleButton.getAttribute('aria-expanded') === 'true';
  toggleButton.setAttribute('aria-expanded', !expanded);
  menu.classList.toggle('show-menu');
});

Grid#

CSS Grid is a two-dimensional layout system that offers a grid-based layout system with rows and columns. It’s ideal for complex layouts.

Key Concepts:

  • Grid Container: Set display: grid to create a grid container.

  • Grid Template: Define rows and columns using grid-template-columns and grid-template-rows.

  • Gap: Use grid-gap or simply gap to add spacing between grid items.

Grid layouts shine when creating complex, image-based interfaces. This photo gallery demonstrates the power of CSS Grid to create visually interesting layouts that automatically adapt to any screen size. The 'featured' images span multiple grid cells on larger screens but collapse into a clean single-column layout on mobile devices. Hover over each image to see additional interactive elements appearing smoothly.

Responsive Grid Photo Gallery
---html
<div class="container">
  <h1>Responsive Grid Photo Gallery</h1>
  <p>This gallery uses CSS Grid to create a responsive, adaptive layout. Resize the browser to see how the grid adjusts!</p>
  
  <div class="gallery">
    <div class="gallery-item featured">
      <a href="#mountain" tabindex="0">View Mountain Landscape</a>
      <img src="https://picsum.photos/id/29/800/800" alt="Mountain landscape with snow peaks">
      <div class="gallery-item-info">
        <h3 class="gallery-item-title">Mountain Peaks</h3>
        <p>Beautiful snow-covered mountains at sunrise</p>
      </div>
    </div>
    
    <div class="gallery-item">
      <a href="#ocean" tabindex="0">View Ocean Scene</a>
      <img src="https://picsum.photos/id/183/400/400" alt="Ocean waves crashing on rocks">
      <div class="gallery-item-info">
        <h3 class="gallery-item-title">Ocean Waves</h3>
        <p>Powerful waves crash against coastal rocks</p>
      </div>
    </div>
    
    <div class="gallery-item">
      <a href="#forest" tabindex="0">View Forest Trail</a>
      <img src="https://picsum.photos/id/15/400/400" alt="Sunlight through forest trees">
      <div class="gallery-item-info">
        <h3 class="gallery-item-title">Forest Path</h3>
        <p>Morning sunlight filters through ancient trees</p>
      </div>
    </div>
    
    <div class="gallery-item">
      <a href="#desert" tabindex="0">View Desert Landscape</a>
      <img src="https://picsum.photos/id/247/400/400" alt="Desert sand dunes at sunset">
      <div class="gallery-item-info">
        <h3 class="gallery-item-title">Desert Dunes</h3>
        <p>Golden sands stretch to the horizon</p>
      </div>
    </div>
    
    <div class="gallery-item">
      <a href="#waterfall" tabindex="0">View Waterfall</a>
      <img src="https://picsum.photos/id/130/400/400" alt="Waterfall cascading down rocks">
      <div class="gallery-item-info">
        <h3 class="gallery-item-title">Rushing Falls</h3>
        <p>Powerful waterfall in a lush green setting</p>
      </div>
    </div>
    
    <div class="gallery-item featured">
      <a href="#canyon" tabindex="0">View Canyon Vista</a>
      <img src="https://picsum.photos/id/111/800/800" alt="Wide canyon view with river below">
      <div class="gallery-item-info">
        <h3 class="gallery-item-title">Canyon Vista</h3>
        <p>Breathtaking view of a massive canyon formation</p>
      </div>
    </div>
    
    <div class="gallery-item">
      <a href="#lake" tabindex="0">View Mountain Lake</a>
      <img src="https://picsum.photos/id/110/400/400" alt="Calm mountain lake reflecting surroundings">
      <div class="gallery-item-info">
        <h3 class="gallery-item-title">Alpine Lake</h3>
        <p>Crystal clear waters reflect the surrounding peaks</p>
      </div>
    </div>
    
    <div class="gallery-item">
      <a href="#fields" tabindex="0">View Rolling Fields</a>
      <img src="https://picsum.photos/id/106/400/400" alt="Rolling green fields with wildflowers">
      <div class="gallery-item-info">
        <h3 class="gallery-item-title">Summer Fields</h3>
        <p>Rolling hills covered in colorful wildflowers</p>
      </div>
    </div>
  </div>
</div>
---css
* {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }
    
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      line-height: 1.6;
      color: #333;
      padding: 20px;
      background-color: #f8f9fa;
    }
    
    .container {
      max-width: 1200px;
      margin: 0 auto;
    }
    
    h1 {
      text-align: center;
      margin-bottom: 1rem;
      color: #2D3748;
    }
    
    p {
      text-align: center;
      margin-bottom: 2rem;
      color: #4A5568;
    }
    
    .gallery {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
      grid-gap: 15px;
    }
    
    .gallery-item {
      position: relative;
      overflow: hidden;
      border-radius: 8px;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
      transition: transform 0.3s ease, box-shadow 0.3s ease;
      cursor: pointer;
      aspect-ratio: 1 / 1;
    }
    
    .gallery-item:hover, .gallery-item:focus-within {
      transform: translateY(-5px);
      box-shadow: 0 10px 20px rgba(0, 0, 0, 0.15);
    }
    
    .gallery-item img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      display: block;
      transition: filter 0.3s ease;
    }
    
    .gallery-item:hover img, .gallery-item:focus-within img {
      filter: brightness(0.7);
    }
    
    .gallery-item-info {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
      color: white;
      padding: 15px;
      transform: translateY(100%);
      transition: transform 0.3s ease;
    }
    
    .gallery-item:hover .gallery-item-info,
    .gallery-item:focus-within .gallery-item-info {
      transform: translateY(0);
    }
    
    .gallery-item-title {
      font-size: 1.1rem;
      margin-bottom: 5px;
    }
    
    .gallery-item a {
      position: absolute;
      inset: 0;
      text-indent: -9999px;
      z-index: 1;
    }
    
    .gallery-item a:focus {
      text-indent: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      background: rgba(0, 0, 0, 0.5);
      text-decoration: none;
      color: white;
      font-weight: bold;
    }
    
    /* Featured items span two columns and rows on larger screens */
    @media (min-width: 768px) {
      .gallery-item.featured {
        grid-column: span 2;
        grid-row: span 2;
      }
    }

Example:

.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
}

Read it from the inside out: each column is at least 250px (minmax), the browser fits as many as the width allows (auto-fit), and the leftover space is shared equally (1fr). In a 700px-wide container that is two columns (3 would need 750px plus gaps); at 800px it is three. No media query is needed for this reflow.

A grid container is 1000px wide with gap: 0 and grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)). How many columns does it get?

Media Queries: Adapting to Different Viewports#

Media queries allow us to apply CSS rules based on conditions like viewport width, height, and even device orientation.

Example:

/* Default styles for mobile-first design */
.container {
  padding: 1rem;
}

/* For screens 600px wide or more */
@media (min-width: 600px) {
  .container {
    padding: 2rem;
  }
}

/* For screens 1024px wide or more */
@media (min-width: 1024px) {
  .container {
    padding: 3rem;
  }
}

This is mobile-first: the base rule is the phone layout, and each min-width query adds to it as the screen grows. The order matters, because both queries can be true at 1100px and the later one wins by the cascade rule from the last post.

With the mobile-first CSS above, what is the .container padding on a 800px-wide viewport?

Using media queries effectively means planning our breakpoints based on the content rather than arbitrary device sizes. This way, the design adapts naturally to the available space.

Media queries are the backbone of responsive design. This interactive example lets you see exactly when and how different design elements respond to changing viewport sizes. Watch as colors, layouts, and typography transform at each breakpoint—all while the current viewport width is displayed in real-time. This demonstrates how we can create completely different experiences for mobile, tablet, and desktop users with the same HTML.

Media Queries in Action
---html
<div class="container">
  <h1>Media Queries in Action</h1>
  <p>Resize your browser window to see how the design adapts to different screen sizes. Notice how colors, layouts, and typography change at each breakpoint.</p>
  
  <div class="width-display">
    Current width: <span id="width-value">-</span>px
  </div>
  
  <div class="demo-box">
    <div class="device-indicator"></div>
    <h2>This Box Changes Color</h2>
    <p>The background color of this box changes based on the viewport width, demonstrating how media queries can be used to provide visual feedback for different device sizes.</p>
  </div>
  
  <section class="card-layout">
    <h2>Card Layout</h2>
    <p>Watch how the number of columns changes based on screen width:</p>
    
    <div class="cards">
      <div class="card">
        <img src="https://picsum.photos/400/180?random=1" alt="Random landscape image">
        <div class="card-content">
          <h3>Card Title 1</h3>
          <p>This card layout adjusts the number of columns based on available space.</p>
        </div>
      </div>
      
      <div class="card">
        <img src="https://picsum.photos/400/180?random=2" alt="Random landscape image">
        <div class="card-content">
          <h3>Card Title 2</h3>
          <p>On mobile, cards stack vertically to maximize readability.</p>
        </div>
      </div>
      
      <div class="card">
        <img src="https://picsum.photos/400/180?random=3" alt="Random landscape image">
        <div class="card-content">
          <h3>Card Title 3</h3>
          <p>As the screen gets wider, more columns are added to use space efficiently.</p>
        </div>
      </div>
      
      <div class="card">
        <img src="https://picsum.photos/400/180?random=4" alt="Random landscape image">
        <div class="card-content">
          <h3>Card Title 4</h3>
          <p>On very large screens, we show even more columns for content.</p>
        </div>
      </div>
    </div>
  </section>
  
  <section class="typography">
    <h2>Responsive Typography</h2>
    <p>Text size and line height adjust based on screen size for optimal readability:</p>
    
    <div class="text-sample">
      <h2>Reading Experience Matters</h2>
      <p>On smaller screens, text is more compact to fit the limited space. As screens get larger, text size and line height increase to take advantage of the additional space and maintain readability. This provides an optimal reading experience across all devices.</p>
      <p>Notice how this paragraph changes in size and spacing as you resize your browser window. Good responsive design adapts typography appropriately for different reading contexts.</p>
    </div>
  </section>
</div>
---css
* {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

body {
	font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
	line-height: 1.6;
	color: #333;
	padding: 20px;
}

.container {
	max-width: 1200px;
	margin: 0 auto;
}

.demo-box {
	border-radius: 8px;
	padding: 2rem;
	margin: 2rem 0;
	transition: all 0.3s ease;
	position: relative;
}

.device-indicator {
	position: absolute;
	top: 0;
	right: 0;
	padding: 5px 10px;
	border-radius: 0 8px 0 8px;
	font-size: 12px;
	font-weight: bold;
	color: white;
}

/* Screen Width Indicator */
.width-display {
	text-align: center;
	font-size: 1.2rem;
	margin: 2rem 0;
	padding: 1rem;
	background-color: #f8f9fa;
	border-radius: 8px;
	box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

/* Card Layout Section */
.card-layout {
	margin-top: 3rem;
}

.cards {
	display: grid;
	gap: 1rem;
	grid-template-columns: 1fr;
	margin-top: 1.5rem;
}

.card {
	background-color: white;
	border-radius: 8px;
	overflow: hidden;
	box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
	transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.card img {
	width: 100%;
	height: 180px;
	object-fit: cover;
}

.card-content {
	padding: 1.5rem;
}

.card h3 {
	margin-bottom: 0.5rem;
	color: #2d3748;
}

.card p {
	color: #4a5568;
}

/* Typography Section */
.typography {
	margin-top: 3rem;
}

.text-sample {
	margin: 1.5rem 0;
	padding: 1.5rem;
	background-color: white;
	border-radius: 8px;
	box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}

.text-sample h2 {
	margin-bottom: 1rem;
}

/* Default Styles (Mobile First) */
.demo-box {
	background-color: #f56565;
}

.device-indicator {
	background-color: #c53030;
}

.device-indicator::after {
	content: "Mobile";
}

.text-sample h2 {
	font-size: 1.5rem;
}

.text-sample p {
	font-size: 1rem;
	line-height: 1.6;
}

h1 {
	font-size: 1.8rem;
}

h2 {
	font-size: 1.4rem;
}

/* Tablet Styles */
@media (min-width: 600px) {
	.demo-box {
		background-color: #ed8936;
	}

	.device-indicator {
		background-color: #c05621;
	}

	.device-indicator::after {
		content: "Tablet";
	}

	.cards {
		grid-template-columns: repeat(2, 1fr);
	}

	.text-sample h2 {
		font-size: 1.8rem;
	}

	.text-sample p {
		font-size: 1.1rem;
		line-height: 1.7;
	}

	h1 {
		font-size: 2.2rem;
	}

	h2 {
		font-size: 1.6rem;
	}
}

/* Desktop Styles */
@media (min-width: 900px) {
	.demo-box {
		background-color: #48bb78;
	}

	.device-indicator {
		background-color: #2f855a;
	}

	.device-indicator::after {
		content: "Desktop";
	}

	.cards {
		grid-template-columns: repeat(3, 1fr);
	}

	.text-sample h2 {
		font-size: 2rem;
	}

	.text-sample p {
		font-size: 1.15rem;
		line-height: 1.8;
	}

	h1 {
		font-size: 2.5rem;
	}

	h2 {
		font-size: 1.8rem;
	}
}

/* Large Desktop Styles */
@media (min-width: 1200px) {
	.demo-box {
		background-color: #4299e1;
	}

	.device-indicator {
		background-color: #2b6cb0;
	}

	.device-indicator::after {
		content: "Large Desktop";
	}

	.cards {
		grid-template-columns: repeat(4, 1fr);
	}

	.text-sample h2 {
		font-size: 2.2rem;
	}

	.text-sample p {
		font-size: 1.2rem;
		line-height: 1.9;
	}

	h1 {
		font-size: 2.8rem;
	}

	h2 {
		font-size: 2rem;
	}
}
---js
// Update width display in real-time
const widthDisplay = document.getElementById("width-value");

function updateWidth() {
  widthDisplay.textContent = window.innerWidth;
}

// Initial update
updateWidth();

// Update on resize
window.addEventListener("resize", updateWidth);

Enhancing Accessibility with Advanced CSS#

Color Contrast and Readability#

Good design is accessible design. Ensuring sufficient color contrast is critical for users with visual impairments. Use tools like the WebAIM Contrast Checker to verify that text and background colors meet WCAG guidelines: at least 4.5:1 for normal text and 3:1 for large text and interface parts.

body {
  background-color: #ffffff;
  color: #333333;
}

Focus Styles for Keyboard Navigation#

Clearly visible focus styles help keyboard users understand which element is active. Customize focus outlines to fit the design while remaining prominent.

a:focus, button:focus, input:focus {
  outline: 3px solid #FFD700; /* A bright, visible gold outline */
  outline-offset: 2px;
}

Accessibility isn't just about screen readers—it's also about keyboard navigation. This example demonstrates the critical importance of proper focus styles for interactive elements. Use your Tab key to navigate through the different examples and see the stark contrast between poor focus indicators (invisible or low-contrast) and accessible ones. Remember that many users rely entirely on keyboard navigation, making these visual cues essential.

Accessible Focus Styles
---html
<div class="container">
	<h1>Accessible Focus Styles</h1>

	<div class="intro">
		<h2>Why Focus Styles Matter</h2>
		<p>Focus indicators are essential for keyboard users, including people with motor disabilities, screen reader users, and power users who prefer keyboard navigation. A good focus style should be highly visible and provide clear feedback about the current interactive element.</p>
	</div>

	<div class="keyboard-instruction">
		<strong>Try it yourself:</strong> Press Tab to navigate through the interactive elements on this page and see the different focus styles in action.
	</div>

	<div class="focus-section">
		<h2>Poor vs. Better Focus Styles for Buttons</h2>
		<p>Compare these examples to see how different focus styles affect usability:</p>

		<div class="focus-demo">
			<button class="btn poor-focus no-focus-outline">No Focus Outline</button>
			<button class="btn poor-focus low-contrast-focus">Low Contrast Focus</button>
			<button class="btn better-focus high-contrast-outline">High Contrast Outline</button>
			<button class="btn better-focus custom-focus-style">Custom Focus Style</button>
		</div>

		<p>Notice how the first button has no visible focus indicator, making it impossible for keyboard users to know when it's focused. The second has such low contrast that it's difficult to see. The third and fourth provide clear, visible focus indicators.</p>
	</div>

	<div class="columns">
		<div class="focus-section">
			<h2>Link Focus Styles</h2>
			<p>Links are fundamental navigation elements that need clear focus states:</p>

			<div class="links-demo">
				<a href="#" class="link poor-link-focus">Poor link focus - No outline</a>
				<a href="#" class="link better-link-focus">Better link focus - Clear outline</a>
			</div>
		</div>

		<div class="focus-section">
			<h2>Form Control Focus</h2>
			<p>Form controls need clear focus indicators to guide users through forms:</p>

			<div class="form-controls">
				<div class="form-group">
					<label for="poor-input">Poor Input Focus:</label>
					<input type="text" id="poor-input" class="poor-input-focus" placeholder="No focus outline">
				</div>

				<div class="form-group">
					<label for="better-input">Better Input Focus:</label>
					<input type="text" id="better-input" class="better-input-focus" placeholder="Clear focus outline">
				</div>
			</div>
		</div>
	</div>

	<div class="focus-section">
		<h2>:focus-visible - The Modern Solution</h2>
		<p>The <code>:focus-visible</code> pseudo-class allows browsers to show focus styles only when they're needed (e.g., when navigating via keyboard, but not when clicking with a mouse):</p>

		<div class="focus-demo">
			<button class="btn better-focus focus-visible-demo">Try clicking and tabbing to me</button>
		</div>

		<p>Click the button first (no focus ring should appear), then try tabbing to it to see the focus ring appear. This provides the best of both worlds - keyboard accessibility without visually distracting mouse users.</p>
	</div>

	<div class="focus-section contrast-section">
		<h2>Color Contrast for Focus Indicators</h2>
		<p>Focus indicators must have sufficient contrast against various backgrounds:</p>

		<div class="contrast-examples">
			<div class="contrast-card light-bg">
				<h3>Light Background</h3>
				<button class="btn poor-focus poor-contrast-focus">Poor Contrast Focus</button>
				<button class="btn poor-focus good-contrast-focus">Good Contrast Focus</button>
			</div>

			<div class="contrast-card dark-bg">
				<h3>Dark Background</h3>
				<button class="btn poor-focus poor-contrast-focus">Poor Contrast Focus</button>
				<button class="btn poor-focus good-contrast-focus">Good Contrast Focus</button>
			</div>
		</div>

		<p>Focus indicators should maintain their visibility across different background colors. WCAG recommends a contrast ratio of at least 3:1 between the focus indicator and the background.</p>
	</div>
</div>
---css
* {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

body {
	font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
	line-height: 1.6;
	color: #333;
	padding: 20px;
	background-color: #f8f9fa;
}

.container {
	max-width: 800px;
	margin: 0 auto;
}

h1 {
	color: #2d3748;
	margin-bottom: 1rem;
	text-align: center;
}

.intro {
	background-color: #ebf8ff;
	padding: 1.5rem;
	border-radius: 8px;
	margin-bottom: 2rem;
	border-left: 5px solid #4299e1;
}

.intro h2 {
	color: #2b6cb0;
	margin-bottom: 0.5rem;
}

.focus-section {
	background-color: white;
	padding: 2rem;
	border-radius: 8px;
	box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
	margin-bottom: 2rem;
}

.focus-section h2 {
	margin-bottom: 1rem;
	color: #2d3748;
	border-bottom: 2px solid #e2e8f0;
	padding-bottom: 0.5rem;
}

.focus-demo {
	display: flex;
	flex-wrap: wrap;
	gap: 1.5rem;
	margin: 1.5rem 0;
}

.keyboard-instruction {
	background-color: #fffaf0;
	padding: 1rem;
	border-radius: 8px;
	margin-bottom: 1rem;
	border-left: 5px solid #ed8936;
}

.columns {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1.5rem;
}

@media (min-width: 768px) {
	.columns {
		grid-template-columns: 1fr 1fr;
	}
}

/* Default Button Styles */
.btn {
	padding: 0.75rem 1.5rem;
	border-radius: 4px;
	font-size: 1rem;
	cursor: pointer;
	transition: all 0.2s ease;
}

/* Poor Focus Examples */
.poor-focus {
	border: 1px solid #a0aec0;
	background-color: white;
	color: #4a5568;
}

.poor-focus:hover {
	background-color: #f7fafc;
}

.no-focus-outline:focus {
	outline: none;
}

.low-contrast-focus:focus {
	outline: 1px dotted #cbd5e0;
}

/* Better Focus Examples */
.better-focus {
	border: none;
	background-color: #4299e1;
	color: white;
}

.better-focus:hover {
	background-color: #3182ce;
}

.high-contrast-outline:focus {
	outline: 3px solid #f6ad55;
	outline-offset: 2px;
}

.custom-focus-style:focus {
	outline: none;
	box-shadow: 0 0 0 3px rgba(66, 153, 225, 0.6);
}

.focus-visible-demo:focus {
	outline: none;
}

.focus-visible-demo:focus-visible {
	outline: 3px solid #f6ad55;
	outline-offset: 2px;
}

/* Link Examples */
.links-demo {
	display: flex;
	flex-direction: column;
	gap: 1rem;
}

.link {
	color: #3182ce;
	text-decoration: underline;
	padding: 0.5rem;
	border-radius: 4px;
	display: inline-block;
}

.poor-link-focus:focus {
	outline: none;
}

.better-link-focus:focus {
	outline: 3px solid #f6ad55;
	outline-offset: 3px;
	text-decoration: none;
}

/* Form Controls */
.form-controls {
	display: flex;
	flex-direction: column;
	gap: 1.5rem;
}

.form-group {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
}

label {
	font-weight: bold;
	color: #4a5568;
}

input,
select {
	padding: 0.75rem;
	border-radius: 4px;
	border: 1px solid #cbd5e0;
	font-size: 1rem;
}

.poor-input-focus:focus {
	outline: none;
}

.better-input-focus:focus {
	outline: 3px solid #4299e1;
	outline-offset: 1px;
	border-color: #4299e1;
}

/* Color contrast for focus */
.contrast-section {
	margin-top: 2rem;
}

.contrast-examples {
	display: grid;
	grid-template-columns: 1fr;
	gap: 1rem;
	margin-top: 1rem;
}

@media (min-width: 768px) {
	.contrast-examples {
		grid-template-columns: 1fr 1fr;
	}
}

.contrast-card {
	padding: 1.5rem;
	border-radius: 8px;
	display: flex;
	flex-direction: column;
	gap: 1rem;
}

.light-bg {
	background-color: #f7fafc;
}

.dark-bg {
	background-color: #2d3748;
	color: white;
}

.poor-contrast-focus:focus {
	outline: 2px solid rgba(160, 174, 192, 0.5);
}

.good-contrast-focus:focus {
	outline: 3px solid #f6ad55;
	outline-offset: 2px;
}

Managing Typography and Spacing for Legibility#

Typography and spacing are key to readability. Using relative units like em and rem ensures that text scales based on user preferences. Consistent spacing and padding help create a visually harmonious layout that’s easier on the eyes.

Example:

body {
  font-size: 100%; /* the reader's own default, usually 16px */
  line-height: 1.6;
  margin: 0;
  padding: 0;
}

h1, h2, h3 {
  margin-bottom: 0.5em;
}

p {
  margin-bottom: 1em;
}

Using CSS custom properties (variables) can help maintain consistency across a design:

:root {
  --primary-color: #0056b3; /* 7:1 against white; #007BFF is only about 4:1 */
  --secondary-color: #333333;
  --base-font-size: 1rem;
}

body {
  font-size: var(--base-font-size);
  color: var(--secondary-color);
}

Real-World Example: A Responsive Web Layout#

Let’s put it all together with a sample layout that uses Flexbox, Grid, and media queries.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Responsive Web Layout</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <header class="flex-container">
    <h1>My Responsive Site</h1>
    <nav>
      <ul class="flex-container">
        <li><a href="#home">Home</a></li>
        <li><a href="#about">About</a></li>
        <li><a href="#services">Services</a></li>
      </ul>
    </nav>
  </header>

  <main class="grid-container">
    <article>
      <h2>Welcome</h2>
      <p>This is a sample responsive layout using advanced CSS techniques.</p>
    </article>
    <article>
      <h2>Our Work</h2>
      <p>We build accessible and responsive websites that adapt to any device.</p>
    </article>
    <article>
      <h2>Contact Us</h2>
      <p>Get in touch with us for more information.</p>
    </article>
  </main>

  <footer>
    <p>&copy; 2025 My Responsive Site. All rights reserved.</p>
  </footer>
</body>
</html>

And the accompanying CSS (styles.css):

/* Base Styles */
body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
  background-color: #ffffff;
  color: #333333;
}

header, nav, main, footer {
  padding: 1rem;
}

/* Flexbox for Header */
.flex-container {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

/* Responsive Grid for Main Content */
.grid-container {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 1rem;
  padding: 1rem;
}

/* Media Queries */
@media (min-width: 600px) {
  body {
    font-size: 18px;
  }
}

@media (min-width: 1024px) {
  body {
    font-size: 20px;
  }
}

/* Focus Styles */
a:focus, button:focus, input:focus {
  outline: 3px solid #FFD700;
  outline-offset: 2px;
}

This example demonstrates a responsive header using Flexbox, a main content area using CSS Grid, and adjustments for typography via media queries.


Conclusion#

Responsive design is how one page works across devices. By combining advanced CSS techniques like Flexbox, Grid, and media queries, we can create layouts that are both good to look at and accessible. Remember, a truly accessible design pays attention to color contrast, focus visibility, and readable typography. Embrace these techniques to build responsive, advanced web layouts that work for everyone.

Comments require JavaScript.