Responsive Design Principles

Week 1, Day 4 - Lecture 3

What is Responsive Design?

Responsive design is like water - it adapts to fill any container. Your website should look great and function perfectly whether viewed on a tiny phone or a giant desktop monitor. It's about creating flexible, adaptive experiences for all users.

graph TD A[Responsive Design] --> B[Fluid Grids] A --> C[Flexible Images] A --> D[Media Queries] B --> E[% based layouts] B --> F[Flexbox/Grid] C --> G[max-width: 100%] C --> H[srcset/picture] D --> I[Breakpoints] D --> J[Device targeting] style A fill:#f9f,stroke:#333,stroke-width:2px style B fill:#9cf,stroke:#333,stroke-width:2px style C fill:#fc9,stroke:#333,stroke-width:2px style D fill:#cf9,stroke:#333,stroke-width:2px

Why Responsive Design Matters

The Viewport Meta Tag

The viewport meta tag is like telling the browser "Hey, this site is responsive!" Without it, mobile browsers assume your site is desktop-only and zoom out.

<!-- Essential viewport meta tag -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<!-- With additional options -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

Viewport Options

Media Queries

Media queries are like conditional statements for CSS. They let you apply different styles based on device characteristics.

Basic Media Query Syntax

/* Basic media query */
@media screen and (max-width: 768px) {
    /* Styles for screens up to 768px wide */
    .container {
        width: 100%;
        padding: 10px;
    }
}

/* Min-width query */
@media screen and (min-width: 1024px) {
    /* Styles for screens 1024px and wider */
    .container {
        width: 1200px;
        margin: 0 auto;
    }
}

/* Range query */
@media screen and (min-width: 768px) and (max-width: 1023px) {
    /* Styles for tablets */
    .container {
        width: 90%;
    }
}

Common Breakpoints

/* Mobile first approach */
/* Base styles for mobile */
.container { width: 100%; }

/* Tablet */
@media screen and (min-width: 768px) {
    .container { width: 750px; }
}

/* Desktop */
@media screen and (min-width: 1024px) {
    .container { width: 960px; }
}

/* Large desktop */
@media screen and (min-width: 1200px) {
    .container { width: 1140px; }
}

Advanced Media Queries

/* Orientation */
@media screen and (orientation: landscape) {
    /* Landscape styles */
}

/* High resolution displays */
@media screen and (min-resolution: 2dppx) {
    /* Retina display styles */
}

/* Hover capability */
@media (hover: hover) {
    /* Styles for devices with hover */
    .button:hover {
        background-color: blue;
    }
}

/* Prefers reduced motion */
@media (prefers-reduced-motion: reduce) {
    * {
        animation: none !important;
        transition: none !important;
    }
}

/* Dark mode */
@media (prefers-color-scheme: dark) {
    body {
        background-color: #333;
        color: white;
    }
}

Mobile-First vs Desktop-First

graph TD A[Design Approach] --> B[Mobile-First] A --> C[Desktop-First] B --> D[Start small] B --> E[Progressive enhancement] B --> F[min-width queries] C --> G[Start large] C --> H[Graceful degradation] C --> I[max-width queries] style B fill:#9f9,stroke:#333,stroke-width:2px style C fill:#f99,stroke:#333,stroke-width:2px

Mobile-First Approach (Recommended)

/* Base styles (mobile) */
.card {
    padding: 10px;
    font-size: 14px;
}

/* Tablet and up */
@media (min-width: 768px) {
    .card {
        padding: 20px;
        font-size: 16px;
    }
}

/* Desktop and up */
@media (min-width: 1024px) {
    .card {
        padding: 30px;
        font-size: 18px;
    }
}

Desktop-First Approach

/* Base styles (desktop) */
.card {
    padding: 30px;
    font-size: 18px;
}

/* Tablet and down */
@media (max-width: 1023px) {
    .card {
        padding: 20px;
        font-size: 16px;
    }
}

/* Mobile */
@media (max-width: 767px) {
    .card {
        padding: 10px;
        font-size: 14px;
    }
}

Fluid Layouts

Percentage-Based Widths

/* Fluid container */
.container {
    width: 90%;
    max-width: 1200px;
    margin: 0 auto;
}

/* Fluid columns */
.column {
    width: 100%;
}

@media (min-width: 768px) {
    .column {
        width: 50%;
        float: left;
    }
}

@media (min-width: 1024px) {
    .column {
        width: 33.333%;
    }
}

Viewport Units

/* Viewport-relative sizing */
.hero {
    height: 100vh; /* Full viewport height */
    width: 100vw;  /* Full viewport width */
}

.section {
    min-height: 50vh; /* Minimum half viewport */
    padding: 5vw;     /* Viewport-relative padding */
}

/* Responsive typography */
h1 {
    font-size: 5vw; /* Scales with viewport */
    font-size: clamp(24px, 5vw, 48px); /* With limits */
}

Responsive Images

Basic Responsive Images

/* Make images responsive */
img {
    max-width: 100%;
    height: auto;
}

/* Background images */
.hero {
    background-image: url('hero.jpg');
    background-size: cover;
    background-position: center;
}

Srcset and Sizes

<!-- Responsive images with srcset -->
<img src="small.jpg"
     srcset="small.jpg 300w,
             medium.jpg 600w,
             large.jpg 1200w"
     sizes="(max-width: 600px) 100vw,
            (max-width: 1200px) 50vw,
            33vw"
     alt="Responsive image">

<!-- Picture element for art direction -->
<picture>
    <source media="(min-width: 1024px)" srcset="desktop.jpg">
    <source media="(min-width: 768px)" srcset="tablet.jpg">
    <img src="mobile.jpg" alt="Responsive image">
</picture>

Responsive Background Images

/* Media queries for background images */
.hero {
    background-image: url('hero-mobile.jpg');
}

@media (min-width: 768px) {
    .hero {
        background-image: url('hero-tablet.jpg');
    }
}

@media (min-width: 1024px) {
    .hero {
        background-image: url('hero-desktop.jpg');
    }
}

/* Using image-set() */
.hero {
    background-image: image-set(
        url('hero-1x.jpg') 1x,
        url('hero-2x.jpg') 2x
    );
}

Responsive Typography

Fluid Typography

/* Base font size */
html {
    font-size: 16px;
}

/* Responsive type scale */
h1 {
    font-size: 2rem; /* 32px */
}

@media (min-width: 768px) {
    h1 {
        font-size: 2.5rem; /* 40px */
    }
}

@media (min-width: 1024px) {
    h1 {
        font-size: 3rem; /* 48px */
    }
}

/* Fluid typography with calc() */
html {
    font-size: calc(16px + (24 - 16) * ((100vw - 320px) / (1200 - 320)));
}

/* Using clamp() for fluid typography */
h1 {
    font-size: clamp(1.5rem, 4vw, 3rem);
}

p {
    font-size: clamp(1rem, 2vw, 1.25rem);
    line-height: clamp(1.4, 2.5vw, 1.6);
}

Responsive Navigation

Mobile Navigation Pattern

/* Mobile navigation (hamburger menu) */
.nav {
    position: relative;
}

.nav-toggle {
    display: block;
    background: none;
    border: none;
    font-size: 1.5rem;
    cursor: pointer;
}

.nav-menu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    background: white;
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.nav-menu.active {
    display: block;
}

/* Desktop navigation */
@media (min-width: 768px) {
    .nav-toggle {
        display: none;
    }
    
    .nav-menu {
        display: flex;
        position: static;
        width: auto;
        background: none;
        box-shadow: none;
    }
    
    .nav-item {
        margin-left: 20px;
    }
}

JavaScript for Mobile Menu

// Toggle mobile menu
const navToggle = document.querySelector('.nav-toggle');
const navMenu = document.querySelector('.nav-menu');

navToggle.addEventListener('click', () => {
    navMenu.classList.toggle('active');
});

// Close menu when clicking outside
document.addEventListener('click', (e) => {
    if (!e.target.closest('.nav')) {
        navMenu.classList.remove('active');
    }
});

Responsive Tables

Scrollable Table

/* Horizontal scroll on small screens */
.table-container {
    overflow-x: auto;
}

table {
    min-width: 600px;
    width: 100%;
}

Stacked Table

/* Transform table for mobile */
@media (max-width: 600px) {
    table, thead, tbody, th, td, tr {
        display: block;
    }
    
    thead tr {
        position: absolute;
        top: -9999px;
        left: -9999px;
    }
    
    tr {
        border: 1px solid #ccc;
        margin-bottom: 10px;
    }
    
    td {
        border: none;
        position: relative;
        padding-left: 50%;
    }
    
    td:before {
        position: absolute;
        left: 6px;
        width: 45%;
        padding-right: 10px;
        white-space: nowrap;
        content: attr(data-label);
        font-weight: bold;
    }
}

<!-- HTML with data-label attributes -->
<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Phone</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td data-label="Name">John Doe</td>
            <td data-label="Email">john@example.com</td>
            <td data-label="Phone">555-1234</td>
        </tr>
    </tbody>
</table>

Performance Considerations

Responsive Images Performance

/* Lazy loading images */
<img src="placeholder.jpg"
     data-src="actual-image.jpg"
     loading="lazy"
     alt="Lazy loaded image">

/* Aspect ratio boxes for images */
.image-container {
    position: relative;
    padding-bottom: 56.25%; /* 16:9 aspect ratio */
}

.image-container img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

CSS Performance

/* Use CSS containment */
.card {
    contain: layout;
}

/* Avoid expensive properties in animations */
.animated {
    transform: translateX(100px); /* Good */
    /* left: 100px; */ /* Avoid */
}

/* Use will-change sparingly */
.will-animate {
    will-change: transform;
}

Testing Responsive Designs

Browser DevTools

Testing Checklist

Responsive Design Patterns

mindmap root((Responsive Patterns)) Layout Mostly Fluid Column Drop Layout Shifter Tiny Tweaks Off Canvas Navigation Priority Plus Hamburger Menu Dropdown Toggle Content Reflow Expand/Collapse Carousel Tabs to Accordion

Common Patterns Example

/* Mostly Fluid Pattern */
.container {
    margin: 0 auto;
    width: 100%;
}

@media (min-width: 600px) {
    .container {
        width: 90%;
        max-width: 960px;
    }
}

/* Column Drop Pattern */
.column {
    width: 100%;
}

@media (min-width: 600px) {
    .column {
        float: left;
        width: 50%;
    }
}

@media (min-width: 900px) {
    .column {
        width: 33.33%;
    }
}

Best Practices

mindmap root((Responsive Best Practices)) Planning Mobile-first approach Content hierarchy Performance budget Implementation Fluid grids Flexible images Media queries Touch-friendly Testing Real devices Different viewports Network conditions Accessibility Optimization Minimize HTTP requests Optimize images Critical CSS Lazy loading

Assignment: Responsive Website

  1. Create a responsive portfolio website:
    • Mobile-first approach
    • Responsive navigation (hamburger menu)
    • Fluid typography
    • Responsive images with srcset
    • At least 3 breakpoints
  2. Build a responsive dashboard:
    • Collapsible sidebar on mobile
    • Responsive tables
    • Card-based layout
    • Flexible charts/graphs
  3. Design a responsive e-commerce product page:
    • Responsive product gallery
    • Flexible product grid
    • Mobile-friendly checkout
    • Touch-friendly controls
  4. Create responsive email template:
    • Works in email clients
    • Fluid layout
    • Responsive images
    • Mobile-friendly buttons

Bonus: Implement a dark mode toggle using CSS custom properties and media queries!