CSS 布局案例:不会还有人不会布局吧
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,注明主题:创作合作或招聘前端工程师。
MDN. position. ↩︎
古兰精. 浅析瀑布流布局原理及实现方式. 博客园. ↩︎
高级前端小白. 干货!纯js封装瀑布流布局插件. 稀土掘金. ↩︎
MDN. Masonry layout. ↩︎
CSS 布局案例:不会还有人不会布局吧相关推荐
- CSS中浮动布局float(小米布局案例、导航栏案例、overflow)
1. CSS 布局的三种机制 网页布局的核心--就是用 CSS 来摆放盒子. CSS 提供了 3 种机制来设置盒子的摆放位置,分别是普通流(标准流).浮动和定位, 其中: 普通流(标准流) 块级元素会 ...
- 《Div+CSS 3.0网页布局案例精粹》扫描版[PDF]
电驴资源 下面是用户共享的文件列表,安装电驴后,您可以点击这些文件名进行下载 [Div.CSS.3.0网页布局案例精粹].王大远.扫描版.rar详情 53.7MB 全选 53.7MB 下载地址(拷贝到 ...
- html5图片列表纵向,div css图片列表实例布局案例ul li布局
DIV CSS布局图文列表布局案例 ul li图文列表 使用div css ul li布局图文列表小局部案例,学习图文列表布局实际案例. div+css图文布局案例图 本案例在DIVCSS5模板基础上 ...
- html中如何写div中div的位置,DIV CSS绝对定位布局案例 position布局实例
DIVCSS5为大家实例讲解绝对定位布局.绝对定位我们要用到样式position:absolute和position:relative,同时需要top.bottom.left.right配合布局实现D ...
- html,css响应式布局案例练习--星巴克官网demo
前言 继续练习响应式布局,我这次选的是星巴克的官网,进行一个页面的还原,还原程度达不到100%,不过也是可以进行一个学习过程的一个练习,细节很多,本人由于初学阶段,用了一天的时间就写了一个官网首页,兼 ...
- CSS课堂案例8-小米布局
浮动布局练习 利用浮动初步实现页面布局的效果 如图所示,可知可将改布局分成三部分,外面的大盒子作为标准流父级,约束浮动元素,内部分成左右两个浮动标签,中间无空隙 <!DOCTYPE html&g ...
- 17综合案例之淘宝轮播图布局
1.整体效果 2.案例分析 3.具体实现 大盒子类的命名tb-promo,淘宝广告: 里面放一张图片: 左右两个按钮用链接就可以,左箭头prev,右箭头next: 底侧小圆点用ul来实现,命名为pro ...
- Css Secret 案例Demo全套
Css Secret 案例全套 github地址 案例地址 去年买了一本CSS揭秘的css专题书,该书揭示了 47 个鲜为人知的 CSS 技巧,主要内容包括背景与边框.形状. 视觉效果.字体排印.用户 ...
- MUI框架:移动端底部固定mui-bar-tab布局 - 案例篇
移动端布局:自定义MUI底部tabs选项卡(nav组件 · 底部固定mui-bar-tab) · 案例演示 效果图 html代码实例 · 如下: <!doctype html> <h ...
- MUI框架:栅格系统 + grid宫格布局 - 案例篇
MUI框架 · 自定义宫格布局 · 应用案例: 通过使用MUI框架的 栅格系统 + grid宫格布局 ,覆盖源码样式,以达到完美的页面效果. 效果图: 点击动画效果不再演示,具体效果参考源码效果! 全 ...
最新文章
- css样式IE8强制兼容IE7
- python cvxpy包安装教程
- 简明python教程电子版-简明Python教程PDF电子书免费下载
- 用.NET SqlBulkCopy类执行批量复制
- 开发过程中的常见问题
- oracle允许空行,oracle用户权限的一些基本操作
- IBASE object component的where use list
- P4716-[模板]最小树形图
- 平面图转对偶图19_03_21校内训练 [Everfeel]
- c语言一级考试题目第四季度,模拟试题8套
- 二维数组作数据源填充到repeater
- 吃了核辐射食物怎么办_我们经常吃的猪肉,相当一部分是核辐射照过的,会对身体有害吗...
- aix 文件升级-替换
- zb如何导出自己画的_如何用Rhino做出融球效果?
- android 十六进制string转int,16进制string转成int
- 损失函数的意义和作用_BN究竟起了什么作用?一个闭门造车的分析
- C#俄罗斯方块代码完整版带部分注释
- 将.ncm文件转换为.mp3文件
- 安卓app逆向破解脱壳教程
- 普通有刷直流电机 H桥驱动
热门文章
- Quartus II中关于IP核的破解
- HttpHeaders()无法调用
- 百度地图 3.0 WEB离线开发
- [CF296D] Greg and Graph [floyd]
- java base64转图片打不开_解决通过 Base64 解码得到的图片无法打开查看的问题
- ZCMU-1345: 国际象棋
- Win7添加打印机local port端口拒绝访问的解决方法
- HTML:设置背景颜色和图片
- 数据增强:图片加雾效果实现Python
- 决策树模型回归可视化分析_基于Blank Friday商店销售数据分析构建回归模型