CSS 布局是前端最重要的一课,学会了 CSS 布局前端就算入门了。本文总结了常见的布局案例,可以作为 CSS 布局的学习资料,也可以作为开发的参考资料,建议大家先收藏,如果对你有帮助可以考虑点个小小的赞。

水平居中

水平居中布局要求:假设容器的宽度为 xxx,中间内容的宽度为 yyy,则左边空余宽度=右边空余宽度=(x−y)/2(x-y)/2(x−y)/2,如下图所示:

方法一、margin: auto;

    <style>.box {height: 50vh;background-color: #fdeff2;}.content {width: 150px;height: 100px;background-color: #f6bfbc;margin: 0 auto; /*居中*/}</style><div class="box"><div class="content"></div></div>

【要点解读】水平居中的含义:当容器宽度比内容大的时候,“居中”才有意义,因此使用此方法的前提是内容的宽度比容器的宽度小。

【易错点】对和容器宽度相等的内容使用 margin:auto;,例如容器是浮动盒子时,脱流的定位容器。

【原理】margin 的 auto 值等于剩余空间的宽度,写 margin-left: auto;内容会被顶到右边,如果同时设置左右 margin: 0 auto; 则左右平分剩余空间。

【技巧】margin: 0 auto; 可以简写成:margin: auto; 因为当 margin-top 或 margin-bottom 为 auto 时值为 0 ,除非脱离文档流。

方法二、弹性盒子

    <style>.box {height: 150px;background-color: #fdeff2;display: flex;justify-content: center; /*居中*/}.content {width: 150px;height: 100px;background-color: #f6bfbc;}</style><div class="box"><div class="content"></div></div>

【解读】弹性盒子有专门的居中方案:即在主轴与交叉轴方向设置 center。

方法三、text-align: center

当内容是非块级元素时,使用 text-align:center; 可以实现居中效果:

    <style>ul {text-align: center;/* 其他样式 */line-height: 40px;list-style: none;margin: 0;padding: 0;background-color: #fdeff2;}ul li {display: inline-block;/* 其他样式 */background-color: #f6bfbc;padding: 8px 16px;}</style><ul><li>首页</li><li>关于</li><li>产品</li></ul>

【要点解读】text-align 的方法经常在文本居中时使用,并且该属性具有继承性,使用起来非常方便。用于布局时,常用语导航条内的链接居中,把 li 设置成 inline-block 然后居中即可。

【易错点】没有分清容器与内容,把 inline-block 设置到容器元素上了。

【易错点】对宽度与内容相等的容器使用,例如浮动的容器。

方法四、定位实现

    <style>.box {height: 200px;background-color: #fdeff2;position: relative;}.content {width: 150px;height: 100px;background-color: #f6bfbc;/* 定位实现水平居中1. left=right2. 剩余空间的宽度大于零3. 内容宽度已知*/position: absolute;left: 0;right: 0;margin: auto;}</style><div class="box"><div class="content"></div></div>

【要点解读】设置左右距离相等,然后设置 margin: auto;

【易错点】需要知道内容的宽度,如果不设置内容的宽度,则铺满容器。

小结

这么多水平居中的方法,你学会了了吗?

【练习】请说出几种水平居中的方法,各有何优缺点?

垂直居中

方法一、line-height 实现文字垂直居中

思路:把 line-height 设置成容器的高度,即可实现文字居中。

<style>.box {height: 50px;background-color: #fdeff2;}.content {line-height: 50px;background-color: #f6bfbc;color: #b94047;}
</style><div class="box"><div class="content">你猜我居中了没</div>
</div>

方法二、vertical-align 实现图片文字居中

    <style>.box {line-height: 50px;background-color: #fdeff2;color: #b94047;}.box img {height: 30px;vertical-align: middle;}.box span {vertical-align: middle;}</style><div class="box"><img src="https://s1.52poke.wiki/wiki/thumb/5/53/054Psyduck.png/300px-054Psyduck.png" alt="图不见了" /><span>这可怎么居中呀</span></div>

【要点】该方法只能用于具有行内性质的元素,并且内容的高度小于 line-height 的时候有效。

方法三、弹性盒子

弹性盒子轻轻松松就能实现垂直居中:

    <style>.box {height: 50px;display: flex;align-items: center;background-color: #fdeff2;color: #b94047;}.box img {height: 30px;}</style><div class="box"><img src="https://s1.52poke.wiki/wiki/thumb/5/53/054Psyduck.png/300px-054Psyduck.png" alt="图不见了" /><span>这可怎么居中鸭</span></div>

【要点解读】使用 align-items:center; 可实现垂直居中,使用 justify-content:center; 可以实现水平居中。更为准确的说法是:align-items:center; 实现交叉轴方向的居中,justify-content:center; 实现主轴方向的居中,主轴方向由 flex-direction声明,默认为从左到右。

【易错点】只有容器的高度比内容大时,才能实现垂直居中。

方法四、定位实现垂直居中

    <style>.box {height: 100px;background-color: #fdeff2;position: relative;}.content {width: 20px;height: 50px;background-color: #f6bfbc;/* 定位实现垂直居中1. top=bottom, 设置 margin: auto;2. 剩余空间的高度大于零3. 内容高度已知*/position: absolute;right: 20px;top: 0;bottom: 0;margin: auto;}</style><div class="box"><div class="content"></div></div>

【要点解读】设置上下距离相等,然后设置 margin: auto; 即可实现,这种方法多用于右侧工具栏布局。

定位还有另外一种方法,平移法:

    <style>.box {height: 100px;background-color: #fdeff2;position: relative;}.content {width: 20px;height: 50px;background-color: #f6bfbc;/* 定位实现垂直居中1. 先让上边界居中,然后用平移调整2. 剩余空间的高度大于零3. 内容高度已知*/position: absolute;right: 20px;top: 50%;transform: translateY(-50%);}</style><div class="box"><div class="content"></div></div>

小结

垂直居中是网页布局常用的方法,垂直居中比水平居中会麻烦一点点。不过有了弹性盒子之后,一切都变得简单了,毕竟弹性盒子专门为布局而生。

【练习】请说出几种垂直居中的方法,并说说各有何优缺点?

两栏布局

如下图所示,两栏布局要求:

1)左侧宽度固定

2)右侧占据剩余宽度

3)左侧不随着右侧内容滚动

两栏布局常用于后台管理系统,左侧是多级导航菜单,右侧是系统详情。也常用于文档系统,左侧是多级目录,右侧是文档内容。

方法一、使用定位实现两栏布局

    <style>body {margin: 0;}.home-side {/* 实现固定侧边栏 * 必须同时设置 top 和 bottom*/position: fixed;top: 0;bottom: 0;/* 设置侧边栏宽度 */width: 200px;/* 设置内容溢出滚动效果 */overflow-y: auto;}.side-content {width: 100%;height: 120vh;background-color: #e9dfe5;}.home-main {/* 使用左外边距留出侧边栏宽度 */margin-left: 200px;background-color: #f5b1aa;height: 200vh;}</style><div class="home"><aside class="home-side"><div class="side-content"></div></aside><main class="home-main"></main></div>

【要点】

1)使用固定定位使得侧边栏固定在左侧,要让侧边栏可以滚动,还必须同时设置 top 与 bottom 与 overflow 属性。

2)使用 margin 或 paddding 为内容留出侧边栏的内容。

实现效果:

如果放弃第三个条件:即侧边栏可以随着内容滚动,那么布局的方法就会很多:

方法二、弹性布局

    <style>body {margin: 0;}.home {display: flex;}.home-side {width: 200px;flex-shrink: 0; /*不允许收缩*/}.home-main {flex-grow: 1; /*占据剩余空间*/background-color: #f5b1aa;height: 200vh;}.side-content {width: 100%;height: 120vh;background-color: #e9dfe5;}</style><div class="home"><aside class="home-side"><div class="side-content"></div></aside><main class="home-main"></main></div>

【要点解读】关键代码就四行:

      .home {display: flex;}.home-side {width: 200px;flex-shrink: 0; /*不允许收缩*/}.home-main {flex-grow: 1; /*占据剩余空间*/}

【优点】简单易懂。

【缺点】不能实现侧边栏固定。

【技巧】flex:1; 等价于 flex-grow:1;

可改变宽度的侧边栏布局

不用 JavaScript 无法实现可改变宽度的固定侧边栏,这里贴一个案例仅供参考:

    <style>body {margin: 0;}:root {--sidebar-width: 200px;}.home-side {/* 实现固定侧边栏 * 必须同时设置 top 和 bottom*/position: fixed;top: 0;bottom: 0;box-sizing: border-box;/* 设置侧边栏宽度 */width: var(--sidebar-width);}.side-resizer {position: absolute;right: 0;top: 0;bottom: 0;cursor: ew-resize;background-color: transparent;width: 5px;}.side-resizer:hover,.side-resizer:active {border-right: 1px dashed #43676b;}.side-scroll-box {position: absolute;top: 0;bottom: 0;left: 0;right: 0;overflow-y: auto;/* 火狐浏览器滚动条样式 */scrollbar-color: #bfbfbf rgb(239, 239, 239);scrollbar-width: thin;}/*滚动条样式*/.side-scroll-box::-webkit-scrollbar {width: 5px;}.side-scroll-box::-webkit-scrollbar-track {background: rgb(239, 239, 239);border-radius: 2px;}.side-scroll-box::-webkit-scrollbar-thumb {background: #bfbfbf;border-radius: 10px;}/* 拖动的时候禁用选择 */.sidebar-resizing {-moz-user-select: none;-webkit-user-select: none;-ms-user-select: none;user-select: none;}.side-content {height: 120vh;background-color: #e9dfe5;}.home-main {/* 使用左外边距留出侧边栏宽度 */margin-left: var(--sidebar-width);background-color: #f5b1aa;height: 200vh;}</style><div class="home"><aside class="home-side" id="sidebar"><div class="side-scroll-box"><div class="side-content"></div></div><div class="side-resizer" id="sidebar-resizer"></div></aside><main class="home-main"></main></div><script>const html = document.querySelector("html");const sidebarResizer = document.getElementById("sidebar-resizer");const sidebar = document.getElementById("sidebar");sidebarResizer.addEventListener("mousedown", initResize, false);function initResize(e) {window.addEventListener("mousemove", resize, false);window.addEventListener("mouseup", stopResize, false);html.classList.add("sidebar-resizing");}function resize(e) {var pos = e.clientX - sidebar.offsetLeft;pos = Math.min(pos, window.innerWidth - 100);document.documentElement.style.setProperty("--sidebar-width", pos + "px");}//on mouseup remove windows functions mousemove & mouseupfunction stopResize(e) {html.classList.remove("sidebar-resizing");window.removeEventListener("mousemove", resize, false);window.removeEventListener("mouseup", stopResize, false);}</script>

【要点解读】可调节宽度的侧边栏表面上看起来挺难的,但涉及到的技术细节还是挺多的:

  • 固定双栏布局

  • CSS 变量:--sidebar-width

  • 滚动条样式调整

  • 调整宽度的相关事件。

三栏布局与粘性定位

三栏布局的使用场景一般是文章详情,一边是分享、点赞等操作,另一边是推荐,目录,广告等内容。其实三栏布局也不难:可以先实现两栏布局,然后再实现三栏布局。本案例除了给大家展示三栏布局效果,还给大家展示粘性布局的效果,这个功能你用上了根本就停不下来:

    <style>.home {display: flex;align-items: flex-start;}.left {width: 200px;flex-shrink: 0;background-color: #b98c46;height: 80vh;margin-right: 20px;}.right {width: 200px;flex-shrink: 0;}.main {flex: 1;display: flex;}.content {flex: 1;background-color: #8b968d;height: 300vh;}.box1 {width: 200px;flex-shrink: 0;height: 50vh;background-color: #aa4c8f;margin: 20px 20px;}.box2 {width: 200px;flex-shrink: 0;height: 30vh;background-color: #7a4171;margin: 20px 20px;position: sticky;top: 20px;}</style><div class="home"><div class="left"></div><div class="main"><div class="content"></div><div class="right"><div class="box1"></div><div class="box2"></div></div></div></div>

效果:

【要点解读】

  • 结构:中间是很长的内容,右边是广告(淡紫色)和目录(深紫色)
  • 滚动条向下滑动的时候目录区域会吸附在顶部。吸附效果使用 position: sticky; 实现,目前主流的浏览器支持良好1

瀑布流布局

瀑布流布局常用于图片类型的网站,例如:堆糖网。瀑布流布局有一个专业的英文名称 Masonry Layouts。瀑布流又称瀑布流式布局,是比较流行的一种网站页面布局方式。2

瀑布流布局特点:

1、因为瀑布流有吸引力,瀑布流会在它的页面底部给你不断地加载新的信息,,通过给出不完整的视觉图片去吸引你的好奇心,让你停不下来想要不断的向下探索。采用这种方案的产品,往往可以通过瀑布流加强用户的停留时间,提高用户的使用粘度。

2、用户一扫而过的快速阅读模式,短时间内可以看到大量的信息,瀑布流的懒加载模式,又避免点击的的翻页操作,在最小的操作成本下能够获得最多的内容体验,瀑布流的视觉方式,让人容易沉浸其中,不容易被打断。

3、另外瀑布流的主要特质就是:定宽而不定高,这样的页面设计区别于传统的矩阵式图片布局模式,巧妙的利用视觉层级,视线的任意流动来缓解视觉的疲劳。

瀑布流更适合那些随意浏览,不带目的性的使用场景,就像是在逛街一样,边走边看,同时被街边琳琅满目的商品吸引着,所以比较适合的图片、小说、资讯类的场景,以现有的成功案例来说,以 UGC 为主的相关网站很多在使用瀑布流进行承载。

方法一、JavaScript 实现

目前还没有完美的纯CSS实现方法,成熟的解决方案需要 JavaScript 参与实现3

<style>.waterfall {position: relative;}.waterfall-item {position: absolute;width: 23%;height: 100px;background: rgb(236, 146, 10);margin-bottom: 10px;display: flex;justify-content: center;align-items: center;transition: all 0.1s;}.num {font-size: 18px;color: #fff;border-radius: 100%;width: 25px;height: 25px;line-height: 25px;text-align: center;border: 1px solid #fff;}.btn {text-align: center;font-size: 15px;color: #400eff;cursor: pointer;position: absolute;bottom: 10px;left: 50%;}</style><div id="waterfall" class="waterfall"></div><script>class WaterFall {constructor(container, options) {this.gap = options.gap || 0;this.container = container;this.items = container.children || [];this.heightArr = [];this.renderIndex = 0;window.addEventListener("resize", () => {this.renderIndex = 0;this.heightArr = [];this.layout();});this.container.addEventListener("DOMSubtreeModified", () => {this.layout();});}layout() {if (this.items.length === 0) return;const gap = this.gap;const pageWidth = this.container.offsetWidth;const itemWidth = this.items[0].offsetWidth;const columns = Math.floor(pageWidth / (itemWidth + gap)); // 总共有多少列while (this.renderIndex < this.items.length) {let top, left;if (this.renderIndex < columns) {// 第一行top = 0;left = (itemWidth + gap) * this.renderIndex;this.heightArr.push(this.items[this.renderIndex].offsetHeight);} else {const minIndex = this.getMinIndex(this.heightArr);top = this.heightArr[minIndex] + gap;left = this.items[minIndex].offsetLeft;this.heightArr[minIndex] += this.items[this.renderIndex].offsetHeight + gap;}this.container.style.height = this.getMaxHeight(this.heightArr) + "px";this.items[this.renderIndex].style.top = top + "px";this.items[this.renderIndex].style.left = left + "px";this.renderIndex++;}}getMinIndex(heightArr) {let minIndex = 0;let min = heightArr[minIndex];for (let i = 1; i < heightArr.length; i++) {if (heightArr[i] < min) {min = heightArr[i];minIndex = i;}}return minIndex;}getMaxHeight(heightArr) {let maxHeight = heightArr[0];for (let i = 1; i < heightArr.length; i++) {if (heightArr[i] > maxHeight) {maxHeight = heightArr[i];}}return maxHeight;}}window.onload = function () {const waterfall = document.getElementById("waterfall");const water = new WaterFall(waterfall, { gap: 10 });water.layout();};</script><script>var index = 0;const waterfall = document.getElementById("waterfall");function getData(num = 5) {return new Promise((resolve, reject) => {setTimeout(() => {const fragment = document.createDocumentFragment();for (let i = 0; i < num; i++) {const div = document.createElement("div");const numDiv = document.createElement("div");div.className = "waterfall-item";numDiv.className = "num";numDiv.textContent = index + 1;index++;div.appendChild(numDiv);div.style.height = getRandomHeight(4, 1) + "px";fragment.appendChild(div);}waterfall.appendChild(fragment);resolve();}, 1000);});}getData(20);var loading = false;window.onscroll = async function () {const scrollTop = document.documentElement.scrollTop; // 滚动条位置const clientHeight = document.documentElement.clientHeight;const scrollHeight = document.body.scrollHeight; // 完整高度if (scrollTop + clientHeight >= scrollHeight && !loading) {loading = true;await getData();loading = false;}};function getRandomHeight(max = 5, min = 1) {return (Math.floor(Math.random() * (max - min + 1)) + min) * 100;}</script>

方法二、未来的方法4

.container {display: grid;grid-template-columns: repeat(4, 1fr);grid-template-rows: masonry;
}

参考文章

♥ 我是前端工程师:你的甜心森。非常感谢大家的点赞与关注,欢迎大家参与讨论或协作,QQ交流群:233589794。

★ 本文开源,采用 CC BY-SA 4.0 协议,转载请注明出处:前端工程师的自我修养. GitHub.com@xiayulu.

★ 创作合作或招聘信息请发私信或邮件:zuiaiqiansen@163.com,注明主题:创作合作或招聘前端工程师


  1. MDN. position. ↩︎

  2. 古兰精. 浅析瀑布流布局原理及实现方式. 博客园. ↩︎

  3. 高级前端小白. 干货!纯js封装瀑布流布局插件. 稀土掘金. ↩︎

  4. MDN. Masonry layout. ↩︎

CSS 布局案例:不会还有人不会布局吧相关推荐

  1. CSS中浮动布局float(小米布局案例、导航栏案例、overflow)

    1. CSS 布局的三种机制 网页布局的核心--就是用 CSS 来摆放盒子. CSS 提供了 3 种机制来设置盒子的摆放位置,分别是普通流(标准流).浮动和定位, 其中: 普通流(标准流) 块级元素会 ...

  2. 《Div+CSS 3.0网页布局案例精粹》扫描版[PDF]

    电驴资源 下面是用户共享的文件列表,安装电驴后,您可以点击这些文件名进行下载 [Div.CSS.3.0网页布局案例精粹].王大远.扫描版.rar详情 53.7MB 全选 53.7MB 下载地址(拷贝到 ...

  3. html5图片列表纵向,div css图片列表实例布局案例ul li布局

    DIV CSS布局图文列表布局案例 ul li图文列表 使用div css ul li布局图文列表小局部案例,学习图文列表布局实际案例. div+css图文布局案例图 本案例在DIVCSS5模板基础上 ...

  4. html中如何写div中div的位置,DIV CSS绝对定位布局案例 position布局实例

    DIVCSS5为大家实例讲解绝对定位布局.绝对定位我们要用到样式position:absolute和position:relative,同时需要top.bottom.left.right配合布局实现D ...

  5. html,css响应式布局案例练习--星巴克官网demo

    前言 继续练习响应式布局,我这次选的是星巴克的官网,进行一个页面的还原,还原程度达不到100%,不过也是可以进行一个学习过程的一个练习,细节很多,本人由于初学阶段,用了一天的时间就写了一个官网首页,兼 ...

  6. CSS课堂案例8-小米布局

    浮动布局练习 利用浮动初步实现页面布局的效果 如图所示,可知可将改布局分成三部分,外面的大盒子作为标准流父级,约束浮动元素,内部分成左右两个浮动标签,中间无空隙 <!DOCTYPE html&g ...

  7. 17综合案例之淘宝轮播图布局

    1.整体效果 2.案例分析 3.具体实现 大盒子类的命名tb-promo,淘宝广告: 里面放一张图片: 左右两个按钮用链接就可以,左箭头prev,右箭头next: 底侧小圆点用ul来实现,命名为pro ...

  8. Css Secret 案例Demo全套

    Css Secret 案例全套 github地址 案例地址 去年买了一本CSS揭秘的css专题书,该书揭示了 47 个鲜为人知的 CSS 技巧,主要内容包括背景与边框.形状. 视觉效果.字体排印.用户 ...

  9. MUI框架:移动端底部固定mui-bar-tab布局 - 案例篇

    移动端布局:自定义MUI底部tabs选项卡(nav组件 · 底部固定mui-bar-tab) · 案例演示 效果图 html代码实例 · 如下: <!doctype html> <h ...

  10. MUI框架:栅格系统 + grid宫格布局 - 案例篇

    MUI框架 · 自定义宫格布局 · 应用案例: 通过使用MUI框架的 栅格系统 + grid宫格布局 ,覆盖源码样式,以达到完美的页面效果. 效果图: 点击动画效果不再演示,具体效果参考源码效果! 全 ...

最新文章

  1. css样式IE8强制兼容IE7
  2. python cvxpy包安装教程
  3. 简明python教程电子版-简明Python教程PDF电子书免费下载
  4. 用.NET SqlBulkCopy类执行批量复制
  5. 开发过程中的常见问题
  6. oracle允许空行,oracle用户权限的一些基本操作
  7. IBASE object component的where use list
  8. P4716-[模板]最小树形图
  9. 平面图转对偶图19_03_21校内训练 [Everfeel]
  10. c语言一级考试题目第四季度,模拟试题8套
  11. 二维数组作数据源填充到repeater
  12. 吃了核辐射食物怎么办_我们经常吃的猪肉,相当一部分是核辐射照过的,会对身体有害吗...
  13. aix 文件升级-替换
  14. zb如何导出自己画的_如何用Rhino做出融球效果?
  15. android 十六进制string转int,16进制string转成int
  16. 损失函数的意义和作用_BN究竟起了什么作用?一个闭门造车的分析
  17. C#俄罗斯方块代码完整版带部分注释
  18. 将.ncm文件转换为.mp3文件
  19. 安卓app逆向破解脱壳教程
  20. 普通有刷直流电机 H桥驱动

热门文章

  1. Quartus II中关于IP核的破解
  2. HttpHeaders()无法调用
  3. 百度地图 3.0 WEB离线开发
  4. [CF296D] Greg and Graph [floyd]
  5. java base64转图片打不开_解决通过 Base64 解码得到的图片无法打开查看的问题
  6. ZCMU-1345: 国际象棋
  7. Win7添加打印机local port端口拒绝访问的解决方法
  8. HTML:设置背景颜色和图片
  9. 数据增强:图片加雾效果实现Python
  10. 决策树模型回归可视化分析_基于Blank Friday商店销售数据分析构建回归模型