响应式布局终极方案:UnoCSS+Grid/Flex实战技巧

1,949 阅读2分钟

COVER.png 作为一个天天和布局死磕的前端,咱们都经历过这样的场景:在不同屏幕尺寸下反复调试CSS,代码越写越臃肿。今天给大家安利一套「UnoCSS+Grid/Flex」组合拳,配合真实代码示例,看看如何把响应式布局玩出花。


一、先整点狠活:UnoCSS响应式原理

先看这段配置(uno.config.ts):

// 自定义断点系统
export default defineConfig({
  theme: {
    breakpoints: {
      xs: '320px',
      sm: '640px',
      md: '768px',
      lg: '1024px',
      xl: '1280px'
    }
  },
  presets: [
    presetUno(),
    presetAttributify()
  ]
})

核心优势:通过lg:hover:text-red这样的原子类,直接在类名里声明不同断点的样式变化,不用写冗余的媒体查询。


二、Grid布局的暴力美学

2.1 列宽自动分配

<!-- 基础网格:列宽自动分配 -->
<div class="grid grid-cols-[repeat(auto-fit,minmax(250px,1fr))] gap-4">
  <div class="h-40 bg-blue-400"></div>
  <div class="h-40 bg-green-400"></div>
  <div class="h-40 bg-red-400"></div>
</div>

运行效果 image.png 代码解释

2.2 响应式调整列

<!-- 响应式调整列数 -->
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
  <div class="h-40 bg-blue-400"></div> 
  <div class="h-40 bg-green-400"></div> 
  <div class="h-40 bg-red-400"></div>
</div>

运行效果

image.png 代码解释

  • 直接通过断点前缀切换列数(md/lg)
  • 源码分享

2.3 间距控制黑科技

<div class="grid gap-x-4 gap-y-8 md:gap-6">
  <div class="h-40 bg-blue-400"></div> 
  <div class="h-40 bg-green-400"></div> 
  <div class="h-40 bg-red-400"></div>
</div>
  • 用UnoCSS生成的间距系统(基于theme.spacing),告别手动计算margin/padding
  • 源码分享

三、Flex布局的精准打击

3.1 经典导航栏布局

<nav class="flex items-center justify-between p-4 bg-white shadow-sm">
  <div class="flex gap-4"> <!-- Logo和文字间距 -->
    <img src="/logo.png" class="w-8 h-8"/>
    <span class="text-lg font-bold">我的站点</span>
  </div>
  
  <div class="flex gap-6 md:gap-8"> <!-- 响应式间距 -->
    <a class="hover:text-blue-500">首页</a>
    <a class="hover:text-blue-500">产品</a>
    <a class="hover:text-blue-500">关于</a>
  </div>
</nav>

运行效果

image.png

关键技巧

  • items-center垂直居中
  • justify-between两侧分散对齐
  • gap-*处理元素间距
  • 源码分享

3.2 移动端专属适配

<div class="flex flex-col space-y-4 md:(flex-row space-y-0 space-x-6)">
  <!-- 移动端纵向排列,PC端横向排列 -->
</div>

语法亮点:用括号语法组合多个断点样式


四、实战:电商首页布局

直接上硬核代码:

<section class="grid lg:grid-cols-3 gap-8 p-6">
  <!-- 主商品区 -->
  <div class="lg:col-span-2 grid sm:grid-cols-2 gap-4">
    <div class="group relative">
      <img src="product.jpg" class="w-full h-64 object-cover"/>
      <div class="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 transition-opacity">
        <button class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 bg-white px-6 py-2 rounded-full hover:bg-gray-100">
          查看详情
        </button>
      </div>
    </div>
  </div>

  <!-- 侧边栏 -->
  <aside class="border-l pl-8">
    <div class="sticky top-6">
      <h3 class="text-xl font-bold mb-4">猜你喜欢</h3>
      <div class="space-y-4">
        <div class="flex items-center gap-4 p-3 hover:bg-gray-50 rounded">
          <img src="related.jpg" class="w-16 h-16 object-cover rounded"/>
          <div>
            <p class="line-clamp-2 text-sm">商品描述文字...</p>
            <p class="text-red-500 mt-1">¥199</p>
          </div>
        </div>
      </div>
    </div>
  </aside>
</section>

运行效果

image.png

代码亮点

  • object-cover实现图片裁剪
  • group实现悬停整体控制
  • line-clamp-2文字截断
  • sticky实现吸顶效果
  • 源码分享

五、性能优化技巧

5.1 按需生成策略

// 过滤未使用的样式
safelist: [
  // 动态生成的安全列表
  /^grid-cols-\d+$/, 
  /^gap-[xy]?-\d+$/
]

5.2 暗黑模式切换

<html class="dark">
  <!-- 组件内直接使用 -->
  <div class="bg-white dark:bg-gray-800">
    <p class="text-gray-800 dark:text-gray-100">内容</p>
  </div>
</html>

最后,说点实在的

这套方案的爽点:

  1. 开发速度提升:不用在HTML和CSS文件之间反复横跳
  2. 代码可读性强:看到类名就知道元素表现
  3. 维护成本低:修改布局只需调整原子类组合

但也要注意:

  • 团队需要统一工具类规范
  • 复杂动画还是建议走独立CSS文件
  • 别魔怔,该写传统CSS的时候别硬凑原子类