本章概述

本章将深入探讨 UnoCSS 的响应式设计能力,学习如何使用断点系统创建适配不同设备的界面。我们将从基础的断点概念开始,逐步学习高级的响应式技巧和最佳实践。

响应式设计基础

什么是响应式设计

响应式设计(Responsive Design)是一种网页设计方法,使网站能够在不同设备和屏幕尺寸上提供最佳的用户体验。它通过使用灵活的布局、图片和CSS媒体查询来实现。

响应式设计的核心原则

  1. 移动优先:从最小屏幕开始设计,逐步增强
  2. 灵活布局:使用相对单位而非固定像素
  3. 弹性图片:图片能够适应容器大小
  4. 媒体查询:根据设备特性应用不同样式
  5. 渐进增强:基础功能在所有设备上可用,高级功能在支持的设备上增强

UnoCSS的响应式方法

// UnoCSS 响应式配置
export default defineConfig({
  theme: {
    breakpoints: {
      'xs': '320px',
      'sm': '640px',
      'md': '768px',
      'lg': '1024px',
      'xl': '1280px',
      '2xl': '1536px',
    }
  },
  
  // 响应式变体
  variants: [
    // 移动优先的断点
    (matcher) => {
      const breakpoints = ['sm', 'md', 'lg', 'xl', '2xl']
      for (const bp of breakpoints) {
        if (matcher.startsWith(`${bp}:`)) {
          return {
            matcher: matcher.slice(bp.length + 1),
            parent: `@media (min-width: ${theme.breakpoints[bp]})`,
          }
        }
      }
      return matcher
    },
  ],
})

断点系统详解

默认断点

UnoCSS 提供了一套默认的断点系统,遵循移动优先的设计原则:

/* 默认断点对应的媒体查询 */
/* xs: 无媒体查询(默认,移动优先) */
/* sm: @media (min-width: 640px) */
/* md: @media (min-width: 768px) */
/* lg: @media (min-width: 1024px) */
/* xl: @media (min-width: 1280px) */
/* 2xl: @media (min-width: 1536px) */

断点使用语法

<!-- 基础语法:{断点}:{工具类} -->
<div class="w-full md:w-1/2 lg:w-1/3">
  <!-- 默认全宽,中等屏幕半宽,大屏幕三分之一宽 -->
</div>

<!-- 多个断点组合 -->
<div class="text-sm sm:text-base md:text-lg lg:text-xl xl:text-2xl">
  <!-- 不同屏幕尺寸下的不同字体大小 -->
</div>

<!-- 复杂响应式布局 -->
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
  <!-- 响应式网格布局 -->
</div>

自定义断点

// 自定义断点配置
export default defineConfig({
  theme: {
    breakpoints: {
      // 覆盖默认断点
      'xs': '375px',    // iPhone SE
      'sm': '640px',    // 小平板
      'md': '768px',    // 平板
      'lg': '1024px',   // 小桌面
      'xl': '1280px',   // 桌面
      '2xl': '1536px',  // 大桌面
      
      // 添加自定义断点
      'mobile': '480px',
      'tablet': '768px',
      'laptop': '1024px',
      'desktop': '1280px',
      'wide': '1920px',
      
      // 特殊设备断点
      'iphone': '375px',
      'ipad': '768px',
      'macbook': '1440px',
    }
  },
  
  // 自定义变体生成器
  variants: [
    // 标准断点
    ...Object.entries(theme.breakpoints).map(([name, size]) => {
      return (matcher) => {
        if (!matcher.startsWith(`${name}:`)) return matcher
        return {
          matcher: matcher.slice(name.length + 1),
          parent: `@media (min-width: ${size})`,
        }
      }
    }),
    
    // 最大宽度断点
    (matcher) => {
      const maxBreakpoints = {
        'max-sm': '639px',
        'max-md': '767px',
        'max-lg': '1023px',
        'max-xl': '1279px',
      }
      
      for (const [name, size] of Object.entries(maxBreakpoints)) {
        if (matcher.startsWith(`${name}:`)) {
          return {
            matcher: matcher.slice(name.length + 1),
            parent: `@media (max-width: ${size})`,
          }
        }
      }
      return matcher
    },
    
    // 范围断点
    (matcher) => {
      const rangeBreakpoints = {
        'sm-only': '(min-width: 640px) and (max-width: 767px)',
        'md-only': '(min-width: 768px) and (max-width: 1023px)',
        'lg-only': '(min-width: 1024px) and (max-width: 1279px)',
      }
      
      for (const [name, query] of Object.entries(rangeBreakpoints)) {
        if (matcher.startsWith(`${name}:`)) {
          return {
            matcher: matcher.slice(name.length + 1),
            parent: `@media ${query}`,
          }
        }
      }
      return matcher
    },
  ],
})

响应式布局技巧

容器和网格系统

<!-- 响应式容器 -->
<div class="container mx-auto px-4">
  <!-- 内容会在不同屏幕尺寸下有不同的最大宽度 -->
</div>

<!-- 自定义容器 -->
<div class="w-full max-w-screen-sm mx-auto px-4 sm:max-w-screen-md md:max-w-screen-lg lg:max-w-screen-xl">
  <!-- 渐进式容器宽度 -->
</div>

<!-- 响应式网格 -->
<div class="grid gap-4 grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-6">
  <div class="bg-gray-200 p-4 rounded">项目 1</div>
  <div class="bg-gray-200 p-4 rounded">项目 2</div>
  <div class="bg-gray-200 p-4 rounded">项目 3</div>
  <div class="bg-gray-200 p-4 rounded">项目 4</div>
  <div class="bg-gray-200 p-4 rounded">项目 5</div>
  <div class="bg-gray-200 p-4 rounded">项目 6</div>
</div>

<!-- 复杂网格布局 -->
<div class="grid gap-4 grid-cols-1 md:grid-cols-3">
  <!-- 主内容区域 -->
  <div class="md:col-span-2">
    <div class="bg-white p-6 rounded-lg shadow">
      <h2 class="text-2xl font-bold mb-4">主要内容</h2>
      <p>这里是主要内容区域...</p>
    </div>
  </div>
  
  <!-- 侧边栏 -->
  <div class="md:col-span-1">
    <div class="bg-white p-6 rounded-lg shadow">
      <h3 class="text-lg font-semibold mb-4">侧边栏</h3>
      <p>这里是侧边栏内容...</p>
    </div>
  </div>
</div>

Flexbox 响应式布局

<!-- 响应式导航栏 -->
<nav class="flex flex-col md:flex-row items-center justify-between p-4">
  <div class="flex items-center mb-4 md:mb-0">
    <img src="logo.svg" alt="Logo" class="h-8 w-8 mr-2">
    <span class="text-xl font-bold">品牌名称</span>
  </div>
  
  <div class="flex flex-col md:flex-row space-y-2 md:space-y-0 md:space-x-6">
    <a href="#" class="text-gray-700 hover:text-blue-600">首页</a>
    <a href="#" class="text-gray-700 hover:text-blue-600">产品</a>
    <a href="#" class="text-gray-700 hover:text-blue-600">关于</a>
    <a href="#" class="text-gray-700 hover:text-blue-600">联系</a>
  </div>
</nav>

<!-- 响应式卡片布局 -->
<div class="flex flex-col lg:flex-row gap-6">
  <div class="flex-1">
    <div class="bg-white p-6 rounded-lg shadow">
      <h3 class="text-lg font-semibold mb-2">卡片 1</h3>
      <p class="text-gray-600">卡片内容...</p>
    </div>
  </div>
  
  <div class="flex-1">
    <div class="bg-white p-6 rounded-lg shadow">
      <h3 class="text-lg font-semibold mb-2">卡片 2</h3>
      <p class="text-gray-600">卡片内容...</p>
    </div>
  </div>
  
  <div class="flex-1">
    <div class="bg-white p-6 rounded-lg shadow">
      <h3 class="text-lg font-semibold mb-2">卡片 3</h3>
      <p class="text-gray-600">卡片内容...</p>
    </div>
  </div>
</div>

<!-- 响应式侧边栏布局 -->
<div class="flex flex-col lg:flex-row min-h-screen">
  <!-- 侧边栏 -->
  <aside class="w-full lg:w-64 bg-gray-800 text-white">
    <div class="p-4">
      <h2 class="text-xl font-bold mb-4">菜单</h2>
      <nav class="space-y-2">
        <a href="#" class="block px-3 py-2 rounded hover:bg-gray-700">仪表板</a>
        <a href="#" class="block px-3 py-2 rounded hover:bg-gray-700">用户</a>
        <a href="#" class="block px-3 py-2 rounded hover:bg-gray-700">设置</a>
      </nav>
    </div>
  </aside>
  
  <!-- 主内容 -->
  <main class="flex-1 p-6">
    <h1 class="text-3xl font-bold mb-6">主要内容</h1>
    <div class="bg-white p-6 rounded-lg shadow">
      <p>这里是主要内容区域...</p>
    </div>
  </main>
</div>

响应式间距和尺寸

<!-- 响应式间距 -->
<div class="p-4 sm:p-6 md:p-8 lg:p-12">
  <!-- 不同屏幕尺寸下的不同内边距 -->
</div>

<div class="space-y-4 sm:space-y-6 md:space-y-8">
  <!-- 响应式垂直间距 -->
  <div>项目 1</div>
  <div>项目 2</div>
  <div>项目 3</div>
</div>

<!-- 响应式尺寸 -->
<div class="w-full sm:w-3/4 md:w-1/2 lg:w-1/3 xl:w-1/4">
  <!-- 响应式宽度 -->
</div>

<div class="h-32 sm:h-40 md:h-48 lg:h-56 xl:h-64">
  <!-- 响应式高度 -->
</div>

<!-- 响应式字体大小 -->
<h1 class="text-2xl sm:text-3xl md:text-4xl lg:text-5xl xl:text-6xl font-bold">
  响应式标题
</h1>

<p class="text-sm sm:text-base md:text-lg">
  响应式段落文本
</p>

高级响应式技巧

显示和隐藏元素

<!-- 基于屏幕尺寸显示/隐藏 -->
<div class="block md:hidden">
  <!-- 只在小屏幕显示 -->
  <button class="w-full p-3 bg-blue-500 text-white rounded">
    移动端菜单
  </button>
</div>

<div class="hidden md:block">
  <!-- 只在大屏幕显示 -->
  <nav class="flex space-x-6">
    <a href="#">首页</a>
    <a href="#">产品</a>
    <a href="#">关于</a>
  </nav>
</div>

<!-- 渐进式显示 -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
  <div class="bg-gray-200 p-4">始终显示</div>
  <div class="bg-gray-200 p-4">小屏幕及以上显示</div>
  <div class="bg-gray-200 p-4 hidden lg:block">只在大屏幕显示</div>
</div>

<!-- 响应式图片 -->
<picture>
  <source media="(min-width: 1024px)" srcset="large-image.jpg">
  <source media="(min-width: 768px)" srcset="medium-image.jpg">
  <img src="small-image.jpg" alt="响应式图片" class="w-full h-auto">
</picture>

<!-- 使用CSS类控制图片显示 -->
<div class="relative">
  <img src="mobile-image.jpg" alt="移动端图片" class="w-full h-auto md:hidden">
  <img src="desktop-image.jpg" alt="桌面端图片" class="w-full h-auto hidden md:block">
</div>

响应式排版

<!-- 响应式标题层次 -->
<h1 class="text-3xl sm:text-4xl md:text-5xl lg:text-6xl font-bold leading-tight">
  主标题
</h1>

<h2 class="text-xl sm:text-2xl md:text-3xl lg:text-4xl font-semibold mt-8 mb-4">
  副标题
</h2>

<p class="text-base sm:text-lg md:text-xl leading-relaxed text-gray-700">
  正文内容,在不同屏幕尺寸下有不同的字体大小和行高。
</p>

<!-- 响应式文本对齐 -->
<div class="text-center sm:text-left">
  <h3 class="text-2xl font-bold">标题</h3>
  <p class="text-gray-600">在小屏幕居中,大屏幕左对齐</p>
</div>

<!-- 响应式行高和字间距 -->
<p class="leading-normal sm:leading-relaxed md:leading-loose tracking-normal sm:tracking-wide">
  响应式行高和字间距的文本内容。
</p>

<!-- 响应式文本截断 -->
<div class="w-full">
  <p class="truncate sm:whitespace-normal">
    这是一段很长的文本,在小屏幕上会被截断,在大屏幕上正常显示。
  </p>
</div>

响应式表单

<!-- 响应式表单布局 -->
<form class="space-y-6">
  <!-- 响应式表单组 -->
  <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
    <div>
      <label class="block text-sm font-medium text-gray-700 mb-2">
        姓名
      </label>
      <input type="text" 
             class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
    </div>
    
    <div>
      <label class="block text-sm font-medium text-gray-700 mb-2">
        邮箱
      </label>
      <input type="email" 
             class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
    </div>
  </div>
  
  <!-- 全宽字段 -->
  <div>
    <label class="block text-sm font-medium text-gray-700 mb-2">
      消息
    </label>
    <textarea rows="4" 
              class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
    </textarea>
  </div>
  
  <!-- 响应式按钮组 -->
  <div class="flex flex-col sm:flex-row gap-4 sm:justify-end">
    <button type="button" 
            class="w-full sm:w-auto px-6 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50">
      取消
    </button>
    <button type="submit" 
            class="w-full sm:w-auto px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
      提交
    </button>
  </div>
</form>

<!-- 响应式搜索栏 -->
<div class="flex flex-col sm:flex-row gap-4">
  <div class="flex-1">
    <input type="search" 
           placeholder="搜索..." 
           class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
  </div>
  <button class="w-full sm:w-auto px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
    搜索
  </button>
</div>

实际应用案例

响应式电商产品页面

<div class="min-h-screen bg-gray-50">
  <!-- 响应式头部 -->
  <header class="bg-white shadow-sm">
    <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
      <div class="flex items-center justify-between h-16">
        <!-- Logo -->
        <div class="flex items-center">
          <img class="h-8 w-auto" src="logo.svg" alt="Logo">
          <span class="ml-2 text-xl font-bold text-gray-900 hidden sm:block">
            商店名称
          </span>
        </div>
        
        <!-- 搜索栏 -->
        <div class="flex-1 max-w-lg mx-4 hidden md:block">
          <div class="relative">
            <input type="search" 
                   placeholder="搜索产品..." 
                   class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
            <div class="absolute inset-y-0 left-0 pl-3 flex items-center">
              <svg class="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
              </svg>
            </div>
          </div>
        </div>
        
        <!-- 用户操作 -->
        <div class="flex items-center space-x-4">
          <button class="p-2 text-gray-400 hover:text-gray-500">
            <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"></path>
            </svg>
          </button>
          <button class="p-2 text-gray-400 hover:text-gray-500 relative">
            <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3h2l.4 2M7 13h10l4-8H5.4m0 0L7 13m0 0l-2.5 5M7 13l2.5 5m6 0a1 1 0 100-2 1 1 0 000 2zm-6 0a1 1 0 100-2 1 1 0 000 2z"></path>
            </svg>
            <span class="absolute -top-1 -right-1 h-4 w-4 bg-red-500 text-white text-xs rounded-full flex items-center justify-center">
              3
            </span>
          </button>
        </div>
      </div>
      
      <!-- 移动端搜索栏 -->
      <div class="md:hidden pb-4">
        <input type="search" 
               placeholder="搜索产品..." 
               class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
      </div>
    </div>
  </header>
  
  <!-- 主要内容 -->
  <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
    <!-- 面包屑导航 -->
    <nav class="flex mb-8 text-sm">
      <a href="#" class="text-gray-500 hover:text-gray-700">首页</a>
      <span class="mx-2 text-gray-400">/</span>
      <a href="#" class="text-gray-500 hover:text-gray-700">电子产品</a>
      <span class="mx-2 text-gray-400">/</span>
      <span class="text-gray-900">智能手机</span>
    </nav>
    
    <!-- 产品详情 -->
    <div class="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12">
      <!-- 产品图片 -->
      <div class="space-y-4">
        <div class="aspect-w-1 aspect-h-1 bg-gray-200 rounded-lg overflow-hidden">
          <img src="product-main.jpg" 
               alt="产品主图" 
               class="w-full h-full object-center object-cover">
        </div>
        
        <!-- 缩略图 -->
        <div class="grid grid-cols-4 gap-4">
          <div class="aspect-w-1 aspect-h-1 bg-gray-200 rounded-md overflow-hidden cursor-pointer">
            <img src="product-thumb-1.jpg" alt="缩略图 1" class="w-full h-full object-center object-cover">
          </div>
          <div class="aspect-w-1 aspect-h-1 bg-gray-200 rounded-md overflow-hidden cursor-pointer">
            <img src="product-thumb-2.jpg" alt="缩略图 2" class="w-full h-full object-center object-cover">
          </div>
          <div class="aspect-w-1 aspect-h-1 bg-gray-200 rounded-md overflow-hidden cursor-pointer">
            <img src="product-thumb-3.jpg" alt="缩略图 3" class="w-full h-full object-center object-cover">
          </div>
          <div class="aspect-w-1 aspect-h-1 bg-gray-200 rounded-md overflow-hidden cursor-pointer">
            <img src="product-thumb-4.jpg" alt="缩略图 4" class="w-full h-full object-center object-cover">
          </div>
        </div>
      </div>
      
      <!-- 产品信息 -->
      <div class="space-y-6">
        <div>
          <h1 class="text-2xl sm:text-3xl lg:text-4xl font-bold text-gray-900">
            iPhone 15 Pro Max
          </h1>
          <p class="mt-2 text-lg text-gray-600">
            最新一代智能手机,配备先进的A17 Pro芯片
          </p>
        </div>
        
        <!-- 评分 -->
        <div class="flex items-center space-x-2">
          <div class="flex items-center">
            <svg class="w-5 h-5 text-yellow-400" fill="currentColor" viewBox="0 0 20 20">
              <path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/>
            </svg>
            <span class="text-sm text-gray-600 ml-1">4.8 (2,847 评价)</span>
          </div>
        </div>
        
        <!-- 价格 -->
        <div class="space-y-2">
          <div class="flex items-baseline space-x-2">
            <span class="text-3xl font-bold text-gray-900">¥9,999</span>
            <span class="text-lg text-gray-500 line-through">¥10,999</span>
            <span class="px-2 py-1 bg-red-100 text-red-800 text-sm font-medium rounded">
              限时优惠
            </span>
          </div>
          <p class="text-sm text-gray-600">
            分期付款低至 ¥833/月
          </p>
        </div>
        
        <!-- 选项 -->
        <div class="space-y-4">
          <!-- 颜色选择 -->
          <div>
            <h3 class="text-sm font-medium text-gray-900 mb-3">颜色</h3>
            <div class="flex space-x-3">
              <button class="w-8 h-8 bg-gray-800 rounded-full border-2 border-gray-300 focus:border-gray-500">
                <span class="sr-only">深空灰色</span>
              </button>
              <button class="w-8 h-8 bg-blue-600 rounded-full border-2 border-gray-300 focus:border-gray-500">
                <span class="sr-only">海蓝色</span>
              </button>
              <button class="w-8 h-8 bg-purple-600 rounded-full border-2 border-gray-300 focus:border-gray-500">
                <span class="sr-only">紫色</span>
              </button>
            </div>
          </div>
          
          <!-- 存储容量 -->
          <div>
            <h3 class="text-sm font-medium text-gray-900 mb-3">存储容量</h3>
            <div class="grid grid-cols-2 sm:grid-cols-4 gap-3">
              <button class="px-3 py-2 text-sm border border-gray-300 rounded-md hover:border-gray-400 focus:border-blue-500">
                128GB
              </button>
              <button class="px-3 py-2 text-sm border border-blue-500 bg-blue-50 text-blue-700 rounded-md">
                256GB
              </button>
              <button class="px-3 py-2 text-sm border border-gray-300 rounded-md hover:border-gray-400 focus:border-blue-500">
                512GB
              </button>
              <button class="px-3 py-2 text-sm border border-gray-300 rounded-md hover:border-gray-400 focus:border-blue-500">
                1TB
              </button>
            </div>
          </div>
        </div>
        
        <!-- 操作按钮 -->
        <div class="space-y-4">
          <button class="w-full bg-blue-600 text-white py-3 px-6 rounded-md text-lg font-medium hover:bg-blue-700 transition-colors">
            立即购买
          </button>
          <button class="w-full border border-gray-300 text-gray-700 py-3 px-6 rounded-md text-lg font-medium hover:bg-gray-50 transition-colors">
            加入购物车
          </button>
        </div>
        
        <!-- 产品特性 -->
        <div class="border-t pt-6">
          <h3 class="text-lg font-medium text-gray-900 mb-4">产品特性</h3>
          <ul class="space-y-2 text-sm text-gray-600">
            <li class="flex items-center">
              <svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
                <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
              </svg>
              A17 Pro 芯片,性能提升 20%
            </li>
            <li class="flex items-center">
              <svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
                <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
              </svg>
              Pro 级别摄像头系统
            </li>
            <li class="flex items-center">
              <svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
                <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
              </svg>
              全天候电池续航
            </li>
            <li class="flex items-center">
              <svg class="w-4 h-4 text-green-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
                <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"/>
              </svg>
              IP68 防水等级
            </li>
          </ul>
        </div>
      </div>
    </div>
    
    <!-- 相关产品 -->
    <section class="mt-16">
      <h2 class="text-2xl font-bold text-gray-900 mb-8">相关产品</h2>
      <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
        <!-- 产品卡片 -->
        <div class="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow">
          <div class="aspect-w-1 aspect-h-1">
            <img src="related-product-1.jpg" alt="相关产品" class="w-full h-48 object-cover">
          </div>
          <div class="p-4">
            <h3 class="text-lg font-medium text-gray-900 mb-2">iPhone 15</h3>
            <p class="text-gray-600 text-sm mb-2">标准版智能手机</p>
            <div class="flex items-center justify-between">
              <span class="text-xl font-bold text-gray-900">¥6,999</span>
              <button class="px-3 py-1 bg-blue-600 text-white text-sm rounded hover:bg-blue-700">
                查看
              </button>
            </div>
          </div>
        </div>
        
        <!-- 重复其他产品卡片... -->
      </div>
    </section>
  </main>
</div>

响应式博客布局

<div class="min-h-screen bg-gray-50">
  <!-- 响应式头部 -->
  <header class="bg-white shadow-sm sticky top-0 z-50">
    <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
      <div class="flex items-center justify-between h-16">
        <div class="flex items-center">
          <h1 class="text-xl sm:text-2xl font-bold text-gray-900">
            我的博客
          </h1>
        </div>
        
        <nav class="hidden md:flex space-x-8">
          <a href="#" class="text-gray-700 hover:text-blue-600 font-medium">首页</a>
          <a href="#" class="text-gray-700 hover:text-blue-600 font-medium">文章</a>
          <a href="#" class="text-gray-700 hover:text-blue-600 font-medium">分类</a>
          <a href="#" class="text-gray-700 hover:text-blue-600 font-medium">关于</a>
        </nav>
        
        <button class="md:hidden p-2">
          <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
          </svg>
        </button>
      </div>
    </div>
  </header>
  
  <!-- 主要内容 -->
  <main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
    <div class="grid grid-cols-1 lg:grid-cols-4 gap-8">
      <!-- 文章列表 -->
      <div class="lg:col-span-3 space-y-8">
        <!-- 特色文章 -->
        <article class="bg-white rounded-lg shadow-md overflow-hidden">
          <div class="md:flex">
            <div class="md:w-1/3">
              <img src="featured-post.jpg" 
                   alt="特色文章" 
                   class="w-full h-48 md:h-full object-cover">
            </div>
            <div class="p-6 md:w-2/3">
              <div class="flex items-center text-sm text-gray-500 mb-2">
                <span>2024年1月15日</span>
                <span class="mx-2">•</span>
                <span>技术</span>
              </div>
              <h2 class="text-xl sm:text-2xl font-bold text-gray-900 mb-3">
                UnoCSS:下一代原子化CSS引擎
              </h2>
              <p class="text-gray-600 mb-4 line-clamp-3">
                UnoCSS是一个即时按需的原子化CSS引擎,它提供了极高的性能和灵活性...
              </p>
              <div class="flex items-center justify-between">
                <div class="flex items-center space-x-2">
                  <img src="author.jpg" alt="作者" class="w-8 h-8 rounded-full">
                  <span class="text-sm text-gray-700">张三</span>
                </div>
                <a href="#" class="text-blue-600 hover:text-blue-800 font-medium">
                  阅读更多 →
                </a>
              </div>
            </div>
          </div>
        </article>
        
        <!-- 普通文章列表 -->
        <div class="grid grid-cols-1 md:grid-cols-2 gap-6">
          <article class="bg-white rounded-lg shadow-md overflow-hidden">
            <img src="post-1.jpg" alt="文章1" class="w-full h-48 object-cover">
            <div class="p-6">
              <div class="flex items-center text-sm text-gray-500 mb-2">
                <span>2024年1月10日</span>
                <span class="mx-2">•</span>
                <span>设计</span>
              </div>
              <h3 class="text-lg font-semibold text-gray-900 mb-2">
                响应式设计的最佳实践
              </h3>
              <p class="text-gray-600 text-sm mb-4 line-clamp-2">
                在移动设备普及的今天,响应式设计已经成为了网页开发的标准...
              </p>
              <a href="#" class="text-blue-600 hover:text-blue-800 font-medium text-sm">
                阅读更多 →
              </a>
            </div>
          </article>
          
          <article class="bg-white rounded-lg shadow-md overflow-hidden">
            <img src="post-2.jpg" alt="文章2" class="w-full h-48 object-cover">
            <div class="p-6">
              <div class="flex items-center text-sm text-gray-500 mb-2">
                <span>2024年1月8日</span>
                <span class="mx-2">•</span>
                <span>开发</span>
              </div>
              <h3 class="text-lg font-semibold text-gray-900 mb-2">
                JavaScript ES2024 新特性
              </h3>
              <p class="text-gray-600 text-sm mb-4 line-clamp-2">
                ES2024带来了许多令人兴奋的新特性,让我们一起来看看...
              </p>
              <a href="#" class="text-blue-600 hover:text-blue-800 font-medium text-sm">
                阅读更多 →
              </a>
            </div>
          </article>
        </div>
        
        <!-- 分页 -->
        <div class="flex items-center justify-center space-x-2">
          <button class="px-3 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50">
            上一页
          </button>
          <button class="px-3 py-2 text-sm bg-blue-600 text-white rounded-md">
            1
          </button>
          <button class="px-3 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50">
            2
          </button>
          <button class="px-3 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50">
            3
          </button>
          <button class="px-3 py-2 text-sm border border-gray-300 rounded-md hover:bg-gray-50">
            下一页
          </button>
        </div>
      </div>
      
      <!-- 侧边栏 -->
      <aside class="lg:col-span-1 space-y-6">
        <!-- 搜索 -->
        <div class="bg-white p-6 rounded-lg shadow-md">
          <h3 class="text-lg font-semibold text-gray-900 mb-4">搜索</h3>
          <div class="relative">
            <input type="search" 
                   placeholder="搜索文章..." 
                   class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
            <div class="absolute inset-y-0 left-0 pl-3 flex items-center">
              <svg class="h-5 w-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
              </svg>
            </div>
          </div>
        </div>
        
        <!-- 分类 -->
        <div class="bg-white p-6 rounded-lg shadow-md">
          <h3 class="text-lg font-semibold text-gray-900 mb-4">分类</h3>
          <ul class="space-y-2">
            <li>
              <a href="#" class="flex items-center justify-between text-gray-700 hover:text-blue-600">
                <span>技术</span>
                <span class="text-sm text-gray-500">12</span>
              </a>
            </li>
            <li>
              <a href="#" class="flex items-center justify-between text-gray-700 hover:text-blue-600">
                <span>设计</span>
                <span class="text-sm text-gray-500">8</span>
              </a>
            </li>
            <li>
              <a href="#" class="flex items-center justify-between text-gray-700 hover:text-blue-600">
                <span>生活</span>
                <span class="text-sm text-gray-500">5</span>
              </a>
            </li>
          </ul>
        </div>
        
        <!-- 热门文章 -->
        <div class="bg-white p-6 rounded-lg shadow-md">
          <h3 class="text-lg font-semibold text-gray-900 mb-4">热门文章</h3>
          <div class="space-y-4">
            <div class="flex space-x-3">
              <img src="popular-1.jpg" alt="热门文章" class="w-16 h-16 object-cover rounded">
              <div class="flex-1">
                <h4 class="text-sm font-medium text-gray-900 line-clamp-2">
                  CSS Grid 完全指南
                </h4>
                <p class="text-xs text-gray-500 mt-1">2024年1月5日</p>
              </div>
            </div>
            
            <div class="flex space-x-3">
              <img src="popular-2.jpg" alt="热门文章" class="w-16 h-16 object-cover rounded">
              <div class="flex-1">
                <h4 class="text-sm font-medium text-gray-900 line-clamp-2">
                  React Hooks 最佳实践
                </h4>
                <p class="text-xs text-gray-500 mt-1">2024年1月3日</p>
              </div>
            </div>
          </div>
        </div>
        
        <!-- 标签云 -->
        <div class="bg-white p-6 rounded-lg shadow-md">
          <h3 class="text-lg font-semibold text-gray-900 mb-4">标签</h3>
          <div class="flex flex-wrap gap-2">
            <span class="px-3 py-1 bg-gray-100 text-gray-700 text-sm rounded-full hover:bg-gray-200 cursor-pointer">
              CSS
            </span>
            <span class="px-3 py-1 bg-gray-100 text-gray-700 text-sm rounded-full hover:bg-gray-200 cursor-pointer">
              JavaScript
            </span>
            <span class="px-3 py-1 bg-gray-100 text-gray-700 text-sm rounded-full hover:bg-gray-200 cursor-pointer">
              React
            </span>
            <span class="px-3 py-1 bg-gray-100 text-gray-700 text-sm rounded-full hover:bg-gray-200 cursor-pointer">
              Vue
            </span>
            <span class="px-3 py-1 bg-gray-100 text-gray-700 text-sm rounded-full hover:bg-gray-200 cursor-pointer">
              Node.js
            </span>
          </div>
        </div>
      </aside>
    </div>
  </main>
</div>

性能优化建议

移动优先策略

/* 移动优先的CSS生成 */
/* 基础样式(移动端) */
.container {
  padding: 1rem;
}

/* 平板及以上 */
@media (min-width: 768px) {
  .container {
    padding: 2rem;
  }
}

/* 桌面及以上 */
@media (min-width: 1024px) {
  .container {
    padding: 3rem;
  }
}

减少媒体查询数量

// 优化断点使用
// 避免过多的断点变化
// 好的做法
<div class="text-sm md:text-base lg:text-lg">

// 避免的做法
<div class="text-xs sm:text-sm md:text-base lg:text-lg xl:text-xl 2xl:text-2xl">

图片响应式优化

<!-- 响应式图片 -->
<picture>
  <source media="(min-width: 1024px)" srcset="large.webp" type="image/webp">
  <source media="(min-width: 768px)" srcset="medium.webp" type="image/webp">
  <source media="(min-width: 1024px)" srcset="large.jpg">
  <source media="(min-width: 768px)" srcset="medium.jpg">
  <img src="small.jpg" alt="响应式图片" class="w-full h-auto">
</picture>

<!-- 使用CSS控制图片显示 -->
<div class="relative">
  <img src="mobile.jpg" alt="移动端" class="w-full h-auto md:hidden">
  <img src="desktop.jpg" alt="桌面端" class="w-full h-auto hidden md:block">
</div>

本章总结

通过本章学习,我们全面掌握了:

  1. 响应式设计基础:核心原则和UnoCSS的实现方法
  2. 断点系统:默认断点、自定义断点和高级变体
  3. 响应式布局:容器、网格、Flexbox等布局技巧
  4. 高级技巧:显示隐藏、排版、表单等响应式处理
  5. 实际应用:电商页面、博客布局等完整案例
  6. 性能优化:移动优先、减少媒体查询、图片优化等

核心要点

  • 移动优先是现代响应式设计的基础
  • 合理使用断点,避免过度复杂化
  • 响应式不仅仅是布局,还包括字体、间距、交互等
  • 性能优化是响应式设计的重要考虑因素

下一步

在下一章中,我们将学习如何创建自定义规则和变体,进一步扩展UnoCSS的功能。

练习题

  1. 响应式导航:创建一个在移动端折叠、桌面端展开的导航栏
  2. 卡片网格:实现一个响应式的产品卡片网格布局
  3. 自定义断点:为特定项目需求创建自定义断点系统
  4. 性能测试:比较不同响应式策略的性能差异
  5. 完整页面:设计并实现一个完整的响应式着陆页