CSS传统布局方法(补充)——WEB开发系列37
开发技术不断演进,布局方式也经历了多个阶段的变革。从最初的基于表格布局到 CSS 的浮动布局,再到今天的弹性盒(Flexbox)与 CSS Grid 网格布局,每一种布局方式都有其独特的背景和解决特定问题的优势。
一、CSS Grid 出现之前的布局与网格系统
在 CSS Grid 诞生之前,前端开发者通常使用 float
、inline-block
、positioning
、table
等方法来创建复杂的布局。这些方法可以说是 CSS 布局发展的基础,虽然它们存在许多局限性,但在现代布局体系尚未完善之前,它们依旧是最常用的手段。
1.1 浮动布局(Float)
浮动布局 是最早用于网页布局的 CSS 技术之一,最初是为了让文字环绕图片而设计的。开发者发现,可以利用 float
属性来构建多列布局。
示例:
<div class="container"><div class="column-left">左侧列</div><div class="column-right">右侧列</div>
</div><style>
.container {width: 100%;
}.column-left {float: left;width: 50%;background-color: #eaeaea;
}.column-right {float: right;width: 50%;background-color: #cfcfcf;
}
</style>
上例子中,column-left
使用 float: left
,column-right
使用 float: right
来创建左右两列的布局。然而,浮动布局存在一些显著的缺陷,比如清除浮动(clearfix)问题,需要额外的技巧来防止父元素的高度坍塌。
1.2 inline-block 布局
为了避免浮动布局带来的清除问题,一些开发者开始使用 inline-block
来构建多列布局。inline-block
的特点是元素依然具有块级元素的宽高,但可以在一行内并排显示。
示例:
<div class="container"><div class="column">第一列</div><div class="column">第二列</div>
</div><style>
.container {font-size: 0; /* 避免 inline-block 之间的空白间隙 */
}.column {display: inline-block;width: 50%;background-color: #ddd;font-size: 16px; /* 恢复子元素的字体大小 */
}
</style>
尽管 inline-block
可以解决浮动布局的一些问题,但它仍然有一些不便之处,比如需要清除行内元素之间的空白间隙(通过设置 font-size: 0
)。
1.3 绝对定位布局
绝对定位(Positioning) 也是一种传统的布局方式。通过 position: absolute
可以将元素从文档流中移除,并相对于最近的定位祖先元素进行布局。
示例:
<div class="container"><div class="column-left">左侧列</div><div class="column-right">右侧列</div>
</div><style>
.container {position: relative;
}.column-left {position: absolute;left: 0;width: 50%;background-color: #eaeaea;
}.column-right {position: absolute;right: 0;width: 50%;background-color: #cfcfcf;
}
</style>
绝对定位布局的灵活性较强,但通常情况下不适用于创建复杂的响应式布局,因为它会导致页面内容脱离文档流,且难以处理复杂的排列关系。
二、两列布局的经典实现
在实际的项目中,两列布局 是一种非常常见的布局形式。常见的两列布局包括主内容区域和侧边栏,它们通常具有不同的宽度。
2.1 基于浮动的两列布局
经典的基于浮动的两列布局,左侧是主内容,右侧是侧边栏:
<div class="container"><div class="main-content">主内容</div><div class="sidebar">侧边栏</div>
</div><style>
.container {width: 100%;overflow: hidden; /* 清除浮动 */
}.main-content {float: left;width: 70%;background-color: #eaeaea;
}.sidebar {float: right;width: 30%;background-color: #cfcfcf;
}
</style>
2.2 Flexbox 实现的两列布局
使用 弹性盒布局(Flexbox) 实现两列布局更加简洁和直观。display: flex
可以轻松实现横向排列,并通过 flex-grow
控制列的伸缩性。
<div class="container"><div class="main-content">主内容</div><div class="sidebar">侧边栏</div>
</div><style>
.container {display: flex;
}.main-content {flex-grow: 3;background-color: #eaeaea;
}.sidebar {flex-grow: 1;background-color: #cfcfcf;
}
</style>
Flexbox 的优势在于它可以自动适应不同的屏幕尺寸,同时在对齐和分布元素方面具有极大的灵活性。
三、创建简单的传统网格框架
3.1 固定宽度网格
固定宽度网格 是最简单的网格布局之一,它通常用于较小的网页或定宽设计中。
<div class="container"><div class="row"><div class="column">列 1</div><div class="column">列 2</div><div class="column">列 3</div></div>
</div><style>
.container {width: 960px;margin: 0 auto;
}.row {display: flex;
}.column {width: 30%;margin: 1%;background-color: #ddd;
}
</style>
例子中网格是一个 960px 宽的定宽布局。每一列都具有固定的宽度,并通过 margin
保持间距。
3.2 创建液态网格
液态网格可以根据视口宽度自动调整列的宽度。通过使用 calc()
函数,可以轻松地进行计算。
<div class="container"><div class="row"><div class="column">列 1</div><div class="column">列 2</div><div class="column">列 3</div></div>
</div><style>
.container {width: 100%;
}.row {display: flex;
}.column {width: calc(33.33% - 20px);margin: 10px;background-color: #ddd;
}
</style>
这个例子使用 calc()
函数来减去列之间的间距,使得列的宽度能根据视口的宽度自动调整,创造出更灵活的网格布局。
3.3 语义 vs “无语义” 网格系统
传统的网格系统通常依赖于大量的类名,比如 .col-1
、.col-2
等等。这种网格布局方式并不关注内容的语义,导致代码难以维护。
<div class="row"><div class="col-4">内容 1</div><div class="col-8">内容 2</div>
</div>
而现代开发更强调语义化布局,即通过使用更具描述性的类名,来表达结构和内容的关系。
<div class="header">头部</div>
<div class="main-content">主要内容</div>
<div class="sidebar">侧边栏</div>
3.4 启用偏移容器
在网格布局中,有时需要某些列偏移一定的距离,以便实现更复杂的布局。可以通过增加 margin
或使用 calc()
来实现。
<div class="row"><div class="column offset-2">偏移 2 列</div><div class="column">内容</div>
</div><style>
.column {width: calc(30% - 10px);margin-right: 10px;
}.offset-2 {margin-left: calc(20% + 10px);
}
</style>
四、浮动网格的限制
浮动网格尽管能实现大部分布局需求,但它有许多局限性,特别是清除浮动和内容对齐问题。这些问题在现代布局方法如 Flexbox 和 CSS Grid 中得到了更好的解决。
1. 清除浮动(Clearfix)问题
当使用浮动布局时,一个最常见的问题是清除浮动(clearfix)。因为浮动的元素会脱离文档流,父容器往往不会自动扩展以包围浮动的子元素。这会导致父容器的高度坍塌,需要开发者手动清除浮动来解决这个问题。
例如,如果没有清除浮动的情况下,父元素的背景颜色不会扩展以包含所有子元素:
<div class="container"><div class="float-box">浮动框 1</div><div class="float-box">浮动框 2</div>
</div><style>
.container {background-color: #eaeaea; /* 背景颜色不会扩展 */
}.float-box {float: left;width: 50%;background-color: #cfcfcf;
}
</style>
解决方案: 添加一个伪元素清除浮动,或在容器元素上使用overflow: hidden
或clearfix
类。
.container::after {content: "";display: table;clear: both;
}
2. 响应式布局不便
CSS浮动布局在响应式设计方面的支持较差。因为浮动元素的宽度通常是以固定值或百分比来定义的,所以当视口(viewport)宽度发生变化时,必须手动调整布局的CSS代码,这使得代码难以维护和扩展。与Flexbox和CSS Grid相比,浮动布局缺乏对元素自动对齐和分布的支持。
3. 无法轻松实现垂直居中
浮动布局的一个显著限制是无法轻松实现垂直居中对齐。由于浮动元素不占用其所在行的空间,开发者必须使用复杂的技巧(如使用margin
调整)来实现垂直居中,这与现代布局方法(如Flexbox的align-items
或CSS Grid的align-content
)的简单和直观形成鲜明对比。
/* 常见的垂直居中技巧 */
.parent {position: relative;height: 200px;
}.child {position: absolute;top: 50%;transform: translateY(-50%);
}
4. 浮动元素的顺序问题
使用浮动布局时,元素的顺序是固定的,即元素在HTML文档中的排列顺序决定了它们在页面上的显示顺序。这对于需要不同屏幕大小下重新排序的响应式布局来说是一个很大的限制。而使用CSS Grid或Flexbox,开发者可以通过简单的CSS规则来改变元素的排列顺序,而不需要调整HTML结构。
/* Flexbox 的简单 reorder 例子 */
.parent {display: flex;
}.child:first-child {order: 2;
}.child:last-child {order: 1;
}
5. 边距重叠(Margin Collapse)
浮动元素在处理相邻元素的边距(margin)时可能会出现边距重叠问题,这意味着两个相邻的浮动元素的边距可能会意外地合并,导致布局出现问题。解决这
6. 无法轻松实现复杂的网格布局
浮动布局更适合简单的布局需求。当需要实现复杂的网格布局(如多列、多行且包含嵌套的子网格)时,浮动布局的代码会变得异常复杂且难以维护。相反,CSS Grid提供了一种更简
7. 缺乏对齐和分布的高级功能
浮动布局不具备CSS Grid或Flexbox提供的对齐(alignment)和分布(distribution)功能。比如,CSS Grid可以轻松控制网格项之间的间距,Flexbox可以让元素在容器中均匀分布或对齐。浮动布局只能通过手动计算margin
和padding
来实现,这在大型项目中变得非常繁琐和易错。
五、弹性盒网格(Flexbox)
Flexbox 是一种全新的 CSS 布局方式,专为灵活布局设计。与传统的浮动布局相比,它具有更简洁的语法和更强的适应性。
Flexbox 可以轻松实现各种复杂布局:
<div class="container"><div class="item">Item 1</div><div class="item">Item 2</div><div class="item">Item 3</div>
</div><style>
.container {display: flex;justify-content: space-between;
}.item {width: 30%;background-color: #ddd;
}
</style>
例子中justify-content: space-between
可以让所有子元素在容器中均匀分布,而不需要手动设置 margin
。
六、第三方网格系统
在实际项目中,很多人喜欢使用第三方网格系统来加速开发,如 Bootstrap、Foundation 等。
6.1 Bootstrap网格系统
Bootstrap的网格系统基于 flexbox,采用一个包含最多12个列的布局,可以根据屏幕大小自动调整布局。其响应式设计通过定义不同的断点,使网页能够适配不同设备(如手机、平板、桌面显示器等)。
核心特性:
- 基于Flexbox:通过
flexbox
提供灵活的列对齐和排列方式。 - 12列布局:默认网格系统是12列,每行最多容纳12个“列单位”,可以根据需要自由分配列宽。
- 响应式断点:提供5种预定义的响应式断点(extra small, small, medium, large, extra large)。
- 可嵌套的网格:列内可以再包含一套网格系统,形成嵌套布局。
使用示例:
<div class="container"><div class="row"><div class="col-sm-4">列1</div><div class="col-sm-4">列2</div><div class="col-sm-4">列3</div></div>
</div>
-
.container
:定义一个固定宽度的容器。 -
.row
:用于创建一行,行内的列将被水平排列。 -
.col-sm-4
:表示在小屏幕及以上的设备中,每个列占据4个网格单位(共12个单位)。
断点说明:
Bootstrap定义了几个重要的断点类,以便为不同的屏幕尺寸设置不同的列数:
-
col-xs-
(超小屏幕,如手机) -
col-sm-
(小屏幕,如平板) -
col-md-
(中屏幕,如笔记本) -
col-lg-
(大屏幕,如桌面显示器) -
col-xl-
(超大屏幕)
例如,col-md-6
意味着在中屏及以上的设备上,这一列占据12列中的6列,也就是50%的宽度。
其他特性:
- Offset列:使用
offset
类为列增加空白间距。 - Order类:使用
order
类轻松改变列的显示顺序。
<div class="row"><div class="col order-2">列2</div><div class="col order-1">列1</div>
</div>
6.2 Foundation网格系统
Foundation的网格系统非常灵活,也基于 flexbox,与Bootstrap相似,但在某些方面提供了更简便的语法和定制选项。Foundation的网格系统同样支持12列的响应式布局,但其断点系统和类名略有不同。
核心特性:
- 基于Flexbox或CSS Grid:用户可以选择使用
flexbox
或CSS Grid
进行布局。 - 12列布局:同样的12列布局系统,每行最多容纳12个网格单位。
- 可选断点:Foundation允许用户自己定义断点,默认提供了小、中、大、超大的断点设置。
- 灵活的间距控制:允许更细粒度的列间距控制。
使用示例:
<div class="grid-container"><div class="grid-x grid-padding-x"><div class="cell small-4">列1</div><div class="cell small-4">列2</div><div class="cell small-4">列3</div></div>
</div>
-
.grid-container
:定义一个网格容器。 -
.grid-x
:表示水平布局(x轴方向)。 -
.cell
:每一个网格单元。 -
small-4
:表示在小屏幕及以上的设备中,每个单元占4个网格单位(共12个单位)。
断点说明:
Foundation中的断点与Bootstrap类似,但它的命名方式略有不同,用户还可以自定义断点。
-
small-
:小屏幕 -
medium-
:中屏幕 -
large-
:大屏幕 -
xlarge-
:超大屏幕
其他特性:
- 嵌套网格:和Bootstrap一样,Foundation支持嵌套网格布局。
- 自动尺寸单元:使用
auto
类,Foundation允许单元自动调整大小,填满剩余空间。
<div class="grid-x grid-padding-x"><div class="cell auto">自动宽度</div><div class="cell small-6">固定宽度</div>
</div>
6.3 比较与总结
相似之处:
- 都基于12列网格系统。
- 支持响应式布局,允许开发者根据屏幕大小调整内容。
- 都使用
flexbox
作为底层布局机制,提供灵活的列对齐和排序。
不同之处:
- 断点设置:Bootstrap的断点固定且命名简单,而Foundation允许用户自定义断点。
- 语法简洁度:Foundation的网格语法相对更简洁,例如它使用
cell
代替Bootstrap的col
。 - 定制性:Foundation更灵活,尤其在定制断点和控制列间距方面表现出色。
- 兼容性:Bootstrap在社区和第三方支持上稍显优势,因为它的用户和扩展库更多。
两者都非常强大,选择使用哪个框架通常取决于项目需求以及开发团队的偏好。如果你需要一个更灵活的断点系统或喜欢简化的语法,Foundation是不错的选择;如果你想要一个社区支持更广泛且集成了更多组件的系统,Bootstrap则更适合。
如有表述错误及欠缺之处敬请指正补充。
相关文章:

CSS传统布局方法(补充)——WEB开发系列37
开发技术不断演进,布局方式也经历了多个阶段的变革。从最初的基于表格布局到 CSS 的浮动布局,再到今天的弹性盒(Flexbox)与 CSS Grid 网格布局,每一种布局方式都有其独特的背景和解决特定问题的优势。 一、CSS Grid 出…...

【系统架构设计师】软件架构的风格(经典习题)
更多内容请见: 备考系统架构设计师-核心总结索引 文章目录 【第1题】【第2题】【第3~4题】【第5题】【第6题】【第7题】【第8题】【第9题】【第10题】【第11题】【第12题】【第13题】【第14题】【第15~16题】【第17题】【第18~19题】【第20~21题】【第22题】【第23题】【第24~…...

网页打开时,下载的文件fetcht类型?有什么作用?
fetch API是一种用于向服务器发送请求并获取响应的现代Web API。它支持获取各种类型的数据,包括文本、JSON、图像和文件等。fetch API的主要优势之一是支持流式传输和取消请求,这使得处理大型数据集和长时间运行的操作变得更加简单和可靠。此外&…...

作为HR,如何考察候选人的专业知识与技能
这是严肃的话题,如何考察候选人的专业知识和技能。HR招聘是一个让我们既爱又恨的过程。爱的是,我们有机会遇到各种各样的人才;恨的是,要从茫茫人海中找到那个“对的人”简直比找一根针在干草堆里还难。 本系列的文章,…...

阻止冒泡事件
每一div都有一个切换事件 div里包括【复制】事件, 点击【复制按钮】,会触发【切换事件】 因为冒泡 在 Vue 3 中,阻止 click 事件冒泡可以使用以下常规方法: 1 事件修饰符:Vue 3 中提供了多种事件修饰符,…...

聊聊Netty对于内存方面的优化
写在文章开头 Netty通过巧妙的内存使用技巧尽可能节约内存空间,进而减少java中Full gc的STW的时间,由此间接的提升了程序的性能,本文也将直接从源码的角度分析一下Netty对于内存方面的使用技巧,希望对你有所启发。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java…...

2024年轻人驯化AI指南
或许Python编程是答案 我为您精心准备了一份全面的Python学习大礼包,完全免费分享给每一位渴望成长、希望突破自我现状却略感迷茫的朋友。无论您是编程新手还是希望深化技能的开发者,都欢迎加入我们的学习之旅,共同交流进步! &…...

算法:双指针题目练习
文章目录 算法:双指针移动零复写零快乐数盛最多水的容器有效三角形的个数查找总价格为目标值的两个商品三数之和四数之和 总结 算法:双指针 移动零 定义两个指针,slow和fast.用这两个指针把整个数组分成三块. [0,slow]为非零元素,[slow1,fast-1]为0元素,[fast,num.length]为未…...

傅里叶变换的基本性质和有关定理
一、傅里叶变换的基本性质 1.1 线性性质 若 则 其中:a,b是常数 函数线性组合的傅里叶变换等于歌函数傅里叶变换的相应组合。 1.2 对称性 若 则 关于傅里叶变换的对称性还有 虚、实、奇、偶函数的傅里叶变换性质: 1.3 迭次傅里叶变换 对f(x,y)连续两次做二维傅里叶变换…...

VIM使用技巧
VIM使用技巧;VIM常用快捷键;vim常用命令;VIM常用快捷命令;vim使用技巧 VIM使用技巧 移动光标 hjkl,h光标向前移动一个字符的位置;j光标向下移动一行;k光标向上移动一行;l光标向后移动一个字符…...

C语言进阶【4】---数据在内存中的存储【1】(你不想知道数据是怎样存储的吗?)
本章概述 整数在内存中的存储大小端字节序和字节序判断练习1练习2练习3练习4练习5练习6 彩蛋时刻!!! 整数在内存中的存储 回忆知识:在讲操作符的那章节中,对于整数而言咱们讲过原码,反码和补码。整数分为有…...

【mysql面试题】mysql复习之常见面试题(一)
本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》:python零基础入门学习 《python运维脚本》: python运维脚本实践 《shell》:shell学习 《terraform》持续更新中:terraform_Aws学习零基础入门到最佳实战 《k8…...

VB.NET中如何利用ASP.NET进行Web开发
在VB.NET中利用ASP.NET进行Web开发是一个常见的做法,特别是在需要构建动态、交互式Web应用程序时。ASP.NET是一个由微软开发的开源Web应用程序框架,它允许开发者使用多种编程语言(包括VB.NET)来创建Web应用程序。以下是在VB.NET中…...

vue2+js项目升级vue3项目流程
Vue 3 相较于 Vue 2 在性能、特性和开发体验上都有了显著的提升。升级到 Vue 3 可以让你的项目受益于这些改进。但是,升级过程也需要谨慎,因为涉及到代码的重构和潜在的兼容性问题。 1. 升级前的准备 备份项目: 在开始升级之前,…...

做EDM邮件群发营销时如何跟进外贸客户?
跟进外贸客户是外贸业务中至关重要的一环,需要耐心和策略。以下是一些建议,帮助你有效跟进外贸客户: 充分了解产品: 深入了解自己的产品,包括品质、价格竞争力、适用市场等。 只有对产品有充分的了解,才…...

【Java经典游戏】-01-是男人就坚持30秒
hello!各位彦祖们!我们又见面了!! 今天兄弟我给大家带来了一款经典趣味小游戏的项目案例-是男人就坚持30秒 本项目案例涉及到的技术: Java 语法基础Java 面向对象JavaSwing 编程Java 线程 是一个非常适合小白来加强…...

微调框QSpinBox
作用:允许用户按照一定的步长,来增加或减少其中显示的数值 有两种类型的微调框 QSpinBox - 用于整数的显示和输入QDoubleSpinBox - 用于浮点数的显示和输入 值 包括最大值、最小值、当前值 // 获取和设置当前值 int value() const void setValue(in…...

在线查看 Android 系统源代码 AOSPXRef and AndroidXRef
在线查看 Android 系统源代码 AOSPXRef and AndroidXRef 1. AOSPXRef1.1. http://aospxref.com/android-14.0.0_r2/1.2. build/envsetup.sh 2. AndroidXRef2.1. http://androidxref.com/9.0.0_r3/2.2. build/envsetup.sh 3. HELLO AndroidReferences 1. AOSPXRef http://aospx…...

JavaScript substr() 方法
定义和用法 substr() 方法可在字符串中抽取从 start 下标开始的指定数目的字符。 <script type"text/javascript">var str"Hello world!" document.write(str.substr(3))</script>lo world!<script type"text/javascript">v…...

教你把图片转换为炫酷的翻页电子杂志
翻页电子杂志以其炫酷的视觉效果和便捷的阅读方式,受到了许多用户的喜爱。想要把普通的图片转换成这样的效果,其实并不复杂。下面,就让我来为您介绍一下如何操作。 首先,您需要准备一些基本的工具和材料。您需要一个图像编辑软件…...

生信软件35 - AI代码编辑器Cursor
1. Cursor - AI代码编辑器 Cursor的核心功能是利用生成式AI,帮助程序员通过自然语言描述快速生成代码。让程序员未来需要关注的是“做什么”(What)而不是“怎么做”(How),即在使用AI生成代码的基础上&…...

Vue Router 编程式导航全攻略:深入掌握 push, replace, go, back, forward,beforeEach 方法
Vue Router 编程式导航全攻略:深入掌握 push, replace, go, back, forward,beforeEach 方法 在Vue Router中,编程式导航是一种通过JavaScript代码来实现路由跳转的方法。与声明式导航(使用<router-link>标签)相比ÿ…...

切换淘宝最新镜像源:优化NPM包管理的极致体验
在NPM生态系统中,快速、安全地获取所需的包是每个前端工程师追求的目标。然而,由于不同地区的网络环境,直接通过官方NPM仓库获取包可能会导致下载速度缓慢、超时等问题。针对这些情况,淘宝团队提供了优秀的NPM镜像源,并且定期更新。本文将详尽介绍如何切换淘宝最新镜像源,…...

react 基础语法
前置知识 类的回顾 通过class关键字定义一个类 类名首字母大写 class类有constructor构造器 new 一个类得到一个实例 类还有方法,该方法也会在其原型上 static静态数据,访问静态属性通过 类名.id getter和setter getter:定义一个属性&…...

k8s的NodeIP、PodIP、ClusterIP、ExternalIP
1.NodeIP K8s集群由Master Node与Worker Node组成。 Node:组成k8s集群的机器,可以是物理机或虚拟机。 Master Node :管理节点也叫控制平面主要负责管理控制方面。 Worker Node::工作节点用于部署处理业务的工作负载或p…...

【vue element-ui】关于删除按钮的提示框,可一键复制
实现效果: Delete: function (id) {this.$confirm(此操作将永久删除该文件, 是否继续?, 提示, {confirmButtonText: 确定,cancelButtonText: 取消,type: warning,center: true,}).then(() > {Delete(id).then(() > {this.$message({type: success,message: 删…...

内部工具使用
1. displaytool 开发的渲染工具,如将车端建图结果显示在渲染窗口中,便于查bug 2. localization / csmap 开发的定位工具 和 车端建图工具 3. bolepack 第三方,处理感知数据的工具 运行流程:1-> 2 -> 3 bol…...

Spring Boot-静态资源管理问题
在Spring Boot中,静态资源管理是构建现代Web应用程序时必不可少的一部分。无论是处理静态页面、图片、CSS、JavaScript文件,还是一些自定义文件,正确管理这些资源能够提升用户体验和优化应用的性能。 1. Spring Boot中的静态资源管理概述 S…...

白酒与商务宴请:如何成为餐桌上的受宠者之一?
在商务宴请的场合中,白酒往往是餐桌上不可或缺的佳酿。一瓶好的白酒,不仅能够彰显主人的品味,还能为宾客带来愉悦的享受。那么,在商务宴请中,如何选择一瓶合适的白酒,让自己成为餐桌上的受宠者之一呢&#…...

【C语言零基础入门篇 - 9】:文件操作
文章目录 文件操作文件的简介指向指针的文件文件的打开方式字符的读取和存储数据的读取和存储 文件操作 文件的简介 一、什么是文件? 文件有不同的类型,主要有两种文件: (1)程序文件。(2)数据…...