ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Tailwind CSS Grid 响应式布局实战:从 3 列基础栅格到 16 列自定义扩展(refine 项目实践)

2026/9/10 2:01:21 拓冰建站 浏览量
Tailwind CSS Grid 响应式布局实战:从 3 列基础栅格到 16 列自定义扩展(refine 项目实践) Tailwind CSS Grid 响应式布局实战从 3 列基础栅格到 16 列自定义扩展refine 项目实践【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine导读本文以 Tailwind CSS 的 Grid 工具类为核心从 Block Formatting ContextBFC出发逐步引入grid、grid-cols-{n}、gap-{size}、col-span-{n}、grid-rows-{n}等类最终实现一个包含导航栏、侧栏、主内容区和页脚的响应式页面骨架。读完本文你将掌握 Tailwind Grid 的完整用法含移动优先断点语义、跨列跨行、断点重排并能在tailwind.config.js中把默认 12 列栅格扩展为 16 列。文章同时结合 refine 仓库中真实示例examples/store、examples/blog-refine-daisyui、examples/blog-refine-shadcn给出可复制的实战佐证。Tailwind 的 Grid 系统为什么不用 Flexbox 切分宽度Tailwind CSS简称 Tailwind是一个用于快速构建网站的 CSS 框架内置了一批开箱即用的工具类utility classes可以按需组合并能在后续通过配置文件轻易定制以适配任意设计在响应式、布局与主题上的需求。在 Tailwind 1.2 之前的版本里构建多列布局通常依赖 Flexbox 工具类用w-{fraction}如w-1/3手工把容器的宽度切分成若干列。而从 1.2 版本起Tailwind 提供了一整套基于原生 CSS Grid 的类可以构建更精细的多行多列布局。与 Twitter Bootstrap、Foundation 这类底层仍用 Flexbox 实现 12 列栅格的框架不同Tailwind 直接使用 CSS Grid让我们可以构建任意列数与行数、高度可定制的布局。它提供的 Grid 容器类包括grid启用 Grid Formatting Contextgrid-cols-{n}定义列数grid-rows-{n}定义行数以及用于控制 Grid 子元素行为的类例如col-span-{n}、row-span-{n}、col-start-{n}、col-end-{n}、row-start-{n}、row-end-{n}等。Tailwind 默认配置最多支持单屏 12 列可以通过tailwind.config.js自定义与 Grid 相关的许多选项都可以按需调整。本文后面会演示如何把列数上限扩展到 16。建议进一步查阅 Tailwind CSS 官方文档中 grid-template-columns 及其后续的 grid-column-start / grid-column-end / grid-template-rows 等章节作为工具类的完整参考。项目目标一个 3 列 5 行的页面骨架我们从一个最简单的 HTML 文档开始逐步实现如下目标布局顶部导航栏navbar左侧内容区side content主内容区main content底部页脚footer这个布局由 3 列、5 行组成。我们会先用一组遵循 Block Formatting ContextBFC的div起步再按需引入 Grid 相关类逐步过渡到 Grid Formatting ContextGFC在过程中理解每一类的作用。项目初始化与开发环境准备动手前先准备好环境克隆配套的演示仓库包含上述目标布局的起步代码在代码编辑器中打开。确保编辑器安装了 Live Server 插件并处于启用状态。安装依赖并编译样式使用 Tailwind CLI 监视模式npx tailwindcss -i ./src/styles.css -o ./dist/styles.css --watch启动 Live Server点击编辑器右下角的Go Live按钮或在浏览器中直接访问 Live Server 提供的端口号。index.html通过link引入编译产物/dist/styles.css改动源码后 Tailwind 会在监视模式下自动重新生成样式。基础示例一个 9 宫格页面先看起步用的index.html它由 9 个不同背景色的tile组成目前只是普通块级元素BFC从上到下依次堆叠!-- index.html -- !DOCTYPE html html langen head meta charsetUTF-8 / meta http-equivX-UA-Compatible contentIEedge / meta nameviewport contentwidthdevice-width, initial-scale1.0 / link href/dist/styles.css relstylesheet / titleDocument/title /head body div classcontainer m-auto div classtile bg-teal-500 h1 classtile-markerONE/h1 /div div classtile bg-amber-500 h1 classtile-markerTWO/h1 /div div classtile bg-yellow-500 h1 classtile-markerTHREE/h1 /div div classtile bg-lime-600 h1 classtile-markerFOUR/h1 /div div classtile bg-green-600 h1 classtile-markerFIVE/h1 /div div classtile bg-emerald-500 h1 classtile-markerSIX/h1 /div div classtile bg-teal-500 h1 classtile-markerSEVEN/h1 /div div classtile bg-purple-500 h1 classtile-markerEIGHT/h1 /div div classtile bg-pink-500 h1 classtile-markerNINE/h1 /div /div /body /html建立 Grid Formatting Contextgrid类看似什么都不发生给容器加上grid类div classcontainer m-auto grid/div此时页面看不出任何变化——因为默认的grid只有一列子元素仍然按一列堆叠。但布局上下文已经从 BFC 切换为 Grid Formatting ContextGFC。grid-cols-{n}显式声明列数添加三列div classcontainer m-auto grid grid-cols-3/div现在 9 个div按 Grid Formatting Context 流入了 3 列。需要注意的是grid-cols-3并不是简单地“把屏幕切成 3 等份”其底层 CSS 等价于grid-template-columns: repeat(3, minmax(0, 1fr));即每列都是1fr弹性轨道且用minmax(0, 1fr)防止内容的最小内容尺寸min-content把轨道撑爆——这是 Tailwind Grid 列宽行为的关键细节也是它比手动写1fr更稳妥的原因。gap-{size}设置栅格间距间距需要设置在 Grid 容器上而不是子元素上div classcontainer m-auto grid grid-cols-3 gap-4/divgap-4会为子元素之间添加统一的间距同时作用于行与列。Tailwind 也提供gap-x-{size}与gap-y-{size}分别控制水平、垂直方向的间距。响应式列数md:与lg:前缀在更大断点下增加列数div classcontainer m-auto grid grid-cols-3 gap-4 md:grid-cols-5 lg:grid-cols-8 /div这里用到 Tailwind 默认断点体系中的md768px和lg1024px。观察页面缩放可以看到列数在 768px、1024px 两处递增。这里有一个非常重要的语义Tailwind 的响应式前缀md、lg等不是“屏幕尺寸”而是移动优先mobile-first断点。所以grid-cols-3对所有屏幕尺寸都生效3 列是基线屏幕宽度超过md≥768px后列数变为 5屏幕宽度超过lg≥1024px后列数变为 8之后没有再次改变所以即使到了xl、2xl仍然是 8 列。这意味着一套类即可覆盖从小屏到大屏的完整响应式曲线前提是理解“前缀代表 min-width 阈值而非某个具体设备”。控制尺寸与位置span 与 start/endGrid 的尺寸与放置类给了我们更多控制某个区块跨几列、从哪一列开始、到哪一列结束。用col-span-{n}设置跨列尺寸把第一个div当作导航栏让它从栅格起点开始、在每个屏幕尺寸下都横跨整行div classtile col-span-3 bg-teal-500 md:col-span-5 lg:col-span-8 h1 classtile-markerONE/h1 /div注意这里在三个断点分别写col-span-3、md:col-span-5、lg:col-span-8恰好等于对应断点下的总列数即“占满整行”。当需要“始终占满整行”时可以简化为col-span-fulldiv classtile col-span-full bg-teal-500 h1 classtile-markerONE/h1 /div也可以用col-start-{n}与col-end-{n}组合达到同样效果div classtile col-start-1 col-end-4 bg-teal-500 md:col-start-1 md:col-end-6 lg:col-start-1 lg:col-end-9 h1 classtile-markerONE/h1 /div但请看这里每个断点都要同时写 start 和 end 两组响应式类md:col-start-1 md:col-end-6 lg:col-start-1 lg:col-end-9既不 DRY也容易出错。col-span-{n}更适合表达“尺寸”而 start/end 更擅长表达“位置”。继续设置第二、第三个div的宽度div classtile col-span-1 bg-amber-500 md:col-span-2 lg:col-span-3 h1 classtile-markerTWO/h1 /div div classtile col-span-2 bg-yellow-500 md:col-span-3 lg:col-span-5 h1 classtile-markerTHREE/h1 /div用col-start-{n}放置元素start 负责位置、span 负责尺寸单独使用col-span-{n}时对元素在栅格中的放置自由度有限而单独使用col-start-{n}/col-end-{n}又会在响应式场景下带来大量重复。最佳实践是组合使用start 类定位span 类定宽高。以第四个div为例让它在lg断点从第 4 列开始、向右跨 2 列div classtile bg-lime-600 lg:col-span-2 lg:col-start-4 h1 classtile-markerFOUR/h1 /div可以看到从lg起第四个div从第 4 列开始向右跨两列代码比“start end 双写”精简得多。但此时如果仔细观察整体布局会发现它仍是一盘散沙最后两个div游离在整体之外。原因是我们只完成了“一半的方程式”——只用了 Grid 的列相关类还没有显式管理 Grid 的行。显式定义行grid-rows-{n}要对栅格有更精细的控制需要像声明列一样显式声明行数。目前行数是隐式implicit生成的现在我们显式声明 5 行div classcontainer m-auto grid grid-cols-3 grid-rows-5 gap-4 md:grid-cols-5 lg:grid-cols-8 /divgrid-rows-5对应grid-template-rows: repeat(5, minmax(0, 1fr))等价地创建 5 个等高的行轨道。用row-start-{n}把页脚放到最底行现在把最后一个div设置为页脚小屏时放到最底行的左侧md之后横跨整行div classtile row-start-5 bg-pink-500 md:col-span-full h1 classtile-markerNINE/h1 /divrow-start-5告诉页脚从第 5 行最底行开始放置配合md:col-span-full页脚在md之后铺满整行。跨行row-start-{n}row-end-{n}让第二个div占据导航栏与页脚之间的左侧整列——起点选在第 2 行、终点为第 5 行div classtile col-span-1 row-start-2 row-end-5 bg-amber-500 md:col-span-2 lg:col-span-3 h1 classtile-markerTWO/h1 /div此时页面开始成型顶部导航、左侧侧栏、右侧内容、底部页脚一个接近真实网站的布局已经出现。在不同断点重排区块Reorder Regions改变row-start-{n}/col-start-{n}中n的值就可以在不同断点重新排列区块顺序。例如把第三个div当作一个广告位小屏时展示在底部md之后移到顶部。先设置小屏顺序再在md覆盖div classtile col-span-2 row-start-4 row-end-5 bg-yellow-500 md:col-span-3 md:row-start-2 md:row-end-3 lg:col-span-5 h1 classtile-markerTHREE/h1 /div在小屏上它位于第 4 行接近底部一旦超过mdmd:row-start-2 md:row-end-3把它提升到第 2 行靠近顶部列宽也随之调整为md:col-span-3。这种“同一个 DOM 节点在不同断点出现在不同区域”的能力是 CSS Grid 相对于传统 float/Flexbox 布局的重要优势且无需改动 HTML 结构顺序。完整的最终代码整合以上所有步骤后最终的index.html如下!-- index.html -- !DOCTYPE html html langen head meta charsetUTF-8 / meta http-equivX-UA-Compatible contentIEedge / meta nameviewport contentwidthdevice-width, initial-scale1.0 / link href/dist/styles.css relstylesheet / titleDocument/title /head body div classcontainer m-auto grid grid-cols-3 grid-rows-5 gap-4 md:grid-cols-5 lg:grid-cols-8 div classtile col-span-full bg-teal-500 h1 classtile-markerONE/h1 /div div classtile col-span-1 row-start-2 row-end-5 bg-amber-500 md:col-span-2 lg:col-span-3 h1 classtile-markerTWO/h1 /div div classtile col-span-2 row-start-4 row-end-5 bg-yellow-500 md:col-span-3 md:row-start-2 md:row-end-3 lg:col-span-5 h1 classtile-markerTHREE/h1 /div div classtile bg-lime-600 lg:col-span-2 lg:col-start-4 h1 classtile-markerFOUR/h1 /div div classtile bg-green-600 h1 classtile-markerFIVE/h1 /div div classtile bg-emerald-500 h1 classtile-markerSIX/h1 /div div classtile bg-teal-500 h1 classtile-markerSEVEN/h1 /div div classtile bg-purple-500 h1 classtile-markerEIGHT/h1 /div div classtile row-start-5 bg-pink-500 md:col-span-full h1 classtile-markerNINE/h1 /div /div /body /htmlTailwind CSS Grid 类速查表类作用示例grid启用 Grid 布局div classgrid/divgrid-cols-{n}设置列数grid-cols-3gap-{size}在栅格项之间添加间距gap-4col-span-{n}让栅格项跨越多列col-span-2row-start-{n}设置栅格项的起始行row-start-2grid-rows-{n}设置行数grid-rows-5在此基础上还有对称的row-span-{n}、row-end-{n}、col-start-{n}、col-end-{n}以及独立的gap-x-{size}/gap-y-{size}可以按需组合出任意二维栅格结构。自定义 Tailwind 主题把列数扩展到 16Tailwind 的 Grid 相关配置都可以按需修改。假设业务设计需要最多16 列那么必须能生成从 0 到 16 的所有grid-cols-{n}类同时还要生成对应的col-start-{n}与col-end-{n}类。在tailwind.config.js中通过extend扩展gridTemplateColumns、gridColumnStart、gridColumnEnd三个属性即可// tailwind.config.js module.exports { theme: { extend: { gridTemplateColumns: { // Simple 16 column grid 16: repeat(16, minmax(0, 1fr)), }, gridColumnStart: { 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, }, gridColumnEnd: { 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, }, }, }, };说明几点gridTemplateColumns: { 16: ... }生成grid-cols-16类n从 1 到 12 的类由默认主题提供extend不会覆盖它们。16 列栅格中元素的起始/结束行号理论上最多到 17因为列线数量 列数 1所以gridColumnStart与gridColumnEnd需要补上 13 到 17 的取值。配置完成后重新构建样式npx tailwindcss -i ./src/styles.css -o ./dist/styles.css --watch会自动触发grid-cols-16、col-start-13等类即可直接使用。这种“扩展生成规则”的思路也适用于其他维度。在 refine 仓库中可以看到大量同类实践examples/store/tailwind.config.js 通过theme.extend.screens自定义了整套断点2xsmall: 320px、small: 1024px、medium: 1280px、large: 1440px、xlarge: 1680px等说明断点体系本身也可以按项目需求重定义examples/blog-refine-shadcn/tailwind.config.js 通过content指定了pages/、components/、app/、src/等目录Tailwind 只从这些路径扫描类名并生成用到的工具类examples/blog-refine-daisyui/tailwind.config.js 同样声明了content: [./index.html, ./src/**/*.{js,ts,jsx,tsx}]并挂载daisyui插件——这说明 Grid 类与其他工具类遵循同一套 JIT 扫描机制只有出现在源码里的类才会被编译进产物。refine 仓库中的真实 Grid 用法佐证本文的布局思路在 refine 仓库的 Tailwind 示例中有大量同款实践可以作为进阶参考电商示例响应式商品栅格examples/store/pages/index.tsx 中的商品列表容器就是标准的“移动优先列数递增”写法className{clsx( flex-1, grid, grid-cols-1, md:grid-cols-2, lg:grid-cols-3, gap-x-8, gap-y-16, )}基线 1 列 →md起 2 列 →lg起 3 列用gap-x-8/gap-y-16分别控制列间距与行间距比gap-{size}更精细。这与本文“grid-cols-{n}定列数 断点前缀定切换时机”的方法完全一致只是把{n}换成了 1/2/3并叠加了商品卡片组件。账号概览apply组合 Grid 类examples/store/src/components/account/OverviewTemplate/OverviewTemplate.module.css 展示了在 CSS 中通过apply复用 Grid 工具类.overviewWapper { apply col-span-1 row-span-2 flex h-full flex-1 flex-col gap-y-4; }以及同文件中的grid grid-cols-3 grid-rows-2 gap-x-4第 78 行用一个 3 列 2 行的显式栅格组织数据展示区域。这印证了grid-rows-{n}与col-span-{n}在真实后台/电商界面中的典型用法。集成方式CLI 与 PostCSS 两条路线本文开头的npx tailwindcss ... --watch是 Tailwind CLI 路线refine 的 Tailwind 示例则普遍采用 PostCSS 集成每个示例都同时包含 postcss.config.js 与 tailwind.config.js在 Vite/Next.js 构建链中由 PostCSS 插件处理 Tailwind。两种方式生成的类完全一致选择哪一种取决于项目构建工具。常见问题FAQQ如何在 Tailwind CSS 中创建类似 CSS Grid 的响应式布局A将grid与grid-cols-{n}组合用于定义列并为md:、lg:等响应式前缀添加对应的列数变体即可在指定断点调整布局。QFlexbox 与 Grid 在 Tailwind 中的主要区别是什么AFlexbox 适合简单的一维布局行或列而 Grid 适合同时涉及行与列的复杂二维布局。本文的目标页面导航 侧栏 主内容 页脚就是典型的二维场景应优先选择 Grid。Q如何在 Tailwind 中为栅格项添加间距A使用gap-{size}类例如gap-4可为所有方向提供一致的间距如需分别控制用gap-x-{size}与gap-y-{size}。Q可以自定义 Tailwind Grid 可用的列数吗A可以。在tailwind.config.js中扩展gridTemplateColumns属性以及配套的gridColumnStart/gridColumnEnd即可生成自定义数量的列类例如本文演示的 16 列栅格。结语本文使用 Tailwind 的 CSS Grid 类构建了一个简单的响应式布局通过grid-cols-{n}与grid-rows-{n}显式声明行列数通过md:、lg:等移动优先断点在不同屏幕宽度下重置布局并用col-span-{n}、col-start-{n}、row-start-{n}、row-end-{n}精确控制每个区块的尺寸与位置甚至可以在断点切换时重排区块顺序。更进一步Tailwind 允许我们通过tailwind.config.js扩展生成类的规则——无论是把列数从 12 扩展到 16还是像 refine 仓库的 store 示例 那样重定义整套断点——从而构建完全贴合业务需求的流畅响应式布局。这套“显式行列 断点前缀 扩展主题”的方法论同样适用于 refine 构建后台面板、仪表盘等二维密集型界面时的布局工作。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考