📱 Responsive Design Implementation
Create themes that work perfectly on all devices
Master mobile-first development, flexible layouts, and responsive techniques
Learning Objectives
- Understand responsive design principles
- Implement mobile-first development
- Create flexible grid systems
- Master CSS media queries
- Handle responsive images and media
- Build responsive navigation menus
- Optimize typography for all screens
- Test and debug responsive layouts
Responsive Design Fundamentals
Responsive web design ensures your WordPress theme adapts seamlessly to different screen sizes, providing an optimal viewing experience across all devices - from mobile phones to desktop computers.
Key Principle
Three Pillars of Responsive Design
- Fluid Grids: Use relative units (%, em, rem, vw, vh) instead of fixed pixels
- Flexible Media: Images and videos that scale with their containers
- Media Queries: CSS rules that apply styles based on device characteristics
Viewport Configuration
Essential Viewport Meta Tag
<!-- In header.php -->
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- Additional responsive meta tags -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<?php wp_head(); ?>
</head>
Viewport Options Explained
- width=device-width: Sets viewport width to device width
- initial-scale=1.0: Sets initial zoom level
- maximum-scale=5.0: Maximum zoom allowed (accessibility)
- user-scalable=yes: Allow user to zoom (always yes for accessibility)
- viewport-fit=cover: For iPhone X and notched displays
Common Breakpoints
| Device | Breakpoint | CSS Media Query |
|---|---|---|
| Small phones | 320px - 480px | @media (min-width: 320px) |
| Phones | 481px - 768px | @media (min-width: 481px) |
| Tablets | 769px - 1024px | @media (min-width: 769px) |
| Desktop | 1025px - 1200px | @media (min-width: 1025px) |
| Large screens | 1201px+ | @media (min-width: 1201px) |
Sass Breakpoint Variables
// _variables.scss
// Breakpoints
$breakpoint-xs: 320px;
$breakpoint-sm: 576px;
$breakpoint-md: 768px;
$breakpoint-lg: 992px;
$breakpoint-xl: 1200px;
$breakpoint-xxl: 1400px;
// Breakpoint mixins
@mixin respond-to($breakpoint) {
@if $breakpoint == 'xs' {
@media (min-width: $breakpoint-xs) { @content; }
}
@else if $breakpoint == 'sm' {
@media (min-width: $breakpoint-sm) { @content; }
}
@else if $breakpoint == 'md' {
@media (min-width: $breakpoint-md) { @content; }
}
@else if $breakpoint == 'lg' {
@media (min-width: $breakpoint-lg) { @content; }
}
@else if $breakpoint == 'xl' {
@media (min-width: $breakpoint-xl) { @content; }
}
@else if $breakpoint == 'xxl' {
@media (min-width: $breakpoint-xxl) { @content; }
}
}
// Usage
.container {
padding: 1rem;
@include respond-to('md') {
padding: 2rem;
}
@include respond-to('lg') {
padding: 3rem;
}
}
Mobile-First Development
Why Mobile-First?
- Progressive enhancement approach
- Better performance on mobile devices
- Forces focus on essential content
- Easier to scale up than scale down
- Mobile traffic often exceeds desktop
Mobile-First CSS Structure
/* Base styles - Mobile first */
.content {
width: 100%;
padding: 1rem;
font-size: 1rem;
}
.sidebar {
width: 100%;
margin-top: 2rem;
}
/* Small devices (landscape phones, 576px and up) */
@media (min-width: 576px) {
.content {
padding: 1.5rem;
font-size: 1.1rem;
}
}
/* Medium devices (tablets, 768px and up) */
@media (min-width: 768px) {
.content {
width: 70%;
padding: 2rem;
}
.sidebar {
width: 30%;
margin-top: 0;
margin-left: 2rem;
}
.container {
display: flex;
}
}
/* Large devices (desktops, 992px and up) */
@media (min-width: 992px) {
.content {
width: 75%;
padding: 3rem;
font-size: 1.2rem;
}
.sidebar {
width: 25%;
}
}
/* Extra large devices (large desktops, 1200px and up) */
@media (min-width: 1200px) {
.container {
max-width: 1140px;
margin: 0 auto;
}
}
Flexible Grid Systems
CSS Grid Responsive Layout
/* CSS Grid - Responsive without media queries */
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
padding: 2rem;
}
/* Flexbox Grid System */
.row {
display: flex;
flex-wrap: wrap;
margin: -0.5rem;
}
.col {
flex: 1 1 100%;
padding: 0.5rem;
}
@media (min-width: 576px) {
.col-sm-6 { flex: 0 0 50%; }
.col-sm-4 { flex: 0 0 33.333%; }
.col-sm-3 { flex: 0 0 25%; }
}
@media (min-width: 768px) {
.col-md-6 { flex: 0 0 50%; }
.col-md-4 { flex: 0 0 33.333%; }
.col-md-3 { flex: 0 0 25%; }
.col-md-8 { flex: 0 0 66.666%; }
}
@media (min-width: 992px) {
.col-lg-6 { flex: 0 0 50%; }
.col-lg-4 { flex: 0 0 33.333%; }
.col-lg-3 { flex: 0 0 25%; }
.col-lg-9 { flex: 0 0 75%; }
}
Grid System Demo
Column 1
Column 2
Column 3
Resize your browser to see columns stack on mobile
Responsive Images in WordPress
WordPress Responsive Images
<?php
// WordPress automatically adds srcset and sizes attributes
the_post_thumbnail( 'large', array(
'class' => 'responsive-image',
'loading' => 'lazy',
'alt' => get_the_title()
) );
// Custom responsive image sizes
add_action( 'after_setup_theme', 'theme_image_sizes' );
function theme_image_sizes() {
// Add custom image sizes
add_image_size( 'mobile', 480, 320, true );
add_image_size( 'tablet', 768, 512, true );
add_image_size( 'desktop', 1200, 800, true );
add_image_size( 'retina', 2400, 1600, true );
}
// Customize srcset sizes
add_filter( 'wp_calculate_image_sizes', 'custom_image_sizes', 10, 2 );
function custom_image_sizes( $sizes, $size ) {
if ( $size[0] >= 1200 ) {
$sizes = '(max-width: 480px) 480px,
(max-width: 768px) 768px,
(max-width: 1200px) 1200px,
100vw';
}
return $sizes;
}
CSS for Responsive Images
/* Basic responsive images */
img {
max-width: 100%;
height: auto;
display: block;
}
/* Responsive background images */
.hero {
background-image: url('images/hero-mobile.jpg');
background-size: cover;
background-position: center;
min-height: 300px;
}
@media (min-width: 768px) {
.hero {
background-image: url('images/hero-tablet.jpg');
min-height: 400px;
}
}
@media (min-width: 1200px) {
.hero {
background-image: url('images/hero-desktop.jpg');
min-height: 600px;
}
}
@media (min-width: 1200px) and (-webkit-min-device-pixel-ratio: 2),
(min-width: 1200px) and (min-resolution: 192dpi) {
.hero {
background-image: url('images/hero-desktop@2x.jpg');
}
}
/* Art direction with picture element */
.responsive-image-container picture {
display: block;
}
.responsive-image-container img {
width: 100%;
height: auto;
object-fit: cover;
}
Picture Element for Art Direction
<picture>
<source media="(min-width: 1200px)"
srcset="large-desktop.jpg 1x, large-desktop@2x.jpg 2x">
<source media="(min-width: 768px)"
srcset="tablet.jpg 1x, tablet@2x.jpg 2x">
<source srcset="mobile.jpg 1x, mobile@2x.jpg 2x">
<img src="fallback.jpg" alt="Responsive image" loading="lazy">
</picture>
Responsive Typography
Fluid Typography with Clamp
/* Modern fluid typography */
:root {
--min-font-size: 1rem;
--max-font-size: 1.25rem;
--min-viewport: 320px;
--max-viewport: 1200px;
}
body {
font-size: clamp(1rem, 2vw + 0.5rem, 1.25rem);
line-height: 1.6;
}
h1 {
font-size: clamp(1.75rem, 5vw + 1rem, 3.5rem);
line-height: 1.2;
}
h2 {
font-size: clamp(1.5rem, 4vw + 0.5rem, 2.75rem);
line-height: 1.3;
}
h3 {
font-size: clamp(1.25rem, 3vw + 0.25rem, 2rem);
line-height: 1.4;
}
p {
font-size: clamp(1rem, 2vw, 1.125rem);
line-height: 1.6;
max-width: 65ch; /* Optimal reading length */
}
/* Responsive spacing */
.section {
padding: clamp(2rem, 5vw, 4rem) clamp(1rem, 3vw, 3rem);
}
/* Traditional approach with media queries */
@media (min-width: 768px) {
body { font-size: 1.125rem; }
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.5rem; }
}
@media (min-width: 1200px) {
body { font-size: 1.25rem; }
h1 { font-size: 3.5rem; }
h2 { font-size: 2.75rem; }
h3 { font-size: 2rem; }
}
Modern Techniques: Container Queries
CSS Container Queries (Modern Browsers)
/* Container queries for component-based responsive design */
.card-container {
container-type: inline-size;
container-name: card;
}
@container card (min-width: 400px) {
.card {
display: flex;
align-items: center;
}
.card-image {
width: 40%;
}
.card-content {
width: 60%;
padding-left: 1rem;
}
}
@container card (min-width: 600px) {
.card {
flex-direction: column;
}
.card-image,
.card-content {
width: 100%;
}
.card-content {
padding: 1rem;
}
}
Testing Responsive Designs
Testing Tools and Techniques
Browser DevTools
- Chrome DevTools Device Mode
- Firefox Responsive Design Mode
- Safari Responsive Design Mode
Online Testing Tools
- BrowserStack
- Responsinator
- Am I Responsive?
- Screenfly
Testing Checklist
- ✓ Test all major breakpoints
- ✓ Check both portrait and landscape orientations
- ✓ Test on real devices when possible
- ✓ Verify touch interactions work
- ✓ Check font readability at all sizes
- ✓ Test forms and interactive elements
- ✓ Verify images load appropriately
- ✓ Test with slow network speeds
WordPress Responsive Features
Responsive Embeds
<?php
// Enable responsive embeds
add_theme_support( 'responsive-embeds' );
// Add responsive wrapper to embeds
add_filter( 'embed_oembed_html', 'wrap_embed_with_div', 10, 3 );
function wrap_embed_with_div( $html, $url, $attr ) {
return '<div class="responsive-embed">' . $html . '</div>';
}
CSS for Responsive Embeds
/* Responsive video embeds */
.responsive-embed {
position: relative;
padding-bottom: 56.25%; /* 16:9 aspect ratio */
height: 0;
overflow: hidden;
}
.responsive-embed iframe,
.responsive-embed object,
.responsive-embed embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Best Practices
Responsive Design Best Practices
- Mobile-first approach: Start with mobile and enhance for larger screens
- Content priority: Focus on essential content for mobile users
- Touch-friendly: Ensure buttons and links are at least 44x44px
- Performance matters: Optimize images and resources for mobile
- Test early and often: Don't wait until the end to test responsiveness
- Avoid horizontal scrolling: Content should never overflow horizontally
- Use relative units: Prefer rem, em, %, vw/vh over pixels
- Flexible images: Always use max-width: 100% on images
- Accessible: Ensure responsive design doesn't break accessibility
- Progressive enhancement: Basic functionality should work everywhere
Never disable user zooming with user-scalable=no or maximum-scale=1. This creates accessibility issues for users who need to zoom.
Practice Exercise
Build a Responsive Theme Component