本章概述

响应式设计是现代Web开发的核心理念,Bootstrap采用移动优先的设计策略,确保网站在各种设备上都能提供优秀的用户体验。本章将深入探讨Bootstrap的响应式设计系统,包括断点系统、网格布局、响应式工具类以及移动优先的设计原则。

学习目标

  • 理解移动优先设计理念
  • 掌握Bootstrap断点系统
  • 学会使用响应式网格布局
  • 掌握响应式工具类的使用
  • 学会创建适配不同设备的界面
  • 了解响应式图片和媒体处理
  • 掌握响应式导航设计

Bootstrap断点系统

1. 断点定义

Bootstrap 5定义了6个主要断点,用于创建响应式布局:

// Bootstrap 5 断点
$grid-breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px,
  xxl: 1400px
);

2. 断点使用示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Bootstrap 断点系统</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .breakpoint-demo {
            padding: 1rem;
            margin: 0.5rem 0;
            border-radius: 0.375rem;
            text-align: center;
            font-weight: bold;
        }
        
        .xs-demo { background-color: #f8f9fa; }
        .sm-demo { background-color: #e9ecef; }
        .md-demo { background-color: #dee2e6; }
        .lg-demo { background-color: #ced4da; }
        .xl-demo { background-color: #adb5bd; }
        .xxl-demo { background-color: #6c757d; color: white; }
    </style>
</head>
<body>
    <div class="container my-5">
        <h2 class="text-primary mb-4">Bootstrap 断点系统演示</h2>
        
        <!-- 断点可视化 -->
        <div class="row">
            <div class="col-12">
                <div class="breakpoint-demo xs-demo d-block d-sm-none">
                    XS: 超小屏幕 (&lt; 576px)
                </div>
                <div class="breakpoint-demo sm-demo d-none d-sm-block d-md-none">
                    SM: 小屏幕 (≥ 576px)
                </div>
                <div class="breakpoint-demo md-demo d-none d-md-block d-lg-none">
                    MD: 中等屏幕 (≥ 768px)
                </div>
                <div class="breakpoint-demo lg-demo d-none d-lg-block d-xl-none">
                    LG: 大屏幕 (≥ 992px)
                </div>
                <div class="breakpoint-demo xl-demo d-none d-xl-block d-xxl-none">
                    XL: 超大屏幕 (≥ 1200px)
                </div>
                <div class="breakpoint-demo xxl-demo d-none d-xxl-block">
                    XXL: 超超大屏幕 (≥ 1400px)
                </div>
            </div>
        </div>
        
        <!-- 响应式列布局 -->
        <div class="mt-5">
            <h4>响应式列布局示例</h4>
            <div class="row">
                <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                    <div class="bg-primary text-white p-3 mb-3 text-center">
                        响应式列 1
                    </div>
                </div>
                <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                    <div class="bg-secondary text-white p-3 mb-3 text-center">
                        响应式列 2
                    </div>
                </div>
                <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                    <div class="bg-success text-white p-3 mb-3 text-center">
                        响应式列 3
                    </div>
                </div>
                <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                    <div class="bg-danger text-white p-3 mb-3 text-center">
                        响应式列 4
                    </div>
                </div>
                <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                    <div class="bg-warning text-dark p-3 mb-3 text-center">
                        响应式列 5
                    </div>
                </div>
                <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                    <div class="bg-info text-white p-3 mb-3 text-center">
                        响应式列 6
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

2. 响应式表单

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式表单</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .form-container {
            background: white;
            border-radius: 1rem;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
            overflow: hidden;
        }
        
        .form-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 2rem;
            text-align: center;
        }
        
        .form-step {
            display: none;
        }
        
        .form-step.active {
            display: block;
        }
        
        .step-indicator {
            display: flex;
            justify-content: center;
            margin-bottom: 2rem;
        }
        
        .step {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background: #e9ecef;
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 0 0.5rem;
            font-weight: bold;
            color: #6c757d;
            position: relative;
        }
        
        .step.active {
            background: #007bff;
            color: white;
        }
        
        .step.completed {
            background: #28a745;
            color: white;
        }
        
        .step:not(:last-child)::after {
            content: '';
            position: absolute;
            top: 50%;
            left: 100%;
            width: 2rem;
            height: 2px;
            background: #e9ecef;
            transform: translateY(-50%);
        }
        
        .step.completed:not(:last-child)::after {
            background: #28a745;
        }
        
        @media (max-width: 575.98px) {
            .form-header {
                padding: 1.5rem 1rem;
            }
            
            .step {
                width: 30px;
                height: 30px;
                font-size: 0.875rem;
                margin: 0 0.25rem;
            }
            
            .step:not(:last-child)::after {
                width: 1rem;
            }
        }
    </style>
</head>
<body>
    <div class="container my-5">
        <div class="row justify-content-center">
            <div class="col-12 col-md-8 col-lg-6">
                <div class="form-container">
                    <div class="form-header">
                        <h3 class="mb-2">用户注册</h3>
                        <p class="mb-0 opacity-75">请填写以下信息完成注册</p>
                    </div>
                    
                    <div class="p-4">
                        <!-- 步骤指示器 -->
                        <div class="step-indicator">
                            <div class="step active" data-step="1">1</div>
                            <div class="step" data-step="2">2</div>
                            <div class="step" data-step="3">3</div>
                        </div>
                        
                        <form id="registrationForm">
                            <!-- 第一步:基本信息 -->
                            <div class="form-step active" data-step="1">
                                <h5 class="mb-3">基本信息</h5>
                                
                                <div class="row">
                                    <div class="col-12 col-sm-6 mb-3">
                                        <label for="firstName" class="form-label">姓</label>
                                        <input type="text" class="form-control" id="firstName" required>
                                    </div>
                                    <div class="col-12 col-sm-6 mb-3">
                                        <label for="lastName" class="form-label">名</label>
                                        <input type="text" class="form-control" id="lastName" required>
                                    </div>
                                </div>
                                
                                <div class="mb-3">
                                    <label for="email" class="form-label">邮箱地址</label>
                                    <input type="email" class="form-control" id="email" required>
                                </div>
                                
                                <div class="mb-3">
                                    <label for="phone" class="form-label">手机号码</label>
                                    <input type="tel" class="form-control" id="phone" required>
                                </div>
                                
                                <div class="d-flex justify-content-end">
                                    <button type="button" class="btn btn-primary" onclick="nextStep()">下一步</button>
                                </div>
                            </div>
                            
                            <!-- 第二步:账户信息 -->
                            <div class="form-step" data-step="2">
                                <h5 class="mb-3">账户信息</h5>
                                
                                <div class="mb-3">
                                    <label for="username" class="form-label">用户名</label>
                                    <input type="text" class="form-control" id="username" required>
                                    <div class="form-text">用户名必须是3-20个字符</div>
                                </div>
                                
                                <div class="mb-3">
                                    <label for="password" class="form-label">密码</label>
                                    <input type="password" class="form-control" id="password" required>
                                    <div class="form-text">密码必须包含至少8个字符</div>
                                </div>
                                
                                <div class="mb-3">
                                    <label for="confirmPassword" class="form-label">确认密码</label>
                                    <input type="password" class="form-control" id="confirmPassword" required>
                                </div>
                                
                                <div class="d-flex justify-content-between">
                                    <button type="button" class="btn btn-outline-secondary" onclick="prevStep()">上一步</button>
                                    <button type="button" class="btn btn-primary" onclick="nextStep()">下一步</button>
                                </div>
                            </div>
                            
                            <!-- 第三步:个人偏好 -->
                            <div class="form-step" data-step="3">
                                <h5 class="mb-3">个人偏好</h5>
                                
                                <div class="mb-3">
                                    <label for="country" class="form-label">国家/地区</label>
                                    <select class="form-select" id="country" required>
                                        <option value="">请选择国家/地区</option>
                                        <option value="CN">中国</option>
                                        <option value="US">美国</option>
                                        <option value="JP">日本</option>
                                        <option value="KR">韩国</option>
                                    </select>
                                </div>
                                
                                <div class="mb-3">
                                    <label class="form-label">兴趣爱好</label>
                                    <div class="row">
                                        <div class="col-6 col-sm-4">
                                            <div class="form-check">
                                                <input class="form-check-input" type="checkbox" id="tech" value="tech">
                                                <label class="form-check-label" for="tech">科技</label>
                                            </div>
                                        </div>
                                        <div class="col-6 col-sm-4">
                                            <div class="form-check">
                                                <input class="form-check-input" type="checkbox" id="sports" value="sports">
                                                <label class="form-check-label" for="sports">运动</label>
                                            </div>
                                        </div>
                                        <div class="col-6 col-sm-4">
                                            <div class="form-check">
                                                <input class="form-check-input" type="checkbox" id="music" value="music">
                                                <label class="form-check-label" for="music">音乐</label>
                                            </div>
                                        </div>
                                        <div class="col-6 col-sm-4">
                                            <div class="form-check">
                                                <input class="form-check-input" type="checkbox" id="travel" value="travel">
                                                <label class="form-check-label" for="travel">旅行</label>
                                            </div>
                                        </div>
                                        <div class="col-6 col-sm-4">
                                            <div class="form-check">
                                                <input class="form-check-input" type="checkbox" id="reading" value="reading">
                                                <label class="form-check-label" for="reading">阅读</label>
                                            </div>
                                        </div>
                                        <div class="col-6 col-sm-4">
                                            <div class="form-check">
                                                <input class="form-check-input" type="checkbox" id="cooking" value="cooking">
                                                <label class="form-check-label" for="cooking">烹饪</label>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                
                                <div class="mb-3">
                                    <div class="form-check">
                                        <input class="form-check-input" type="checkbox" id="newsletter" value="newsletter">
                                        <label class="form-check-label" for="newsletter">
                                            订阅我们的新闻通讯
                                        </label>
                                    </div>
                                </div>
                                
                                <div class="mb-3">
                                    <div class="form-check">
                                        <input class="form-check-input" type="checkbox" id="terms" required>
                                        <label class="form-check-label" for="terms">
                                            我同意 <a href="#">服务条款</a> 和 <a href="#">隐私政策</a>
                                        </label>
                                    </div>
                                </div>
                                
                                <div class="d-flex justify-content-between">
                                    <button type="button" class="btn btn-outline-secondary" onclick="prevStep()">上一步</button>
                                    <button type="submit" class="btn btn-success">完成注册</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        let currentStep = 1;
        const totalSteps = 3;
        
        function showStep(step) {
            // 隐藏所有步骤
            document.querySelectorAll('.form-step').forEach(el => {
                el.classList.remove('active');
            });
            
            // 显示当前步骤
            document.querySelector(`[data-step="${step}"]`).classList.add('active');
            
            // 更新步骤指示器
            document.querySelectorAll('.step').forEach((el, index) => {
                const stepNumber = index + 1;
                el.classList.remove('active', 'completed');
                
                if (stepNumber < step) {
                    el.classList.add('completed');
                } else if (stepNumber === step) {
                    el.classList.add('active');
                }
            });
        }
        
        function nextStep() {
            if (validateCurrentStep() && currentStep < totalSteps) {
                currentStep++;
                showStep(currentStep);
            }
        }
        
        function prevStep() {
            if (currentStep > 1) {
                currentStep--;
                showStep(currentStep);
            }
        }
        
        function validateCurrentStep() {
            const currentStepElement = document.querySelector(`[data-step="${currentStep}"]`);
            const requiredFields = currentStepElement.querySelectorAll('[required]');
            
            for (let field of requiredFields) {
                if (!field.value.trim()) {
                    field.focus();
                    field.classList.add('is-invalid');
                    return false;
                } else {
                    field.classList.remove('is-invalid');
                    field.classList.add('is-valid');
                }
            }
            
            // 特殊验证:密码确认
            if (currentStep === 2) {
                const password = document.getElementById('password').value;
                const confirmPassword = document.getElementById('confirmPassword').value;
                
                if (password !== confirmPassword) {
                    document.getElementById('confirmPassword').classList.add('is-invalid');
                    alert('密码和确认密码不匹配');
                    return false;
                }
            }
            
            return true;
        }
        
        // 表单提交
        document.getElementById('registrationForm').addEventListener('submit', function(e) {
            e.preventDefault();
            
            if (validateCurrentStep()) {
                alert('注册成功!');
                // 这里可以添加实际的表单提交逻辑
            }
        });
        
        // 实时验证
        document.querySelectorAll('input, select').forEach(field => {
            field.addEventListener('blur', function() {
                if (this.hasAttribute('required') && !this.value.trim()) {
                    this.classList.add('is-invalid');
                    this.classList.remove('is-valid');
                } else {
                    this.classList.remove('is-invalid');
                    this.classList.add('is-valid');
                }
            });
        });
    </script>
</body>
</html>

响应式可访问性

1. 键盘导航支持

// 响应式键盘导航类
class ResponsiveKeyboardNavigation {
    constructor() {
        this.init();
    }
    
    init() {
        this.setupFocusManagement();
        this.setupSkipLinks();
        this.setupMobileNavigation();
        this.setupModalNavigation();
    }
    
    // 焦点管理
    setupFocusManagement() {
        // 为所有交互元素添加焦点样式
        const focusableElements = 'a, button, input, textarea, select, [tabindex]:not([tabindex="-1"])';
        
        document.querySelectorAll(focusableElements).forEach(element => {
            element.addEventListener('focus', function() {
                this.classList.add('keyboard-focus');
            });
            
            element.addEventListener('blur', function() {
                this.classList.remove('keyboard-focus');
            });
        });
        
        // 添加焦点样式
        const style = document.createElement('style');
        style.textContent = `
            .keyboard-focus {
                outline: 2px solid #007bff !important;
                outline-offset: 2px !important;
                box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25) !important;
            }
            
            @media (max-width: 767.98px) {
                .keyboard-focus {
                    outline-width: 3px !important;
                    outline-offset: 3px !important;
                }
            }
        `;
        document.head.appendChild(style);
    }
    
    // 跳转链接
    setupSkipLinks() {
        const skipLink = document.createElement('a');
        skipLink.href = '#main-content';
        skipLink.textContent = '跳转到主要内容';
        skipLink.className = 'skip-link';
        
        // 跳转链接样式
        const style = document.createElement('style');
        style.textContent = `
            .skip-link {
                position: absolute;
                top: -40px;
                left: 6px;
                background: #000;
                color: #fff;
                padding: 8px;
                text-decoration: none;
                z-index: 9999;
                border-radius: 4px;
            }
            
            .skip-link:focus {
                top: 6px;
            }
            
            @media (max-width: 767.98px) {
                .skip-link {
                    left: 10px;
                    padding: 12px;
                    font-size: 1.1rem;
                }
                
                .skip-link:focus {
                    top: 10px;
                }
            }
        `;
        document.head.appendChild(style);
        document.body.insertBefore(skipLink, document.body.firstChild);
    }
    
    // 移动端导航
    setupMobileNavigation() {
        const navToggle = document.querySelector('.navbar-toggler');
        const navMenu = document.querySelector('.navbar-collapse');
        
        if (navToggle && navMenu) {
            navToggle.addEventListener('keydown', (e) => {
                if (e.key === 'Enter' || e.key === ' ') {
                    e.preventDefault();
                    navToggle.click();
                }
            });
            
            // ESC 键关闭菜单
            document.addEventListener('keydown', (e) => {
                if (e.key === 'Escape' && navMenu.classList.contains('show')) {
                    navToggle.click();
                    navToggle.focus();
                }
            });
        }
    }
    
    // 模态框导航
    setupModalNavigation() {
        document.addEventListener('shown.bs.modal', (e) => {
            const modal = e.target;
            const focusableElements = modal.querySelectorAll(
                'a, button, input, textarea, select, [tabindex]:not([tabindex="-1"])'
            );
            
            if (focusableElements.length > 0) {
                focusableElements[0].focus();
            }
            
            // Tab 键循环
            modal.addEventListener('keydown', (e) => {
                if (e.key === 'Tab') {
                    const firstElement = focusableElements[0];
                    const lastElement = focusableElements[focusableElements.length - 1];
                    
                    if (e.shiftKey && document.activeElement === firstElement) {
                        e.preventDefault();
                        lastElement.focus();
                    } else if (!e.shiftKey && document.activeElement === lastElement) {
                        e.preventDefault();
                        firstElement.focus();
                    }
                }
            });
        });
    }
}

// 初始化键盘导航
new ResponsiveKeyboardNavigation();

2. ARIA 标签优化

<!-- 响应式导航栏 ARIA 优化 -->
<nav class="navbar navbar-expand-lg" role="navigation" aria-label="主导航">
    <div class="container">
        <a class="navbar-brand" href="#" aria-label="网站首页">
            <img src="logo.png" alt="公司标志" width="30" height="30">
            公司名称
        </a>
        
        <button class="navbar-toggler" 
                type="button" 
                data-bs-toggle="collapse" 
                data-bs-target="#navbarNav"
                aria-controls="navbarNav" 
                aria-expanded="false" 
                aria-label="切换导航菜单">
            <span class="navbar-toggler-icon" aria-hidden="true"></span>
        </button>
        
        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav" role="menubar">
                <li class="nav-item" role="none">
                    <a class="nav-link" href="#" role="menuitem" aria-current="page">首页</a>
                </li>
                <li class="nav-item dropdown" role="none">
                    <a class="nav-link dropdown-toggle" 
                       href="#" 
                       role="menuitem"
                       data-bs-toggle="dropdown" 
                       aria-expanded="false"
                       aria-haspopup="true">
                        产品
                    </a>
                    <ul class="dropdown-menu" role="menu" aria-labelledby="产品菜单">
                        <li role="none">
                            <a class="dropdown-item" href="#" role="menuitem">产品A</a>
                        </li>
                        <li role="none">
                            <a class="dropdown-item" href="#" role="menuitem">产品B</a>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
</nav>

<!-- 响应式表单 ARIA 优化 -->
<form role="form" aria-labelledby="form-title">
    <h2 id="form-title">用户注册表单</h2>
    
    <fieldset>
        <legend>基本信息</legend>
        
        <div class="mb-3">
            <label for="email" class="form-label">邮箱地址 *</label>
            <input type="email" 
                   class="form-control" 
                   id="email" 
                   required 
                   aria-required="true"
                   aria-describedby="email-help email-error">
            <div id="email-help" class="form-text">我们不会分享您的邮箱地址</div>
            <div id="email-error" class="invalid-feedback" aria-live="polite"></div>
        </div>
        
        <div class="mb-3">
            <label for="password" class="form-label">密码 *</label>
            <input type="password" 
                   class="form-control" 
                   id="password" 
                   required 
                   aria-required="true"
                   aria-describedby="password-help"
                   minlength="8">
            <div id="password-help" class="form-text">
                密码必须至少包含8个字符,包括字母和数字
            </div>
        </div>
    </fieldset>
    
    <fieldset>
        <legend>偏好设置</legend>
        
        <div class="mb-3" role="group" aria-labelledby="interests-label">
            <div id="interests-label" class="form-label">兴趣爱好</div>
            <div class="form-check">
                <input class="form-check-input" type="checkbox" id="tech" value="tech">
                <label class="form-check-label" for="tech">科技</label>
            </div>
            <div class="form-check">
                <input class="form-check-input" type="checkbox" id="sports" value="sports">
                <label class="form-check-label" for="sports">运动</label>
            </div>
        </div>
    </fieldset>
    
    <button type="submit" class="btn btn-primary" aria-describedby="submit-help">
        提交注册
    </button>
    <div id="submit-help" class="form-text">
        点击提交即表示您同意我们的服务条款
    </div>
</form>

<!-- 响应式表格 ARIA 优化 -->
<div class="table-responsive" role="region" aria-labelledby="table-title" tabindex="0">
    <h3 id="table-title">用户数据表</h3>
    <table class="table" role="table">
        <caption class="visually-hidden">用户信息列表,包含姓名、邮箱、状态等信息</caption>
        <thead>
            <tr role="row">
                <th scope="col" role="columnheader">姓名</th>
                <th scope="col" role="columnheader">邮箱</th>
                <th scope="col" role="columnheader">状态</th>
                <th scope="col" role="columnheader">操作</th>
            </tr>
        </thead>
        <tbody>
            <tr role="row">
                <td role="cell">张三</td>
                <td role="cell">zhangsan@example.com</td>
                <td role="cell">
                    <span class="badge bg-success" aria-label="状态:活跃">活跃</span>
                </td>
                <td role="cell">
                    <button class="btn btn-sm btn-outline-primary" aria-label="编辑张三的信息">
                        编辑
                    </button>
                    <button class="btn btn-sm btn-outline-danger" aria-label="删除张三的账户">
                        删除
                    </button>
                </td>
            </tr>
        </tbody>
    </table>
</div>

性能优化建议

1. 响应式图片优化

<!-- 响应式图片优化 -->
<picture>
    <!-- 移动端优化图片 -->
    <source media="(max-width: 575px)" 
            srcset="image-mobile-320w.webp 320w,
                    image-mobile-480w.webp 480w"
            sizes="100vw"
            type="image/webp">
    
    <!-- 平板端优化图片 -->
    <source media="(max-width: 991px)" 
            srcset="image-tablet-768w.webp 768w,
                    image-tablet-1024w.webp 1024w"
            sizes="100vw"
            type="image/webp">
    
    <!-- 桌面端优化图片 -->
    <source media="(min-width: 992px)" 
            srcset="image-desktop-1200w.webp 1200w,
                    image-desktop-1920w.webp 1920w"
            sizes="100vw"
            type="image/webp">
    
    <!-- 回退图片 -->
    <img src="image-fallback.jpg" 
         alt="产品图片" 
         class="img-fluid"
         loading="lazy"
         decoding="async">
</picture>

<!-- 背景图片优化 -->
<div class="hero-section" 
     data-bg-mobile="hero-mobile.webp"
     data-bg-tablet="hero-tablet.webp"
     data-bg-desktop="hero-desktop.webp">
    <div class="container">
        <h1>响应式背景图片</h1>
    </div>
</div>

<script>
// 响应式背景图片加载
function loadResponsiveBackground() {
    const elements = document.querySelectorAll('[data-bg-mobile]');
    
    elements.forEach(element => {
        let bgImage;
        
        if (window.innerWidth <= 575) {
            bgImage = element.dataset.bgMobile;
        } else if (window.innerWidth <= 991) {
            bgImage = element.dataset.bgTablet;
        } else {
            bgImage = element.dataset.bgDesktop;
        }
        
        if (bgImage) {
            const img = new Image();
            img.onload = () => {
                element.style.backgroundImage = `url(${bgImage})`;
            };
            img.src = bgImage;
        }
    });
}

// 初始加载和窗口大小改变时重新加载
loadResponsiveBackground();
window.addEventListener('resize', debounce(loadResponsiveBackground, 250));

// 防抖函数
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}
</script>

2. CSS 优化

/* 关键 CSS 内联优化 */
/* 将首屏关键样式内联到 HTML 中 */
<style>
/* 关键路径 CSS */
.container {
    width: 100%;
    padding-right: 15px;
    padding-left: 15px;
    margin-right: auto;
    margin-left: auto;
}

@media (min-width: 576px) {
    .container {
        max-width: 540px;
    }
}

@media (min-width: 768px) {
    .container {
        max-width: 720px;
    }
}

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

@media (min-width: 1200px) {
    .container {
        max-width: 1140px;
    }
}

/* 首屏内容样式 */
.hero-section {
    min-height: 100vh;
    display: flex;
    align-items: center;
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
}

.btn {
    display: inline-block;
    padding: 0.375rem 0.75rem;
    font-size: 1rem;
    line-height: 1.5;
    border-radius: 0.375rem;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
}

.btn-primary {
    background-color: #007bff;
    border-color: #007bff;
    color: #fff;
}
</style>

/* 非关键 CSS 异步加载 */
<link rel="preload" href="bootstrap.min.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="bootstrap.min.css"></noscript>

3. JavaScript 优化

// 响应式组件懒加载
class ResponsiveLazyLoader {
    constructor() {
        this.components = new Map();
        this.observer = null;
        this.init();
    }
    
    init() {
        // 创建 Intersection Observer
        this.observer = new IntersectionObserver(
            this.handleIntersection.bind(this),
            {
                rootMargin: '50px',
                threshold: 0.1
            }
        );
        
        // 注册组件
        this.registerComponents();
        
        // 监听窗口大小变化
        window.addEventListener('resize', 
            this.debounce(this.handleResize.bind(this), 250)
        );
    }
    
    registerComponents() {
        // 注册轮播图组件
        this.components.set('carousel', {
            selector: '[data-lazy="carousel"]',
            mobile: () => import('./components/mobile-carousel.js'),
            desktop: () => import('./components/desktop-carousel.js')
        });
        
        // 注册图表组件
        this.components.set('chart', {
            selector: '[data-lazy="chart"]',
            mobile: () => import('./components/mobile-chart.js'),
            desktop: () => import('./components/desktop-chart.js')
        });
        
        // 注册数据表格组件
        this.components.set('datatable', {
            selector: '[data-lazy="datatable"]',
            mobile: () => import('./components/mobile-table.js'),
            desktop: () => import('./components/desktop-table.js')
        });
        
        // 开始观察所有组件
        this.observeComponents();
    }
    
    observeComponents() {
        this.components.forEach((config, name) => {
            const elements = document.querySelectorAll(config.selector);
            elements.forEach(element => {
                element.dataset.componentName = name;
                this.observer.observe(element);
            });
        });
    }
    
    async handleIntersection(entries) {
        for (const entry of entries) {
            if (entry.isIntersecting) {
                const element = entry.target;
                const componentName = element.dataset.componentName;
                const config = this.components.get(componentName);
                
                if (config && !element.dataset.loaded) {
                    await this.loadComponent(element, config);
                    element.dataset.loaded = 'true';
                    this.observer.unobserve(element);
                }
            }
        }
    }
    
    async loadComponent(element, config) {
        try {
            // 显示加载指示器
            this.showLoadingIndicator(element);
            
            // 根据屏幕尺寸选择合适的组件
            const isMobile = window.innerWidth < 768;
            const moduleLoader = isMobile ? config.mobile : config.desktop;
            
            // 动态导入组件
            const module = await moduleLoader();
            const Component = module.default;
            
            // 初始化组件
            new Component(element);
            
            // 隐藏加载指示器
            this.hideLoadingIndicator(element);
            
        } catch (error) {
            console.error(`Failed to load component:`, error);
            this.showErrorIndicator(element);
        }
    }
    
    showLoadingIndicator(element) {
        const indicator = document.createElement('div');
        indicator.className = 'loading-indicator';
        indicator.innerHTML = `
            <div class="spinner-border" role="status">
                <span class="visually-hidden">加载中...</span>
            </div>
        `;
        element.appendChild(indicator);
    }
    
    hideLoadingIndicator(element) {
        const indicator = element.querySelector('.loading-indicator');
        if (indicator) {
            indicator.remove();
        }
    }
    
    showErrorIndicator(element) {
        const indicator = element.querySelector('.loading-indicator');
        if (indicator) {
            indicator.innerHTML = `
                <div class="alert alert-warning" role="alert">
                    <i class="bi bi-exclamation-triangle"></i>
                    组件加载失败,请刷新页面重试
                </div>
            `;
        }
    }
    
    handleResize() {
        // 窗口大小改变时重新评估组件
        const loadedElements = document.querySelectorAll('[data-loaded="true"]');
        
        loadedElements.forEach(async element => {
            const componentName = element.dataset.componentName;
            const config = this.components.get(componentName);
            
            if (config) {
                // 清除当前组件
                element.innerHTML = '';
                element.dataset.loaded = 'false';
                
                // 重新加载适合当前屏幕尺寸的组件
                await this.loadComponent(element, config);
                element.dataset.loaded = 'true';
            }
        });
    }
    
    debounce(func, wait) {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }
}

// 初始化懒加载器
const lazyLoader = new ResponsiveLazyLoader();

// 预加载关键资源
class ResourcePreloader {
    constructor() {
        this.preloadCriticalResources();
    }
    
    preloadCriticalResources() {
        // 预加载关键字体
        this.preloadFont('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
        
        // 预加载关键图片
        this.preloadImage('/images/hero-background.webp');
        
        // 预加载关键 JavaScript
        this.preloadScript('/js/critical.js');
    }
    
    preloadFont(href) {
        const link = document.createElement('link');
        link.rel = 'preload';
        link.as = 'style';
        link.href = href;
        link.onload = () => {
            link.rel = 'stylesheet';
        };
        document.head.appendChild(link);
    }
    
    preloadImage(src) {
        const link = document.createElement('link');
        link.rel = 'preload';
        link.as = 'image';
        link.href = src;
        document.head.appendChild(link);
    }
    
    preloadScript(src) {
        const link = document.createElement('link');
        link.rel = 'preload';
        link.as = 'script';
        link.href = src;
        document.head.appendChild(link);
    }
}

// 初始化资源预加载器
new ResourcePreloader();

本章总结

在本章中,我们深入学习了 Bootstrap 的响应式设计与移动优先原则:

核心概念

  1. 断点系统:掌握了 Bootstrap 的五个断点及其应用
  2. 移动优先:理解了从小屏幕开始设计的重要性
  3. 响应式网格:学会了创建灵活的布局系统
  4. 工具类:掌握了响应式显示、对齐、间距等工具类

实践技能

  1. 响应式导航:创建了适应不同屏幕的导航系统
  2. 响应式表格:实现了桌面表格和移动卡片的切换
  3. 响应式表单:设计了多步骤的响应式表单
  4. 响应式图片:优化了不同设备的图片加载

高级技术

  1. 自定义断点:学会了扩展 Bootstrap 的断点系统
  2. 可访问性:实现了键盘导航和 ARIA 标签优化
  3. 性能优化:掌握了懒加载和资源预加载技术

最佳实践

  1. 始终采用移动优先的设计思路
  2. 合理使用断点,避免过度复杂化
  3. 注重可访问性和用户体验
  4. 优化性能,特别是移动端的加载速度
  5. 测试不同设备和屏幕尺寸的显示效果

响应式设计是现代 Web 开发的基础,通过本章的学习,您已经掌握了使用 Bootstrap 创建优秀响应式网站的核心技能。

练习题

基础练习

  1. 创建一个响应式的产品展示页面,包含网格布局和卡片组件
  2. 实现一个响应式的联系表单,在移动端使用步骤式设计
  3. 设计一个响应式的图片画廊,支持不同尺寸的图片显示

进阶练习

  1. 创建一个完整的响应式电商网站首页
  2. 实现一个响应式的后台管理界面
  3. 设计一个支持多种设备的在线学习平台

挑战练习

  1. 创建一个自定义的响应式组件库
  2. 实现一个高性能的响应式图片懒加载系统
  3. 设计一个完全可访问的响应式 Web 应用

通过这些练习,您将能够熟练运用 Bootstrap 的响应式设计功能,创建出适应各种设备的优秀网站。

移动优先设计原则

1. 移动优先CSS

/* 移动优先设计示例 */

/* 基础样式(移动设备) */
.mobile-first-card {
    padding: 1rem;
    margin-bottom: 1rem;
    background-color: #f8f9fa;
    border-radius: 0.375rem;
    text-align: center;
}

.mobile-first-card h3 {
    font-size: 1.25rem;
    margin-bottom: 0.5rem;
}

.mobile-first-card p {
    font-size: 0.875rem;
    line-height: 1.4;
}

/* 小屏幕及以上 */
@media (min-width: 576px) {
    .mobile-first-card {
        padding: 1.5rem;
        text-align: left;
    }
    
    .mobile-first-card h3 {
        font-size: 1.5rem;
    }
    
    .mobile-first-card p {
        font-size: 1rem;
    }
}

/* 中等屏幕及以上 */
@media (min-width: 768px) {
    .mobile-first-card {
        padding: 2rem;
        display: flex;
        align-items: center;
    }
    
    .mobile-first-card h3 {
        font-size: 1.75rem;
        margin-right: 1rem;
        margin-bottom: 0;
        flex-shrink: 0;
    }
}

/* 大屏幕及以上 */
@media (min-width: 992px) {
    .mobile-first-card {
        padding: 2.5rem;
    }
    
    .mobile-first-card h3 {
        font-size: 2rem;
    }
    
    .mobile-first-card p {
        font-size: 1.125rem;
    }
}

2. 移动优先布局示例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>移动优先设计</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .mobile-first-demo {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            min-height: 100vh;
        }
        
        .feature-card {
            background: rgba(255, 255, 255, 0.1);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.2);
            border-radius: 1rem;
            padding: 2rem;
            margin-bottom: 1.5rem;
            transition: transform 0.3s ease;
        }
        
        .feature-card:hover {
            transform: translateY(-5px);
        }
        
        .feature-icon {
            width: 60px;
            height: 60px;
            background: rgba(255, 255, 255, 0.2);
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 0 auto 1rem;
            font-size: 1.5rem;
        }
        
        @media (min-width: 768px) {
            .feature-icon {
                margin: 0 0 1rem 0;
            }
        }
    </style>
</head>
<body>
    <div class="mobile-first-demo">
        <div class="container py-5">
            <!-- 头部区域 -->
            <div class="row justify-content-center text-center mb-5">
                <div class="col-12 col-md-8 col-lg-6">
                    <h1 class="display-4 fw-bold mb-3">移动优先设计</h1>
                    <p class="lead">从小屏幕开始设计,逐步增强到大屏幕体验</p>
                </div>
            </div>
            
            <!-- 特性展示 -->
            <div class="row">
                <div class="col-12 col-md-6 col-lg-4">
                    <div class="feature-card text-center text-md-start">
                        <div class="feature-icon">
                            📱
                        </div>
                        <h3 class="h4 mb-3">移动优先</h3>
                        <p>从最小的屏幕开始设计,确保核心功能在所有设备上都能正常工作。</p>
                    </div>
                </div>
                
                <div class="col-12 col-md-6 col-lg-4">
                    <div class="feature-card text-center text-md-start">
                        <div class="feature-icon">
                            🎨
                        </div>
                        <h3 class="h4 mb-3">渐进增强</h3>
                        <p>随着屏幕尺寸增大,逐步添加更多功能和视觉效果。</p>
                    </div>
                </div>
                
                <div class="col-12 col-md-6 col-lg-4">
                    <div class="feature-card text-center text-md-start">
                        <div class="feature-icon">
                            ⚡
                        </div>
                        <h3 class="h4 mb-3">性能优化</h3>
                        <p>优先考虑移动设备的性能限制,确保快速加载和流畅体验。</p>
                    </div>
                </div>
                
                <div class="col-12 col-md-6 col-lg-4">
                    <div class="feature-card text-center text-md-start">
                        <div class="feature-icon">
                            🔧
                        </div>
                        <h3 class="h4 mb-3">灵活布局</h3>
                        <p>使用弹性网格系统,适应各种屏幕尺寸和设备方向。</p>
                    </div>
                </div>
                
                <div class="col-12 col-md-6 col-lg-4">
                    <div class="feature-card text-center text-md-start">
                        <div class="feature-icon">
                            👆
                        </div>
                        <h3 class="h4 mb-3">触摸友好</h3>
                        <p>设计适合触摸操作的界面元素,提供良好的移动交互体验。</p>
                    </div>
                </div>
                
                <div class="col-12 col-md-6 col-lg-4">
                    <div class="feature-card text-center text-md-start">
                        <div class="feature-icon">
                            🌐
                        </div>
                        <h3 class="h4 mb-3">跨平台</h3>
                        <p>确保在不同操作系统和浏览器上都能提供一致的用户体验。</p>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

响应式网格系统

1. 基础网格布局

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式网格系统</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .grid-demo {
            background-color: #f8f9fa;
            border: 1px solid #dee2e6;
            padding: 1rem;
            margin-bottom: 1rem;
            text-align: center;
            border-radius: 0.375rem;
        }
        
        .grid-demo-primary { background-color: #cfe2ff; border-color: #b6d7ff; }
        .grid-demo-secondary { background-color: #e2e3e5; border-color: #d3d3d4; }
        .grid-demo-success { background-color: #d1e7dd; border-color: #badbcc; }
        .grid-demo-danger { background-color: #f8d7da; border-color: #f5c2c7; }
        .grid-demo-warning { background-color: #fff3cd; border-color: #ffecb5; }
        .grid-demo-info { background-color: #d1ecf1; border-color: #bee5eb; }
    </style>
</head>
<body>
    <div class="container my-5">
        <h2 class="text-primary mb-4">响应式网格系统</h2>
        
        <!-- 等宽列 -->
        <div class="mb-5">
            <h4>等宽列</h4>
            <div class="row">
                <div class="col">
                    <div class="grid-demo grid-demo-primary">col</div>
                </div>
                <div class="col">
                    <div class="grid-demo grid-demo-secondary">col</div>
                </div>
                <div class="col">
                    <div class="grid-demo grid-demo-success">col</div>
                </div>
            </div>
        </div>
        
        <!-- 指定宽度列 -->
        <div class="mb-5">
            <h4>指定宽度列</h4>
            <div class="row">
                <div class="col-4">
                    <div class="grid-demo grid-demo-primary">col-4</div>
                </div>
                <div class="col-8">
                    <div class="grid-demo grid-demo-secondary">col-8</div>
                </div>
            </div>
            <div class="row">
                <div class="col-6">
                    <div class="grid-demo grid-demo-success">col-6</div>
                </div>
                <div class="col-6">
                    <div class="grid-demo grid-demo-danger">col-6</div>
                </div>
            </div>
        </div>
        
        <!-- 响应式列 -->
        <div class="mb-5">
            <h4>响应式列</h4>
            <div class="row">
                <div class="col-12 col-sm-6 col-md-4 col-lg-3">
                    <div class="grid-demo grid-demo-primary">
                        <small>XS: 12</small><br>
                        <small>SM: 6</small><br>
                        <small>MD: 4</small><br>
                        <small>LG: 3</small>
                    </div>
                </div>
                <div class="col-12 col-sm-6 col-md-4 col-lg-3">
                    <div class="grid-demo grid-demo-secondary">
                        <small>XS: 12</small><br>
                        <small>SM: 6</small><br>
                        <small>MD: 4</small><br>
                        <small>LG: 3</small>
                    </div>
                </div>
                <div class="col-12 col-sm-6 col-md-4 col-lg-3">
                    <div class="grid-demo grid-demo-success">
                        <small>XS: 12</small><br>
                        <small>SM: 6</small><br>
                        <small>MD: 4</small><br>
                        <small>LG: 3</small>
                    </div>
                </div>
                <div class="col-12 col-sm-6 col-md-4 col-lg-3">
                    <div class="grid-demo grid-demo-danger">
                        <small>XS: 12</small><br>
                        <small>SM: 6</small><br>
                        <small>MD: 4</small><br>
                        <small>LG: 3</small>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 列偏移 -->
        <div class="mb-5">
            <h4>列偏移</h4>
            <div class="row">
                <div class="col-4">
                    <div class="grid-demo grid-demo-primary">col-4</div>
                </div>
                <div class="col-4 offset-4">
                    <div class="grid-demo grid-demo-secondary">col-4 offset-4</div>
                </div>
            </div>
            <div class="row">
                <div class="col-3 offset-3">
                    <div class="grid-demo grid-demo-success">col-3 offset-3</div>
                </div>
                <div class="col-3 offset-3">
                    <div class="grid-demo grid-demo-danger">col-3 offset-3</div>
                </div>
            </div>
        </div>
        
        <!-- 响应式偏移 -->
        <div class="mb-5">
            <h4>响应式偏移</h4>
            <div class="row">
                <div class="col-12 col-sm-6 col-md-4 offset-md-4 col-lg-3 offset-lg-3">
                    <div class="grid-demo grid-demo-warning">
                        响应式偏移列
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 嵌套网格 -->
        <div class="mb-5">
            <h4>嵌套网格</h4>
            <div class="row">
                <div class="col-12 col-md-8">
                    <div class="grid-demo grid-demo-primary">
                        主要内容区域
                        <div class="row mt-2">
                            <div class="col-6">
                                <div class="grid-demo grid-demo-info">嵌套 1</div>
                            </div>
                            <div class="col-6">
                                <div class="grid-demo grid-demo-info">嵌套 2</div>
                            </div>
                        </div>
                    </div>
                </div>
                <div class="col-12 col-md-4">
                    <div class="grid-demo grid-demo-secondary">
                        侧边栏
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

2. 复杂网格布局

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>复杂网格布局</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .layout-section {
            min-height: 200px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 0.5rem;
            margin-bottom: 1rem;
            color: white;
            font-weight: bold;
            text-align: center;
        }
        
        .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); }
        .sidebar { background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); }
        .main-content { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); }
        .footer { background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); }
        .widget { background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); }
    </style>
</head>
<body>
    <div class="container-fluid my-4">
        <h2 class="text-primary mb-4 text-center">复杂响应式布局示例</h2>
        
        <!-- 经典三栏布局 -->
        <div class="row mb-5">
            <div class="col-12">
                <h4>经典三栏布局</h4>
            </div>
            
            <!-- 头部 -->
            <div class="col-12">
                <div class="layout-section header">
                    网站头部 (Header)
                </div>
            </div>
            
            <!-- 主要内容区域 -->
            <div class="col-12 col-lg-3 order-lg-1">
                <div class="layout-section sidebar">
                    左侧边栏<br>
                    <small>(在移动端显示在底部)</small>
                </div>
            </div>
            
            <div class="col-12 col-lg-6 order-lg-2">
                <div class="layout-section main-content">
                    主要内容区域<br>
                    <small>(响应式调整宽度)</small>
                </div>
            </div>
            
            <div class="col-12 col-lg-3 order-lg-3">
                <div class="layout-section sidebar">
                    右侧边栏<br>
                    <small>(在移动端显示在底部)</small>
                </div>
            </div>
            
            <!-- 底部 -->
            <div class="col-12 order-lg-4">
                <div class="layout-section footer">
                    网站底部 (Footer)
                </div>
            </div>
        </div>
        
        <!-- 卡片网格布局 -->
        <div class="row mb-5">
            <div class="col-12">
                <h4>卡片网格布局</h4>
            </div>
            
            <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                <div class="layout-section widget" style="min-height: 150px;">
                    卡片 1
                </div>
            </div>
            
            <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                <div class="layout-section widget" style="min-height: 150px;">
                    卡片 2
                </div>
            </div>
            
            <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                <div class="layout-section widget" style="min-height: 150px;">
                    卡片 3
                </div>
            </div>
            
            <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                <div class="layout-section widget" style="min-height: 150px;">
                    卡片 4
                </div>
            </div>
            
            <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                <div class="layout-section widget" style="min-height: 150px;">
                    卡片 5
                </div>
            </div>
            
            <div class="col-12 col-sm-6 col-md-4 col-lg-3 col-xl-2">
                <div class="layout-section widget" style="min-height: 150px;">
                    卡片 6
                </div>
            </div>
        </div>
        
        <!-- 不等高列布局 -->
        <div class="row mb-5">
            <div class="col-12">
                <h4>不等高列布局</h4>
            </div>
            
            <div class="col-12 col-md-8">
                <div class="layout-section main-content" style="min-height: 300px;">
                    主要内容区域<br>
                    <small>较高的内容区域</small>
                </div>
            </div>
            
            <div class="col-12 col-md-4">
                <div class="row">
                    <div class="col-12">
                        <div class="layout-section sidebar" style="min-height: 140px;">
                            侧边栏 1
                        </div>
                    </div>
                    <div class="col-12">
                        <div class="layout-section widget" style="min-height: 140px;">
                            侧边栏 2
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

响应式工具类

1. 显示和隐藏工具类

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式工具类</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .utility-demo {
            padding: 1rem;
            margin: 0.5rem 0;
            border-radius: 0.375rem;
            text-align: center;
            font-weight: bold;
            border: 2px solid;
        }
        
        .demo-primary {
            background-color: #cfe2ff;
            border-color: #0d6efd;
            color: #0d6efd;
        }
        
        .demo-success {
            background-color: #d1e7dd;
            border-color: #198754;
            color: #198754;
        }
        
        .demo-warning {
            background-color: #fff3cd;
            border-color: #ffc107;
            color: #664d03;
        }
        
        .demo-danger {
            background-color: #f8d7da;
            border-color: #dc3545;
            color: #dc3545;
        }
    </style>
</head>
<body>
    <div class="container my-5">
        <h2 class="text-primary mb-4">响应式工具类</h2>
        
        <!-- 显示/隐藏工具类 -->
        <div class="mb-5">
            <h4>显示/隐藏工具类</h4>
            
            <div class="utility-demo demo-primary d-block d-sm-none">
                只在 XS 屏幕显示 (d-block d-sm-none)
            </div>
            
            <div class="utility-demo demo-success d-none d-sm-block d-md-none">
                只在 SM 屏幕显示 (d-none d-sm-block d-md-none)
            </div>
            
            <div class="utility-demo demo-warning d-none d-md-block d-lg-none">
                只在 MD 屏幕显示 (d-none d-md-block d-lg-none)
            </div>
            
            <div class="utility-demo demo-danger d-none d-lg-block">
                只在 LG 及以上屏幕显示 (d-none d-lg-block)
            </div>
        </div>
        
        <!-- 文本对齐工具类 -->
        <div class="mb-5">
            <h4>响应式文本对齐</h4>
            
            <div class="utility-demo demo-primary text-center text-md-start">
                移动端居中,桌面端左对齐 (text-center text-md-start)
            </div>
            
            <div class="utility-demo demo-success text-start text-sm-center text-lg-end">
                XS左对齐,SM居中,LG右对齐 (text-start text-sm-center text-lg-end)
            </div>
        </div>
        
        <!-- Flexbox 工具类 -->
        <div class="mb-5">
            <h4>响应式 Flexbox</h4>
            
            <div class="d-flex flex-column flex-md-row">
                <div class="utility-demo demo-primary flex-fill me-md-2">
                    Flex 项目 1<br>
                    <small>(移动端垂直排列,桌面端水平排列)</small>
                </div>
                <div class="utility-demo demo-success flex-fill ms-md-2">
                    Flex 项目 2<br>
                    <small>(移动端垂直排列,桌面端水平排列)</small>
                </div>
            </div>
            
            <div class="d-flex justify-content-center justify-content-md-between align-items-center mt-3">
                <div class="utility-demo demo-warning">
                    左侧内容
                </div>
                <div class="utility-demo demo-danger d-none d-md-block">
                    右侧内容 (桌面端显示)
                </div>
            </div>
        </div>
        
        <!-- 间距工具类 -->
        <div class="mb-5">
            <h4>响应式间距</h4>
            
            <div class="utility-demo demo-primary p-2 p-md-4">
                响应式内边距 (p-2 p-md-4)
            </div>
            
            <div class="utility-demo demo-success mt-2 mt-md-4 mb-2 mb-md-4">
                响应式外边距 (mt-2 mt-md-4 mb-2 mb-md-4)
            </div>
        </div>
        
        <!-- 尺寸工具类 -->
        <div class="mb-5">
            <h4>响应式尺寸</h4>
            
            <div class="utility-demo demo-primary w-100 w-md-75 w-lg-50">
                响应式宽度 (w-100 w-md-75 w-lg-50)
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

响应式图片和媒体

1. 响应式图片

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式图片和媒体</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .image-demo {
            background: linear-gradient(45deg, #f0f0f0, #e0e0e0);
            border: 2px dashed #ccc;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #666;
            font-weight: bold;
            min-height: 200px;
        }
        
        .media-container {
            background-color: #f8f9fa;
            border-radius: 0.5rem;
            padding: 1rem;
            margin-bottom: 2rem;
        }
    </style>
</head>
<body>
    <div class="container my-5">
        <h2 class="text-primary mb-4">响应式图片和媒体</h2>
        
        <!-- 响应式图片 -->
        <div class="media-container">
            <h4>响应式图片</h4>
            
            <div class="row">
                <div class="col-12 col-md-6 mb-3">
                    <h6>img-fluid 类</h6>
                    <div class="image-demo img-fluid">
                        响应式图片<br>
                        (自动缩放)
                    </div>
                    <small class="text-muted">使用 .img-fluid 类使图片响应式</small>
                </div>
                
                <div class="col-12 col-md-6 mb-3">
                    <h6>固定尺寸图片</h6>
                    <div class="image-demo" style="width: 300px; height: 200px;">
                        固定尺寸图片<br>
                        (300x200px)
                    </div>
                    <small class="text-muted">固定尺寸可能在小屏幕上溢出</small>
                </div>
            </div>
        </div>
        
        <!-- 图片形状 -->
        <div class="media-container">
            <h4>图片形状</h4>
            
            <div class="row text-center">
                <div class="col-12 col-sm-4 mb-3">
                    <div class="image-demo rounded" style="width: 150px; height: 150px; margin: 0 auto;">
                        圆角图片<br>
                        .rounded
                    </div>
                </div>
                
                <div class="col-12 col-sm-4 mb-3">
                    <div class="image-demo rounded-circle" style="width: 150px; height: 150px; margin: 0 auto;">
                        圆形图片<br>
                        .rounded-circle
                    </div>
                </div>
                
                <div class="col-12 col-sm-4 mb-3">
                    <div class="image-demo img-thumbnail" style="width: 150px; height: 150px; margin: 0 auto;">
                        缩略图<br>
                        .img-thumbnail
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 响应式嵌入 -->
        <div class="media-container">
            <h4>响应式嵌入</h4>
            
            <div class="row">
                <div class="col-12 col-lg-6 mb-3">
                    <h6>16:9 比例视频</h6>
                    <div class="ratio ratio-16x9">
                        <div class="bg-secondary d-flex align-items-center justify-content-center text-white">
                            <div class="text-center">
                                <i class="bi bi-play-circle" style="font-size: 3rem;"></i><br>
                                16:9 视频播放器
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-12 col-lg-6 mb-3">
                    <h6>4:3 比例视频</h6>
                    <div class="ratio ratio-4x3">
                        <div class="bg-info d-flex align-items-center justify-content-center text-white">
                            <div class="text-center">
                                <i class="bi bi-play-circle" style="font-size: 3rem;"></i><br>
                                4:3 视频播放器
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-12 col-lg-6 mb-3">
                    <h6>1:1 比例内容</h6>
                    <div class="ratio ratio-1x1">
                        <div class="bg-warning d-flex align-items-center justify-content-center text-dark">
                            <div class="text-center">
                                <i class="bi bi-square" style="font-size: 3rem;"></i><br>
                                1:1 正方形内容
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-12 col-lg-6 mb-3">
                    <h6>21:9 比例内容</h6>
                    <div class="ratio ratio-21x9">
                        <div class="bg-danger d-flex align-items-center justify-content-center text-white">
                            <div class="text-center">
                                <i class="bi bi-aspect-ratio" style="font-size: 3rem;"></i><br>
                                21:9 宽屏内容
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <!-- 图片网格 -->
        <div class="media-container">
            <h4>响应式图片网格</h4>
            
            <div class="row g-2">
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="image-demo" style="height: 150px;">
                        图片 1
                    </div>
                </div>
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="image-demo" style="height: 150px;">
                        图片 2
                    </div>
                </div>
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="image-demo" style="height: 150px;">
                        图片 3
                    </div>
                </div>
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="image-demo" style="height: 150px;">
                        图片 4
                    </div>
                </div>
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="image-demo" style="height: 150px;">
                        图片 5
                    </div>
                </div>
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="image-demo" style="height: 150px;">
                        图片 6
                    </div>
                </div>
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="image-demo" style="height: 150px;">
                        图片 7
                    </div>
                </div>
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="image-demo" style="height: 150px;">
                        图片 8
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

响应式导航设计

1. 移动优先导航

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式导航设计</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css" rel="stylesheet">
    <style>
        .navbar-custom {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        
        .navbar-custom .navbar-brand {
            font-weight: bold;
            font-size: 1.5rem;
        }
        
        .navbar-custom .nav-link {
            font-weight: 500;
            transition: all 0.3s ease;
        }
        
        .navbar-custom .nav-link:hover {
            transform: translateY(-2px);
        }
        
        .content-section {
            min-height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .hero-section {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        
        .feature-section {
            background-color: #f8f9fa;
        }
        
        .contact-section {
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            color: white;
        }
    </style>
</head>
<body>
    <!-- 响应式导航栏 -->
    <nav class="navbar navbar-expand-lg navbar-dark navbar-custom fixed-top">
        <div class="container">
            <!-- 品牌标识 -->
            <a class="navbar-brand" href="#">
                <i class="bi bi-bootstrap"></i>
                响应式网站
            </a>
            
            <!-- 移动端切换按钮 -->
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            
            <!-- 导航菜单 -->
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav ms-auto">
                    <li class="nav-item">
                        <a class="nav-link active" href="#home">
                            <i class="bi bi-house"></i>
                            <span class="d-lg-none">首页</span>
                            <span class="d-none d-lg-inline">首页</span>
                        </a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#features">
                            <i class="bi bi-star"></i>
                            <span class="d-lg-none">特性</span>
                            <span class="d-none d-lg-inline">特性</span>
                        </a>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                            <i class="bi bi-grid"></i>
                            服务
                        </a>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="#">Web 开发</a></li>
                            <li><a class="dropdown-item" href="#">移动应用</a></li>
                            <li><a class="dropdown-item" href="#">UI/UX 设计</a></li>
                            <li><hr class="dropdown-divider"></li>
                            <li><a class="dropdown-item" href="#">咨询服务</a></li>
                        </ul>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#contact">
                            <i class="bi bi-envelope"></i>
                            <span class="d-lg-none">联系我们</span>
                            <span class="d-none d-lg-inline">联系</span>
                        </a>
                    </li>
                </ul>
                
                <!-- 搜索框 (桌面端显示) -->
                <form class="d-none d-lg-flex ms-3" role="search">
                    <input class="form-control me-2" type="search" placeholder="搜索..." aria-label="Search">
                    <button class="btn btn-outline-light" type="submit">
                        <i class="bi bi-search"></i>
                    </button>
                </form>
            </div>
        </div>
    </nav>
    
    <!-- 主要内容区域 -->
    <main style="padding-top: 76px;">
        <!-- 首页部分 -->
        <section id="home" class="content-section hero-section">
            <div class="container">
                <div class="row justify-content-center text-center">
                    <div class="col-12 col-md-8 col-lg-6">
                        <h1 class="display-4 fw-bold mb-4">响应式设计</h1>
                        <p class="lead mb-4">使用Bootstrap创建适应所有设备的现代化网站</p>
                        <div class="d-flex flex-column flex-sm-row justify-content-center gap-3">
                            <a href="#features" class="btn btn-light btn-lg">
                                <i class="bi bi-arrow-down"></i>
                                了解更多
                            </a>
                            <a href="#contact" class="btn btn-outline-light btn-lg">
                                <i class="bi bi-envelope"></i>
                                联系我们
                            </a>
                        </div>
                    </div>
                </div>
            </div>
        </section>
        
        <!-- 特性部分 -->
        <section id="features" class="content-section feature-section">
            <div class="container">
                <div class="row justify-content-center">
                    <div class="col-12 col-lg-8 text-center">
                        <h2 class="display-5 fw-bold mb-5">核心特性</h2>
                        
                        <div class="row">
                            <div class="col-12 col-md-4 mb-4">
                                <div class="text-primary mb-3">
                                    <i class="bi bi-phone" style="font-size: 3rem;"></i>
                                </div>
                                <h4>移动优先</h4>
                                <p>从移动设备开始设计,确保在所有屏幕尺寸上都有完美体验。</p>
                            </div>
                            
                            <div class="col-12 col-md-4 mb-4">
                                <div class="text-success mb-3">
                                    <i class="bi bi-grid-3x3" style="font-size: 3rem;"></i>
                                </div>
                                <h4>灵活网格</h4>
                                <p>使用强大的网格系统创建复杂的响应式布局。</p>
                            </div>
                            
                            <div class="col-12 col-md-4 mb-4">
                                <div class="text-info mb-3">
                                    <i class="bi bi-speedometer2" style="font-size: 3rem;"></i>
                                </div>
                                <h4>高性能</h4>
                                <p>优化的CSS和JavaScript确保快速加载和流畅交互。</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </section>
        
        <!-- 联系部分 -->
        <section id="contact" class="content-section contact-section">
            <div class="container">
                <div class="row justify-content-center">
                    <div class="col-12 col-md-8 col-lg-6 text-center">
                        <h2 class="display-5 fw-bold mb-4">联系我们</h2>
                        <p class="lead mb-4">准备开始您的响应式网站项目了吗?</p>
                        
                        <div class="row text-start">
                            <div class="col-12 col-sm-6 mb-3">
                                <div class="d-flex align-items-center">
                                    <i class="bi bi-envelope-fill me-3" style="font-size: 1.5rem;"></i>
                                    <div>
                                        <strong>邮箱</strong><br>
                                        contact@example.com
                                    </div>
                                </div>
                            </div>
                            
                            <div class="col-12 col-sm-6 mb-3">
                                <div class="d-flex align-items-center">
                                    <i class="bi bi-telephone-fill me-3" style="font-size: 1.5rem;"></i>
                                    <div>
                                        <strong>电话</strong><br>
                                        +86 138 0013 8000
                                    </div>
                                </div>
                            </div>
                        </div>
                        
                        <div class="mt-4">
                            <a href="mailto:contact@example.com" class="btn btn-light btn-lg me-3">
                                <i class="bi bi-envelope"></i>
                                发送邮件
                            </a>
                            <a href="tel:+8613800138000" class="btn btn-outline-light btn-lg">
                                <i class="bi bi-telephone"></i>
                                拨打电话
                            </a>
                        </div>
                    </div>
                </div>
            </div>
        </section>
    </main>
    
    <!-- 底部导航 (移动端) -->
    <nav class="navbar navbar-dark bg-dark fixed-bottom d-lg-none">
        <div class="container-fluid">
            <div class="d-flex justify-content-around w-100">
                <a href="#home" class="text-light text-decoration-none text-center">
                    <i class="bi bi-house d-block"></i>
                    <small>首页</small>
                </a>
                <a href="#features" class="text-light text-decoration-none text-center">
                    <i class="bi bi-star d-block"></i>
                    <small>特性</small>
                </a>
                <a href="#contact" class="text-light text-decoration-none text-center">
                    <i class="bi bi-envelope d-block"></i>
                    <small>联系</small>
                </a>
                <a href="#" class="text-light text-decoration-none text-center">
                    <i class="bi bi-person d-block"></i>
                    <small>我的</small>
                </a>
            </div>
        </div>
    </nav>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // 平滑滚动
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                const target = document.querySelector(this.getAttribute('href'));
                if (target) {
                    target.scrollIntoView({
                        behavior: 'smooth',
                        block: 'start'
                    });
                }
            });
        });
        
        // 导航栏活动状态
        window.addEventListener('scroll', function() {
            const sections = document.querySelectorAll('section');
            const navLinks = document.querySelectorAll('.navbar-nav .nav-link');
            
            let current = '';
            sections.forEach(section => {
                const sectionTop = section.offsetTop - 100;
                if (pageYOffset >= sectionTop) {
                    current = section.getAttribute('id');
                }
            });
            
            navLinks.forEach(link => {
                link.classList.remove('active');
                if (link.getAttribute('href') === '#' + current) {
                    link.classList.add('active');
                }
            });
        });
    </script>
</body>
</html>

实际应用案例

1. 响应式电商网站

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式电商网站</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.0/font/bootstrap-icons.css" rel="stylesheet">
    <style>
        .product-card {
            transition: transform 0.3s ease, box-shadow 0.3s ease;
            border: none;
            border-radius: 1rem;
            overflow: hidden;
        }
        
        .product-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0,0,0,0.1);
        }
        
        .product-image {
            height: 200px;
            background: linear-gradient(45deg, #f0f0f0, #e0e0e0);
            display: flex;
            align-items: center;
            justify-content: center;
            color: #666;
            font-size: 3rem;
        }
        
        .price {
            font-size: 1.25rem;
            font-weight: bold;
            color: #e74c3c;
        }
        
        .original-price {
            text-decoration: line-through;
            color: #95a5a6;
            font-size: 0.9rem;
        }
        
        .hero-banner {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 4rem 0;
        }
        
        .category-card {
            background: white;
            border-radius: 1rem;
            padding: 2rem;
            text-align: center;
            transition: all 0.3s ease;
            border: 1px solid #e9ecef;
        }
        
        .category-card:hover {
            transform: translateY(-3px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.1);
        }
        
        .category-icon {
            width: 80px;
            height: 80px;
            background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 0 auto 1rem;
            color: white;
            font-size: 2rem;
        }
        
        @media (max-width: 767.98px) {
            .hero-banner {
                padding: 2rem 0;
            }
            
            .hero-banner h1 {
                font-size: 2rem;
            }
        }
    </style>
</head>
<body>
    <!-- 导航栏 -->
    <nav class="navbar navbar-expand-lg navbar-light bg-white shadow-sm sticky-top">
        <div class="container">
            <a class="navbar-brand fw-bold text-primary" href="#">
                <i class="bi bi-shop"></i>
                电商商城
            </a>
            
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
                <span class="navbar-toggler-icon"></span>
            </button>
            
            <div class="collapse navbar-collapse" id="navbarNav">
                <ul class="navbar-nav me-auto">
                    <li class="nav-item">
                        <a class="nav-link" href="#">首页</a>
                    </li>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">
                            分类
                        </a>
                        <ul class="dropdown-menu">
                            <li><a class="dropdown-item" href="#">电子产品</a></li>
                            <li><a class="dropdown-item" href="#">服装配饰</a></li>
                            <li><a class="dropdown-item" href="#">家居用品</a></li>
                        </ul>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">特价商品</a>
                    </li>
                </ul>
                
                <div class="d-flex align-items-center">
                    <!-- 搜索框 -->
                    <form class="d-none d-md-flex me-3">
                        <div class="input-group">
                            <input type="search" class="form-control" placeholder="搜索商品...">
                            <button class="btn btn-outline-primary" type="submit">
                                <i class="bi bi-search"></i>
                            </button>
                        </div>
                    </form>
                    
                    <!-- 购物车 -->
                    <a href="#" class="btn btn-outline-primary me-2 position-relative">
                        <i class="bi bi-cart"></i>
                        <span class="d-none d-lg-inline ms-1">购物车</span>
                        <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
                            3
                        </span>
                    </a>
                    
                    <!-- 用户菜单 -->
                    <div class="dropdown">
                        <button class="btn btn-primary dropdown-toggle" data-bs-toggle="dropdown">
                            <i class="bi bi-person"></i>
                            <span class="d-none d-lg-inline ms-1">账户</span>
                        </button>
                        <ul class="dropdown-menu dropdown-menu-end">
                            <li><a class="dropdown-item" href="#">我的订单</a></li>
                            <li><a class="dropdown-item" href="#">个人资料</a></li>
                            <li><hr class="dropdown-divider"></li>
                            <li><a class="dropdown-item" href="#">退出登录</a></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </nav>
    
    <!-- 英雄横幅 -->
    <section class="hero-banner">
        <div class="container">
            <div class="row align-items-center">
                <div class="col-12 col-lg-6">
                    <h1 class="display-4 fw-bold mb-3">发现精选商品</h1>
                    <p class="lead mb-4">在我们的响应式电商平台上找到您需要的一切</p>
                    <div class="d-flex flex-column flex-sm-row gap-3">
                        <a href="#products" class="btn btn-light btn-lg">
                            <i class="bi bi-arrow-down"></i>
                            浏览商品
                        </a>
                        <a href="#" class="btn btn-outline-light btn-lg">
                            <i class="bi bi-percent"></i>
                            查看优惠
                        </a>
                    </div>
                </div>
                <div class="col-12 col-lg-6 text-center">
                    <div class="d-none d-lg-block">
                        <i class="bi bi-bag-heart" style="font-size: 10rem; opacity: 0.3;"></i>
                    </div>
                </div>
            </div>
        </div>
    </section>
    
    <!-- 商品分类 -->
    <section class="py-5 bg-light">
        <div class="container">
            <h2 class="text-center mb-5">热门分类</h2>
            <div class="row g-4">
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="category-card">
                        <div class="category-icon">
                            <i class="bi bi-laptop"></i>
                        </div>
                        <h5>电子产品</h5>
                        <p class="text-muted small">最新科技产品</p>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="category-card">
                        <div class="category-icon">
                            <i class="bi bi-bag"></i>
                        </div>
                        <h5>服装配饰</h5>
                        <p class="text-muted small">时尚潮流单品</p>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="category-card">
                        <div class="category-icon">
                            <i class="bi bi-house"></i>
                        </div>
                        <h5>家居用品</h5>
                        <p class="text-muted small">舒适生活必需品</p>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="category-card">
                        <div class="category-icon">
                            <i class="bi bi-heart"></i>
                        </div>
                        <h5>美妆护肤</h5>
                        <p class="text-muted small">美丽从这里开始</p>
                    </div>
                </div>
            </div>
        </div>
    </section>
    
    <!-- 商品展示 -->
    <section id="products" class="py-5">
        <div class="container">
            <div class="d-flex justify-content-between align-items-center mb-4">
                <h2>热销商品</h2>
                <div class="d-none d-md-flex">
                    <button class="btn btn-outline-secondary me-2 active">全部</button>
                    <button class="btn btn-outline-secondary me-2">电子产品</button>
                    <button class="btn btn-outline-secondary me-2">服装</button>
                    <button class="btn btn-outline-secondary">家居</button>
                </div>
            </div>
            
            <div class="row g-4">
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="card product-card h-100">
                        <div class="product-image">
                            <i class="bi bi-laptop"></i>
                        </div>
                        <div class="card-body">
                            <h6 class="card-title">笔记本电脑</h6>
                            <p class="card-text small text-muted">高性能办公笔记本</p>
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <span class="price">¥4,999</span>
                                    <span class="original-price ms-1">¥5,999</span>
                                </div>
                                <button class="btn btn-primary btn-sm">
                                    <i class="bi bi-cart-plus"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="card product-card h-100">
                        <div class="product-image">
                            <i class="bi bi-phone"></i>
                        </div>
                        <div class="card-body">
                            <h6 class="card-title">智能手机</h6>
                            <p class="card-text small text-muted">最新款智能手机</p>
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <span class="price">¥2,999</span>
                                </div>
                                <button class="btn btn-primary btn-sm">
                                    <i class="bi bi-cart-plus"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="card product-card h-100">
                        <div class="product-image">
                            <i class="bi bi-headphones"></i>
                        </div>
                        <div class="card-body">
                            <h6 class="card-title">无线耳机</h6>
                            <p class="card-text small text-muted">降噪无线蓝牙耳机</p>
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <span class="price">¥599</span>
                                    <span class="original-price ms-1">¥799</span>
                                </div>
                                <button class="btn btn-primary btn-sm">
                                    <i class="bi bi-cart-plus"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="card product-card h-100">
                        <div class="product-image">
                            <i class="bi bi-watch"></i>
                        </div>
                        <div class="card-body">
                            <h6 class="card-title">智能手表</h6>
                            <p class="card-text small text-muted">健康监测智能手表</p>
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <span class="price">¥1,299</span>
                                </div>
                                <button class="btn btn-primary btn-sm">
                                    <i class="bi bi-cart-plus"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="card product-card h-100">
                        <div class="product-image">
                            <i class="bi bi-camera"></i>
                        </div>
                        <div class="card-body">
                            <h6 class="card-title">数码相机</h6>
                            <p class="card-text small text-muted">专业摄影相机</p>
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <span class="price">¥3,599</span>
                                    <span class="original-price ms-1">¥4,299</span>
                                </div>
                                <button class="btn btn-primary btn-sm">
                                    <i class="bi bi-cart-plus"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="card product-card h-100">
                        <div class="product-image">
                            <i class="bi bi-mouse"></i>
                        </div>
                        <div class="card-body">
                            <h6 class="card-title">无线鼠标</h6>
                            <p class="card-text small text-muted">人体工学无线鼠标</p>
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <span class="price">¥199</span>
                                </div>
                                <button class="btn btn-primary btn-sm">
                                    <i class="bi bi-cart-plus"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="card product-card h-100">
                        <div class="product-image">
                            <i class="bi bi-keyboard"></i>
                        </div>
                        <div class="card-body">
                            <h6 class="card-title">机械键盘</h6>
                            <p class="card-text small text-muted">RGB背光机械键盘</p>
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <span class="price">¥499</span>
                                    <span class="original-price ms-1">¥699</span>
                                </div>
                                <button class="btn btn-primary btn-sm">
                                    <i class="bi bi-cart-plus"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
                
                <div class="col-6 col-md-4 col-lg-3">
                    <div class="card product-card h-100">
                        <div class="product-image">
                            <i class="bi bi-display"></i>
                        </div>
                        <div class="card-body">
                            <h6 class="card-title">显示器</h6>
                            <p class="card-text small text-muted">4K高清显示器</p>
                            <div class="d-flex justify-content-between align-items-center">
                                <div>
                                    <span class="price">¥1,899</span>
                                </div>
                                <button class="btn btn-primary btn-sm">
                                    <i class="bi bi-cart-plus"></i>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="text-center mt-5">
                <button class="btn btn-outline-primary btn-lg">
                    <i class="bi bi-arrow-clockwise"></i>
                    加载更多商品
                </button>
            </div>
        </div>
    </section>
    
    <!-- 底部导航 (移动端) -->
    <nav class="navbar navbar-light bg-white border-top fixed-bottom d-lg-none">
        <div class="container-fluid">
            <div class="d-flex justify-content-around w-100">
                <a href="#" class="text-decoration-none text-center">
                    <i class="bi bi-house d-block text-primary"></i>
                    <small>首页</small>
                </a>
                <a href="#" class="text-decoration-none text-center">
                    <i class="bi bi-grid d-block text-muted"></i>
                    <small>分类</small>
                </a>
                <a href="#" class="text-decoration-none text-center position-relative">
                    <i class="bi bi-cart d-block text-muted"></i>
                    <small>购物车</small>
                    <span class="position-absolute top-0 start-50 translate-middle badge rounded-pill bg-danger" style="font-size: 0.6rem;">
                        3
                    </span>
                </a>
                <a href="#" class="text-decoration-none text-center">
                    <i class="bi bi-person d-block text-muted"></i>
                    <small>我的</small>
                </a>
            </div>
        </div>
    </nav>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        // 商品筛选功能
        document.querySelectorAll('.btn-outline-secondary').forEach(btn => {
            btn.addEventListener('click', function() {
                document.querySelectorAll('.btn-outline-secondary').forEach(b => b.classList.remove('active'));
                this.classList.add('active');
            });
        });
        
        // 添加到购物车动画
        document.querySelectorAll('.btn-primary').forEach(btn => {
            btn.addEventListener('click', function() {
                const originalText = this.innerHTML;
                this.innerHTML = '<i class="bi bi-check"></i>';
                this.classList.add('btn-success');
                this.classList.remove('btn-primary');
                
                setTimeout(() => {
                    this.innerHTML = originalText;
                    this.classList.add('btn-primary');
                    this.classList.remove('btn-success');
                }, 1000);
            });
        });
    </script>
</body>
</html>

自定义响应式样式

1. 自定义断点

// 自定义断点变量
$custom-breakpoints: (
  xs: 0,
  sm: 576px,
  md: 768px,
  lg: 992px,
  xl: 1200px,
  xxl: 1400px,
  xxxl: 1600px  // 添加超大断点
);

// 自定义媒体查询混合器
@mixin respond-to($breakpoint) {
  @if map-has-key($custom-breakpoints, $breakpoint) {
    @media (min-width: map-get($custom-breakpoints, $breakpoint)) {
      @content;
    }
  } @else {
    @warn "Breakpoint #{$breakpoint} not found in $custom-breakpoints.";
  }
}

// 使用示例
.custom-responsive-element {
  padding: 1rem;
  
  @include respond-to(sm) {
    padding: 1.5rem;
  }
  
  @include respond-to(md) {
    padding: 2rem;
  }
  
  @include respond-to(lg) {
    padding: 2.5rem;
  }
  
  @include respond-to(xl) {
    padding: 3rem;
  }
  
  @include respond-to(xxxl) {
    padding: 4rem;
  }
}

2. 响应式字体系统

/* 响应式字体系统 */
:root {
  /* 基础字体大小 */
  --font-size-xs: 0.75rem;   /* 12px */
  --font-size-sm: 0.875rem;  /* 14px */
  --font-size-base: 1rem;    /* 16px */
  --font-size-lg: 1.125rem;  /* 18px */
  --font-size-xl: 1.25rem;   /* 20px */
  --font-size-2xl: 1.5rem;   /* 24px */
  --font-size-3xl: 1.875rem; /* 30px */
  --font-size-4xl: 2.25rem;  /* 36px */
  --font-size-5xl: 3rem;     /* 48px */
  
  /* 行高 */
  --line-height-tight: 1.25;
  --line-height-normal: 1.5;
  --line-height-relaxed: 1.75;
}

/* 响应式标题 */
.responsive-heading-1 {
  font-size: var(--font-size-2xl);
  line-height: var(--line-height-tight);
  font-weight: 700;
}

@media (min-width: 576px) {
  .responsive-heading-1 {
    font-size: var(--font-size-3xl);
  }
}

@media (min-width: 768px) {
  .responsive-heading-1 {
    font-size: var(--font-size-4xl);
  }
}

@media (min-width: 992px) {
  .responsive-heading-1 {
    font-size: var(--font-size-5xl);
  }
}

/* 响应式正文 */
.responsive-body {
  font-size: var(--font-size-sm);
  line-height: var(--line-height-normal);
}

@media (min-width: 768px) {
  .responsive-body {
    font-size: var(--font-size-base);
  }
}

@media (min-width: 992px) {
  .responsive-body {
    font-size: var(--font-size-lg);
    line-height: var(--line-height-relaxed);
  }
}

3. 响应式间距系统

/* 响应式间距系统 */
:root {
  --spacing-1: 0.25rem;  /* 4px */
  --spacing-2: 0.5rem;   /* 8px */
  --spacing-3: 0.75rem;  /* 12px */
  --spacing-4: 1rem;     /* 16px */
  --spacing-5: 1.25rem;  /* 20px */
  --spacing-6: 1.5rem;   /* 24px */
  --spacing-8: 2rem;     /* 32px */
  --spacing-10: 2.5rem;  /* 40px */
  --spacing-12: 3rem;    /* 48px */
  --spacing-16: 4rem;    /* 64px */
  --spacing-20: 5rem;    /* 80px */
}

/* 响应式容器间距 */
.responsive-container {
  padding: var(--spacing-4);
}

@media (min-width: 576px) {
  .responsive-container {
    padding: var(--spacing-6);
  }
}

@media (min-width: 768px) {
  .responsive-container {
    padding: var(--spacing-8);
  }
}

@media (min-width: 992px) {
  .responsive-container {
    padding: var(--spacing-12);
  }
}

/* 响应式卡片间距 */
.responsive-card {
  padding: var(--spacing-4);
  margin-bottom: var(--spacing-4);
  border-radius: 0.5rem;
  background: white;
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

@media (min-width: 768px) {
  .responsive-card {
    padding: var(--spacing-6);
    margin-bottom: var(--spacing-6);
  }
}

@media (min-width: 992px) {
  .responsive-card {
    padding: var(--spacing-8);
    margin-bottom: var(--spacing-8);
  }
}

响应式组件优化

1. 响应式表格

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式表格</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .responsive-table-card {
            background: white;
            border-radius: 1rem;
            box-shadow: 0 4px 6px rgba(0,0,0,0.1);
            overflow: hidden;
        }
        
        .table-header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 1.5rem;
        }
        
        @media (max-width: 767.98px) {
            .mobile-table {
                display: none;
            }
            
            .mobile-cards {
                display: block;
            }
            
            .mobile-card {
                background: #f8f9fa;
                border-radius: 0.5rem;
                padding: 1rem;
                margin-bottom: 1rem;
                border-left: 4px solid #007bff;
            }
        }
        
        @media (min-width: 768px) {
            .mobile-table {
                display: table;
            }
            
            .mobile-cards {
                display: none;
            }
        }
    </style>
</head>
<body>
    <div class="container my-5">
        <div class="responsive-table-card">
            <div class="table-header">
                <h3 class="mb-0">用户数据表</h3>
                <p class="mb-0 opacity-75">响应式表格展示</p>
            </div>
            
            <!-- 桌面端表格 -->
            <div class="table-responsive">
                <table class="table table-hover mobile-table mb-0">
                    <thead class="table-light">
                        <tr>
                            <th>ID</th>
                            <th>姓名</th>
                            <th>邮箱</th>
                            <th>电话</th>
                            <th>状态</th>
                            <th>注册时间</th>
                            <th>操作</th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>001</td>
                            <td>张三</td>
                            <td>zhangsan@example.com</td>
                            <td>138-0013-8000</td>
                            <td><span class="badge bg-success">活跃</span></td>
                            <td>2024-01-15</td>
                            <td>
                                <button class="btn btn-sm btn-outline-primary me-1">
                                    <i class="bi bi-pencil"></i>
                                </button>
                                <button class="btn btn-sm btn-outline-danger">
                                    <i class="bi bi-trash"></i>
                                </button>
                            </td>
                        </tr>
                        <tr>
                            <td>002</td>
                            <td>李四</td>
                            <td>lisi@example.com</td>
                            <td>138-0013-8001</td>
                            <td><span class="badge bg-warning">待激活</span></td>
                            <td>2024-01-16</td>
                            <td>
                                <button class="btn btn-sm btn-outline-primary me-1">
                                    <i class="bi bi-pencil"></i>
                                </button>
                                <button class="btn btn-sm btn-outline-danger">
                                    <i class="bi bi-trash"></i>
                                </button>
                            </td>
                        </tr>
                        <tr>
                            <td>003</td>
                            <td>王五</td>
                            <td>wangwu@example.com</td>
                            <td>138-0013-8002</td>
                            <td><span class="badge bg-danger">已禁用</span></td>
                            <td>2024-01-17</td>
                            <td>
                                <button class="btn btn-sm btn-outline-primary me-1">
                                    <i class="bi bi-pencil"></i>
                                </button>
                                <button class="btn btn-sm btn-outline-danger">
                                    <i class="bi bi-trash"></i>
                                </button>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            
            <!-- 移动端卡片 -->
            <div class="mobile-cards p-3">
                <div class="mobile-card">
                    <div class="d-flex justify-content-between align-items-start mb-2">
                        <h6 class="mb-0">张三 (#001)</h6>
                        <span class="badge bg-success">活跃</span>
                    </div>
                    <p class="mb-1"><strong>邮箱:</strong> zhangsan@example.com</p>
                    <p class="mb-1"><strong>电话:</strong> 138-0013-8000</p>
                    <p class="mb-2"><strong>注册时间:</strong> 2024-01-15</p>
                    <div class="d-flex gap-2">
                        <button class="btn btn-sm btn-outline-primary">
                            <i class="bi bi-pencil"></i> 编辑
                        </button>
                        <button class="btn btn-sm btn-outline-danger">
                            <i class="bi bi-trash"></i> 删除
                        </button>
                    </div>
                </div>
                
                <div class="mobile-card">
                    <div class="d-flex justify-content-between align-items-start mb-2">
                        <h6 class="mb-0">李四 (#002)</h6>
                        <span class="badge bg-warning">待激活</span>
                    </div>
                    <p class="mb-1"><strong>邮箱:</strong> lisi@example.com</p>
                    <p class="mb-1"><strong>电话:</strong> 138-0013-8001</p>
                    <p class="mb-2"><strong>注册时间:</strong> 2024-01-16</p>
                    <div class="d-flex gap-2">
                        <button class="btn btn-sm btn-outline-primary">
                            <i class="bi bi-pencil"></i> 编辑
                        </button>
                        <button class="btn btn-sm btn-outline-danger">
                            <i class="bi bi-trash"></i> 删除
                        </button>
                    </div>
                </div>
                
                <div class="mobile-card">
                    <div class="d-flex justify-content-between align-items-start mb-2">
                        <h6 class="mb-0">王五 (#003)</h6>
                        <span class="badge bg-danger">已禁用</span>
                    </div>
                    <p class="mb-1"><strong>邮箱:</strong> wangwu@example.com</p>
                    <p class="mb-1"><strong>电话:</strong> 138-0013-8002</p>
                    <p class="mb-2"><strong>注册时间:</strong> 2024-01-17</p>
                    <div class="d-flex gap-2">
                        <button class="btn btn-sm btn-outline-primary">
                            <i class="bi bi-pencil"></i> 编辑
                        </button>
                        <button class="btn btn-sm btn-outline-danger">
                            <i class="bi bi-trash"></i> 删除
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>