用 Flexbox 攻克经典 CSS 布局难题:Solved by Flexbox 六大演示全解与本地构建指南
发布时间:2026/10/7 8:32:09 锦皓数字建站

示例工程【免费下载链接】solved-by-flexboxA showcase of problems once hard or impossible to solve with CSS alone, now made trivially easy with Flexbox.项目地址https://gitcode.com/gh_mirrors/so/solved-by-flexbox点击查看免费下载本指南围绕开源项目 Solved by FlexboxREADME.md展开它是一组以「曾经用纯 CSS 难以甚至无法解决、如今用 Flexbox 可轻松搞定」为主题的布局难题演示集合。文章将完整讲解项目的本地构建与运行方式并逐一深入剖析网格系统、圣杯布局、媒体对象、输入附加组件、粘性页脚、垂直居中六个演示的痛点、HTML/CSS 实现与源码级细节帮助你把这些方案直接复用到自己的项目中。项目定位把 Flexbox 的「逆袭」做成可运行演示正如 README.md 第一句所定义的A showcase of problems once hard or impossible to solve with CSS alone, now made trivially easy with Flexbox.——这个仓库展示的是一批过去仅靠 CSS 很难甚至无法解决、如今用 Flexbox 却变得异常简单的布局问题。package.json 中的description字段也复述了同样的定位。整个站点的核心内容位于 demos/ 目录由六个带 front matter 元数据template、title、excerpt的 Markdown 文档构成每个演示对应一套完整的「问题背景 演示 HTML 核心 CSS 跨浏览器兼容说明」演示文档主题对应组件样式demos/grids.md更简单、更好的网格系统assets/css/components/grid.cssdemos/holy-grail.md圣杯布局assets/css/components/holy-grail.cssdemos/media-object.md媒体对象assets/css/components/media.cssdemos/input-add-ons.md输入框附加组件assets/css/components/input-add-on.cssdemos/sticky-footer.md粘性页脚assets/css/components/site.cssdemos/vertical-centering.md垂直居中assets/css/components/aligner.css在继续之前先掌握如何把整个演示站点在本地跑起来——这是阅读下文所有示例、亲手验证每个 Flexbox 效果的前提。本地构建与运行十分钟起一个可热更新的演示站点README.md 提供了完整的本地运行方式前提是本机已安装 Node.js。克隆仓库此处以当前镜像地址为例后依次执行# 克隆仓库并进入目录 git clone https://gitcode.com/gh_mirrors/so/solved-by-flexbox.git cd solved-by-flexbox # 安装依赖 npm install # 构建并在 http://localhost:4000 提供服务 npm start服务启动后浏览器访问http://localhost:4000即可查看站点。需要更换端口时把端口号作为参数传给npm startnpm start -- -p 8080README 特别强调npm start除了构建并本地服务外还会持续监听文件变化并自动重建——修改代码后刷新浏览器即可立即看到效果。这一点在构建脚本中得到了印证查看 gulpfile.js 的serve任务第 160-168 行它会用gulp.watch分别监听assets/css/**/*.css、assets/images/*、assets/main.js、根目录*.html、demos/*与templates/*任一变化都会触发对应子任务增量重建默认端口逻辑为argv.port || argv.p || 4000。如果你只关心「构建」而不启动服务可以运行npm run build对应package.json中的build: gulp。整个构建流程由 gulpfile.js 的default任务并行执行四条子流水线第 158 行css任务以 assets/css/main.css 为入口经postcss-import合并样式、postcss-preset-envstage: 0编译 CSS 变量与自定义媒体查询浏览器目标为 1%, last 2 versions, Safari 5, ie 9, Firefox ESRgulpfile.jsimages任务复制assets/images/**/*到构建目录javascript任务执行rollup -c由 rollup.config.js 以assets/main.js为入口打包为 ESM 模块pages任务用front-matter解析每个demos/*.md的元数据markdown-it渲染正文配highlight.js代码高亮再交给nunjucks套用 templates/ 下的模板最终输出为demos/slug/index.html根目录*.html如 index.html同样参与渲染gulpfile.js。所有产物统一输出到./solved-by-flexbox目录gulpfile.js中的DEST常量页面permalink规则为index页落在baseUrl其余演示页落在demos/slug/gulpfile.js。若需生产环境构建可设置NODE_ENVproduction——此时pages任务会叠加html-minifier压缩css任务叠加cssnano压缩rollup会启用terser压缩gulpfile.js、rollup.config.jsnpm run deploy脚本则要求NODE_ENVproduction否则直接抛错gulpfile.js。六大经典布局难题的 Flexbox 解法下面六个小节是项目的技术主体。每个演示都遵循同一模式先说明传统 CSS 方案的痛点再给出 Flexbox 的极简实现最后补充仓库源码中的完整细节。1. 网格系统告别 float 与 inline-block 的围剿demos/grids.md 指出绝大多数网格系统至今仍依赖float或inline-block两种布局手段而它们本都不是为布局设计的因而问题重重float需要清除浮动清除行为会带来一系列布局问题最典型的是清除元素有时会被强制推到页面某个无关区域的下方此外清除浮动通常需要同时占用::before/::after两个伪元素导致伪元素无法再用于其他用途inline-block必须处理元素之间的空白字符而现有的各种解决方案都相当 hacky。Flexbox 不仅消除了这些问题还打开了全新的可能性。作者在文档中给出了理想网格系统的六条标准而这些特性 Flexbox 几乎白送默认情况下每个单元格与同行其他单元格等宽等高自动均分空间需要精细控制时可给单个单元格添加尺寸类未设尺寸的单元格照常均分剩余空间响应式网格可为单元格添加媒体查询专属类单个单元格可垂直对齐到顶部、底部或中间当整行网格的尺寸、媒体或对齐值一致时只需给容器加一个类避免重复网格可以任意深度嵌套。基础网格的 HTML 极其简洁.Grid容器包住若干.Grid-cell即可div classGrid div classGrid-cell…/div div classGrid-cell…/div div classGrid-cell…/div /div对应的核心 CSS 只有两条规则.Grid { display: flex; } .Grid-cell { flex: 1; }flex: 1让所有单元格自动均分容器宽度align-items的默认值stretch又让它们天然等高。仓库中的完整实现assets/css/components/grid.css在此基础上还包含flex-wrap: wrap支持换行。单个单元格定制尺寸演示 HTML 中可直接给单元格叠加u-1of2、u-1of3、u-1of4等工具类demos/grids.md 的 Individual Sizing 小节未加尺寸类的「auto」单元格则自动吃掉剩余空间。若希望把尺寸规则统一挂在容器上源码也提供了容器级修饰符.Grid--fit .Grid-cell { flex: 1; } .Grid--full .Grid-cell { flex: 0 0 100%; } .Grid--1of2 .Grid-cell { flex: 0 0 50%; } .Grid--1of3 .Grid-cell { flex: 0 0 33.3333%; } .Grid--1of4 .Grid-cell { flex: 0 0 25%; }响应式网格移动优先文档给出的示例是「默认全宽、48em以上自适应」。原理是先用Grid--fullflex: 0 0 100%做基础全宽再用large-Grid--fitflex: 1在media (min-width: 48em)下让单元格按需分栏。源码中的断点并非硬编码而是使用media (--break-sm)、media (--break-md)、media (--break-lg)等自定义媒体查询变量定义在 assets/css/base/custom-media.css由postcss-preset-env在构建期编译成真实断点。嵌套Grid-ception.Grid组件可以在任意层级内无限嵌套演示中甚至出现了三层嵌套组合。对齐能力文档与源码共同展示了两个层级的对齐控制——/* 按行对齐 */ .Grid--top { align-items: flex-start; } .Grid--bottom { align-items: flex-end; } .Grid--center { align-items: center; } /* 按单元格对齐 */ .Grid-cell--top { align-self: flex-start; } .Grid-cell--bottom { align-self: flex-end; } .Grid-cell--center { align-self: center; }容器级类通过align-items统一整行对齐方式单元格级类通过align-self覆盖单个单元格。源码还额外提供Grid--justifyCenterjustify-content: center与Grid-cell--autoSizeflex: none两个实用修饰符以及Grid--guttersmargin: -1em 0 1em -1em 子元素padding: 1em 0 0 1em、Grid--guttersLg1.5em、Grid--guttersXl2em三档间距方案并各自带有small-/med-/large-前缀的响应式版本。2. 圣杯布局三栏等高的终极方案圣杯布局Holy Grail Layout是 Web 设计史上的经典难题demos/holy-grail.md 将其核心目标概括为五条中间栏流体自适应左右侧栏固定宽度中间主内容列在 HTML 源码中必须排在第一位无论哪一列最高三列高度始终一致标记尽量精简内容稀少时页脚「贴」在页面底部。由于这些目标彼此牵制加上旧 CSS 的能力边界历史上没有任何经典方案能同时满足全部五条。Flexbox 让完整解法首次成为可能。HTML 结构注意main位于nav、aside之前body classHolyGrail header…/header div classHolyGrail-body main classHolyGrail-content…/main nav classHolyGrail-nav…/nav aside classHolyGrail-ads…/aside /div footer…/footer /bodyCSS让中间内容行拉伸、让页脚贴底用的正是与 demos/sticky-footer.md粘性页脚演示相同的手法唯一区别是圣杯布局的中间行.HolyGrail-body需要display: flex来排列自己的三个子元素.HolyGrail { display: flex; min-height: 100vh; flex-direction: column; } .HolyGrail-body { display: flex; flex: 1; }三栏等高、中间流体、两侧固定同样只需三组规则.HolyGrail-content { flex: 1; } .HolyGrail-nav, .HolyGrail-ads { /* 12em 是侧栏的宽度 */ flex: 0 0 12em; } .HolyGrail-nav { /* 把导航放到左侧 */ order: -1; }order: -1让 HTML 中排在第二位的导航在视觉上移到最左从而在不改源顺序的前提下满足「主内容优先」的目标flex: 0 0 12em用flex-basis固定侧栏宽度flex-shrink: 0保证它们不会被压缩。响应式改造圣杯布局诞生于桌面浏览器时代如今更需要移动优先版本。文档给出的思路是默认把中间区设为flex-direction: column纵向堆叠较大屏幕再切回row.HolyGrail, .HolyGrail-body { display: flex; flex-direction: column; } .HolyGrail-nav { order: -1; } media (min-width: 768px) { .HolyGrail-body { flex-direction: row; flex: 1; } .HolyGrail-content { flex: 1; } .HolyGrail-nav, .HolyGrail-ads { /* 12em 是侧栏的宽度 */ flex: 0 0 12em; } }仓库中的完整实现 assets/css/components/holy-grail.css 在示例基础上补充了跨浏览器细节见文件头部注释用height: 100%规避 IE 10-11 的min-heightbug并为头部/页脚设置flex: none防止被浏览器压缩到小于内容默认最小尺寸同时把vh换成%以兼容旧版移动 Safari。3. 媒体对象去掉 BFC 与 clearfix 的拐杖媒体对象Media Object是面向对象 CSSOOCSS的招牌模式但demos/media-object.md 指出传统实现必须借助技巧正文要么创建块格式化上下文BFC要么用与图片同宽的外边距/内边距来阻止文字绕排同时还要对正文做 clearfix只能用overflow: hidden或占用伪元素。Flexbox 一举解决全部问题还顺带解锁了两个新能力图片figure可任意垂直对齐不修改源顺序即可把图片放到右侧。基础结构div classMedia img classMedia-figure src alt p classMedia-bodyhellip;/p /div核心 CSS.Media { display: flex; align-items: flex-start; } .Media-figure { margin-right: 1em; } .Media-body { flex: 1; }flex: 1让正文占据剩余宽度文字永远不会绕排到图片下方align-items: flex-start让图片默认顶对齐。完整源码 assets/css/components/media.css 还提供了两个增强修饰符.Media--center { align-items: center; /* 图片垂直居中 */ } .Media--reverse .Media-figure { order: 1; /* 图片移到右侧 */ margin: 0 0 0 1em; }Media--reverse仅靠order: 1就完成了图文左右互换完全不用调整 DOM 顺序。文档中的演示还覆盖了「非图片 figure」如图标、以及多层嵌套媒体对象评论回复等典型场景这些都直接复用同一套.Media结构。4. 输入附加组件流体 input 与按钮/标签的无缝拼接demos/input-add-ons.md 描述了一个长期无解的痛点受 CSS 输入框尺寸行为限制几乎不可能在 input 前后追加元素并让输入框流体占满剩余宽度。旧方案要么必须预先知道 input 的精确宽度要么使用display: table-cell——后者在部分浏览器中很难对附加元素内部做绝对定位。Flexbox 让这些问题全部消失代码极其简单并且免费获得「输入框与附加元素等高」的效果。支持前附加、后附加、两侧同时附加三种形态!-- 后附加appending -- div classInputAddOn input classInputAddOn-field button classInputAddOn-item…/button /div !-- 前附加prepending -- div classInputAddOn span classInputAddOn-item…/span input classInputAddOn-field /div !-- 两侧都附加 -- div classInputAddOn span classInputAddOn-item…/span input classInputAddOn-field button classInputAddOn-item…/button /div核心 CSS.InputAddOn { display: flex; } .InputAddOn-field { flex: 1; /* 输入框样式 */ } .InputAddOn-item { /* 附加元素样式 */ }完整的 assets/css/components/input-add-on.css 还处理了视觉衔接细节利用:not(:first-child)/:not(:last-child)合并相邻元素的边框border-left: 0/border-right: 0并为首尾元素分别设置border-radius: 2px 0 0 2px与0 2px 2px 0附加元素使用半透明背景rgba(147, 128, 108, 0.1)与主输入框区分。5. 粘性页脚页脚高度未知也不怕让页脚在内容稀少的页面上「贴」在窗口底部几乎是每个 Web 开发者都尝试过的问题且已有不少成熟方案。但demos/sticky-footer.md 点出了它们共同的致命短板页脚高度未知时全部失效。Flexbox 恰好是这类问题的完美匹配——它不只为水平方向设计垂直布局同样擅长只要把纵向区块包进一个 flex 容器再指定哪个区块需要扩展它就会自动占据容器内的全部剩余空间。一个关键差异是垂直方向需要为容器显式指定高度水平方向会自动扩展撑满。示例结构body classSite header…/header main classSite-content…/main footer…/footer /bodyCSS.Site { display: flex; min-height: 100vh; flex-direction: column; } .Site-content { flex: 1; }min-height: 100vh保证页面至少与视口等高flex: 1让主内容区吃掉所有剩余高度页脚自然被推到最底部。仓库源码 assets/css/components/site.css 中的跨浏览器版本做了三处加固用height: 100%替代min-height: 100vh规避 IE 10-11 的 min-height bug 与旧版移动 Safari 的 vh 问题Site-header/Site-footer设flex: none防止被压缩Site-content使用flex: 1 0 autoflex-shrink: 0并用::after插入一个nbsp;空字符占位块来保证内容区底部留白。文档中的演示还附带了一个「Toggle Contents」按钮的交互脚本demos/sticky-footer.md用来直观验证内容隐藏后页脚依然贴底。6. 垂直居中内容尺寸未知、有兄弟元素也能居中demos/vertical-centering.md 开篇就指出CSS 缺乏优雅的垂直居中手段是其历史上的一大污点。更糟的是那些真正能用的技术负外边距、display: table-cell、全高伪元素 hack既晦涩又不直观而最直观的vertical-align: middle在需要时几乎从不生效并且这些老办法都有限制——目标元素尺寸未知怎么办它不是父元素唯一子元素怎么办伪元素被占用怎么办Flexbox 用align-items、align-self、justify-content三个属性让这一切变得毫无压力——任意元素、任意尺寸、任意兄弟关系都能轻松实现垂直和/或水平居中。HTMLdiv classAligner div classAligner-item Aligner-item--top…/div div classAligner-item…/div div classAligner-item Aligner-item--bottom…/div /divCSS.Aligner { display: flex; align-items: center; justify-content: center; } .Aligner-item { max-width: 50%; } .Aligner-item--top { align-self: flex-start; } .Aligner-item--bottom { align-self: flex-end; }容器用align-items: centerjustify-content: center实现双轴居中单个元素可用align-self覆盖为自己的对齐方式从而在同一个容器内混排「顶对齐 / 居中 / 底对齐」。这与传统方案形成鲜明对比兄弟元素的存在完全不影响彼此的垂直对齐能力。演示中还提供了可contenteditable的示例框编辑文字使其变宽变高盒子依然保持居中。完整实现见 assets/css/components/aligner.css其中.Aligner-item为flex: 1另有.Aligner-item--fixedflex: none; max-width: 50%用于固定尺寸项容器设置了min-height: 24em以确保演示区域有足够的对齐空间。跨浏览器兼容与工具链demo 之外的真实代码需要特别留意的是文档中的示例代码假设浏览器完全符合规范而仓库源码为了兼容真实浏览器做了额外处理——每个演示文档都在显眼位置以 Note 形式提示了这一点并指向源码注释圣杯布局与粘性页脚的兼容细节见 assets/css/components/holy-grail.css 与 assets/css/components/site.css 文件头部的注释IE 10-11min-heightbug、flex-shrink置 0、vh→%垂直居中的兼容标记与处理见 assets/css/utils/compat.css。构建工具链为这套「规范示例 兼容源码」的双轨策略提供了支撑样式统一以 assets/css/main.css 为入口由 gulpfile.js 的 css 任务交给postcss-preset-envstage: 0处理 CSS 变量与自定义媒体查询生产环境再用cssnano压缩依赖清单中的normalize.css提供基础样式重置highlight.js负责代码块高亮markdown-it渲染演示正文nunjucks套用 templates/ 下的页面模板如 templates/default.html、templates/holy-grail.html站点级数据则来自 config.json。社区翻译与继续深入README 还记录了一个社区贡献事实该项目已有中文、日文、韩文等社区翻译版本同时明确提示这些非官方翻译可能不够准确或已过时若想提交自己的翻译可向项目提交 pull request 或打开 issue 并附上译文链接。进一步学习时建议按「文档 → 源码 → 构建配置」三层递进阅读逐个精读 demos/ 下的六个 Markdown 文档先理解每个问题的历史痛点对照 assets/css/components/ 下的组件样式观察示例与生产级代码的差异尤其是兼容性注释通读 gulpfile.js、package.json、rollup.config.js理解文档是如何被渲染、压缩并发布成静态站点的。把六个演示中的.Grid、.HolyGrail、.Media、.InputAddOn、.Site、.Aligner组件抽出来稍作变量化调整即可直接嵌入你自己的项目——这正是本项目「solved by flexbox」最大的实用价值所在。赞分享示例工程【免费下载链接】solved-by-flexboxA showcase of problems once hard or impossible to solve with CSS alone, now made trivially easy with Flexbox.项目地址https://gitcode.com/gh_mirrors/so/solved-by-flexbox点击查看免费下载相关推荐Flexbox实战指南solved-by-flexbox项目教你攻克10大CSS布局难题Flexbox实战指南solved by flexbox项目教你攻克10大CSS布局难题 在CSS布局领域Flexbox弹性盒模型的出现彻底改变了前端开示例工程如何配置Lucky反向代理一个监听端口带起多台服务如何配置Lucky反向代理一个监听端口带起多台服务 家里几台机器各跑着一个 Web 服务要记的却是一串 192.168.31.80:28888 这样的地址加后端网络通信Flexbox布局与CSS变量结合solved-by-flexbox的主题切换实现Flexbox布局与CSS变量结合solved by flexbox的主题切换实现 在前端开发中布局与样式的动态调整一直是提升用户体验的关键。solved示例工程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。