CSS 浮动布局

2023-09-16 16:19:45

浮动的设计初衷

float: left/right/both;

浮动是网页布局最古老的方式。

浮动一开始并不是为了网页布局而设计,它的初衷是将一个元素拉到一侧,这样文档流就能够包围它

常见的用途是文本环绕图片:

在这里插入图片描述

浮动元素会被移出正常文档流,并被拉到容器边缘

清除浮动的原因及方法

浮动元素的高度不会追加到父元素上

如果浮动的元素比容器高,那么就可能发生容器折叠现象:

在这里插入图片描述

这时,我们就需要清除浮动。

清除浮动不太优雅的方式:在容器末尾添加一个空 div,设置 clear: both,清除两边浮动,使得容器会向下扩展包含它。

<div style="clear: both;"></div>

既然是添加一个 div 元素,不如使用伪元素 ::after 来实现。

.clearfix::after{
	display: block;
	content: " ";
	clear: both;
}

这个 clearfix 类是添加到包含浮动元素的元素上,而不是浮动元素本身。

使用 display: block 的原因:默认情况下,伪元素是内联元素,而不是块级元素。为了确保伪元素占据一整行并且在浮动元素之后换行,我们需要将其设置为块级元素。更重要的是,clear 属性只对块级元素生效。

设置 content: " " 的原因:解决一些旧版浏览器的 Bug。


清除浮动后的另一个问题:浮动元素的外边距不会折叠到清除浮动后的容器外部,但是非浮动元素会

对此,解决该问题的clearfix的修改版如下:

.clearfix::after,
.clearfix::before{
    display: table;
    content: " ";
}

.clearfix::after{
    clear: both;
}

为什么使用 display:table 而不是 display: block :外边距无法通过单元格元素折叠。


浮动陷阱:浏览器会将浮动元素尽可能地放在靠上的地方

如果众多的浮动元素高度不一致,最后导致布局会千变万化。哪怕是 1px 的高度差距也会导致浮动陷阱。

解决方法:给每一行的第一个元素清除左浮动

假设每行有 m 个元素:

.floatElement::nth-child(mn+1){
	clear: left
}

浮动布局示例解析:古诗欣赏

初始源代码如下:

index.html

<div class="container">
	<header>
		<h1>古诗欣赏</h1>
	</header>
	<main class="main clearfix">
		<h3>五言绝句</h3>
		<div>
			<div class="media">
				<img class="media-image" src="相思.png">
				<div class="media-body">
					<h4>相思·王维</h4>
					<p>
						红豆生南国,春来发几枝。
						愿君多采撷,此物最相思。
					</p>
				</div>
			</div>
			<div class="media">
				<img class="media-image" src="听筝.png">
				<div class="media-body">
					<h4>听筝·李端</h4>
					<p>
						鸣筝金粟柱,素手玉房前。
						欲得周郎顾,时时误拂弦。
					</p>
				</div>
			</div>
			<div class="media">
				<img class="media-image" src="江雪.png">
				<div class="media-body">
					<h4>江雪·柳宗元</h4>
					<p>
						千山鸟飞绝,万径人踪灭。
						孤舟蓑笠翁,独钓寒江雪。
					</p>
				</div>
			</div>
			<div class="media">
				<img class="media-image" src="春晓.png">
				<div class="media-body">
					<h4>春晓·孟浩然</h4>
					<p>
						春眠不觉晓,处处闻啼鸟。
						夜来风雨声,花落知多少。
					</p>
				</div>
			</div>
		</div>
	</main>
</div>

style.css

:root {
    box-sizing: border-box; /* 修改盒模型 */
}

*,
::before,
::after {
    box-sizing: inherit; /* 继承 box-sizing */
}

body {
    background-color: aliceblue;
    font-family: Arial, Helvetica, sans-serif;
}

/* 猫头鹰选择器 */

body * + *{
    margin-top: 1.5em;
}

header{
    padding: 1em 2em;
    background-color: antiquewhite;
    border-radius: .5em;
    margin-bottom: 2em;
}

.main{
    padding: 0 1.5em;
    background-color: white;
    border-radius: .5em;
}

.container{
    max-width: 800px; /* 自动适配宽度 */
    margin: 0 auto; /* 双容器模式 水平居中 */
}

.media{
    float: left;
    margin: 0 1.5em 1.5em 0; /* 重置 margin */
    width: calc(50% - 1.5em); /* 从宽度里减去 1.5em */
    padding: 1.5em;
    background-color:rgb(238, 245, 247);
    border-radius: .5em;
}

.media-image{
    width: 60px;
    height: 60px;
}

/* 清除浮动 */

/* .clearfix::after{
	display: block;
	content: " ";
	clear: both;
} */

/* 清除浮动修改版 */

.clearfix::after,
.clearfix::before{
    display: table;
    content: " ";
}

.clearfix::after{
    clear: both;
}

/* 解决浮动陷阱 */

.media:nth-child(odd){
    clear: left;
}

效果图:

在这里插入图片描述

实现图片被文字环绕

.media-image{
    width: 100px;
    height: 100px;
    float: left; /* 左浮动 */
}

.media-body{
    margin-top: 0; /* 覆盖猫头鹰选择器 */
}

.media-body h4{
    margin-top: 0; /* 覆盖用户代理样式表 */
}

效果:

在这里插入图片描述

实现图片在左文字在右

在这里插入图片描述

如上,图片被包含在了相邻的同级元素 media-body 中。

如果想实现图片在左文字在右,可以为文字创建一个块级格式上下文(block formatting context,BFC)。

BFC 将内部与外部隔绝开,内外互不影响。

创建 BFC 的方式:

  1. float 不为 none。
  2. overflow 不为 visible。
  3. display 为 inline-block、table-cell、table-caption、flex、inline-flex、grid、inline-grid。
  4. position 为 absolute 或 fixed。

网页的根元素就是一个顶级的 BFC。

CSS 修改如下:

.media-image{
    width: 60px;
    height: 60px;
    float: left;
    margin-right: 1.5em; /* 图片与文字间增加一定间距 */
}

.media-body{
    margin-top: 0; /* 覆盖猫头鹰选择器 */
    overflow: auto; /* 创建 BFC */
}

效果图:

在这里插入图片描述

注意:使用浮动或 display: inline-block创建BFC的元素的宽度会变为 100%

基于浮动实现网格系统

在这里插入图片描述

大部分的 CSS 框架都实现了自己的网格系统:在一个行容器内放置若干列容器,列的宽度由列容器的类决定

<div class="row">
	<div class="column-1"></div>
	<div class="column-1"></div>
	<div class="column-1"></div>
	<div class="column-1"></div>
	<div class="column-1"></div>
	<div class="column-1"></div>
	<div class="column-3"></div>
	<div class="column-3"></div>
</div>

使用网格系统可以提高代码的可复用性。

网格系统不参与行列元素的视觉样式,只负责设置宽度和定位。在行列内的元素就不必再考虑宽度和定位了。

/* 网格系统 */

.row::after{
    display: block;
    content: " ";
    clear: both;
}

[class*="column-"]{
    float: left;
    padding: 0 0.75em; /* 左右设置内边距 */
    margin-top: 0; /* 去掉顶部外边距 */
}

.column-1{
    width: 8.333%;
}
.column-2{
    width: 16.6667%;
}
.column-3{
    width: 25%;
}
.column-4{
    width: 33.3333%;
}
.column-5{
    width: 41.6667%;
}
.column-6{
    width: 50%;
}
.column-7{
    width: 58.333%;
}
.column-8{
    width: 66.6667%;
}
.column-9{
    width: 75%;
}
.column-10{
    width: 83.333%;
}
.column-11{
    width: 91.6667%;
}
.column-12{
    width:100%;
}

完整 CSS:

:root {
    box-sizing: border-box; /* 修改盒模型 */
}

*,
::before,
::after {
    box-sizing: inherit; /* 继承 box-sizing */
}

body {
    background-color: aliceblue;
    font-family: Arial, Helvetica, sans-serif;
}

/* 猫头鹰选择器 */

body * + *{
    margin-top: 1.5em;
}

header{
    padding: 1em 2em;
    background-color: antiquewhite;
    border-radius: .5em;
    margin-bottom: 2em;
}

.main{
    padding: 0 1.5em 1.5em;
    background-color: white;
    border-radius: .5em;
}

.container{
    max-width: 800px; /* 自动适配宽度 */
    margin: 0 auto; /* 双容器模式 水平居中 */
}

/* 媒体对象的样式 */

.media{
    padding: 1.5em;
    background-color:rgb(238, 245, 247);
    border-radius: .5em;
}

.media-image{
    width: 60px;
    height: 60px;
    float: left;
    margin-right: 1.5em;
}

.media-body{
    margin-top: 0; /* 覆盖猫头鹰选择器 */
    overflow: auto; /* 创建 BFC */
}

.media-body h4{
    margin-top: 0; /* 覆盖用户代理样式表 */
}

/* 清除浮动 */

/* .clearfix::after{
	display: block;
	content: " ";
	clear: both;
} */

/* 清除浮动修改版 */

.clearfix::after,
.clearfix::before{
    display: table;
    content: " ";
}

.clearfix::after{
    clear: both;
}

/* 网格系统 */

.row::after{
    display: block;
    content: " ";
    clear: both;
}

[class*="column-"]{
    float: left;
    padding: 0 0.75em; /* 左右设置内边距 */
    margin-top: 0; /* 去掉顶部外边距 */
}

.column-1{
    width: 8.333%;
}
.column-2{
    width: 16.6667%;
}
.column-3{
    width: 25%;
}
.column-4{
    width: 33.3333%;
}
.column-5{
    width: 41.6667%;
}
.column-6{
    width: 50%;
}
.column-7{
    width: 58.333%;
}
.column-8{
    width: 66.6667%;
}
.column-9{
    width: 75%;
}
.column-10{
    width: 83.333%;
}
.column-11{
    width: 91.6667%;
}
.column-12{
    width:100%;
}

效果图如下:

在这里插入图片描述

与前面的相比,这个导致了内容出现了错位,没有对齐标题。

使用负 margin 拉伸行元素解决该问题:

/* 网格系统 */

.row{
    margin-left: -0.75em;
    margin-right: -0.75em;
}

...
...

效果图:

在这里插入图片描述

最终代码

更多推荐

数据结构与算法的力量:编写更高效的代码

文章目录为什么数据结构和算法重要?1.提高性能2.节省资源3.解决复杂问题4.改进代码质量常见数据结构和算法数据结构1.数组(Array)2.链表(LinkedList)3.栈(Stack)4.队列(Queue)算法1.排序算法2.搜索算法3.递归算法编写高效的代码的关键考虑因素1.时间复杂度2.空间复杂度3.数据的组

Android 自定义加解密播放音视频(m3u8独立加密)

文章目录背景加密流程音视频解密音视频播放结语背景当涉及App内部视频的时候,我们不希望被别人以抓包的形式来爬取我们的视频大视频文件以文件方式整个加密的话需要完全下载后才能进行解密当前m3u8格式虽然支持加密,但是ts格式的小视频可以独立播放的,也就是ts文件本身没有被加密,或者加密方法过于复杂根据以上,我通过修改Exo

Linux 多线程( 进程VS线程 | 线程控制 )

文章目录Linux进程VS线程进程的多个线程共享进程和线程的关系线程创建pthread_create获取线程IDpthread_self线程等待pthread_join终止线程进程分离线程ID及进程地址空间布局Linux进程VS线程进程是资源分配的基本单位。线程是OS调度的基本单位。线程共享进程数据,但也拥有自己的一部

【CSS3】CSS3 3D 转换 ② ( 3D 透视视图 | “ 透视 “ 概念简介 | 视距与成像关系 | CSS3 中 “ 透视 “ 属性设置 | “ 透视 “ 语法设置 | 代码示例 )

文章目录一、"透视"概念简介1、"透视"概念引入2、视距与成像关系二、CSS3中"透视"属性设置1、"透视"语法设置2、代码示例-"透视"语法设置添加了透视后的代码示例执行结果一、"透视"概念简介1、"透视"概念引入在本博客中引入3D效果透视视图Perspective概念;3D视图中产生3D效果,最终要的是有透视效果,

注解、自定义注解、处理自定义注解

注解概述Java注解(Annotation)又称Java标注,是JDK5.0引入的一种注释机制。Java语言中的类、构造器、方法、成员变量、参数等都可以被注解进行标注。例如:publicclassUserServiceTest{@TestpublicvoidtestLogin(){}@Testpublicvoidtes

【网络安全】黑客自学笔记

1️⃣前言🚀作为一个合格的网络安全工程师,应该做到攻守兼备,毕竟知己知彼,才能百战百胜。计算机各领域的知识水平决定你渗透水平的上限🚀【1】比如:你编程水平高,那你在代码审计的时候就会比别人强,写出的漏洞利用工具就会比别人的好用;【2】比如:你数据库知识水平高,那你在进行SQL注入攻击的时候,你就可以写出更多更好的S

ERR_CONNECTION_REFUSED等非标准的HTTP错误状态码原因分析和解决办法

文章目录一、DNSResolutionFailed1,DNS服务器故障2,DNS配置错误3,DNS劫持4,域名过期-5,其他网络问题二、ERR_CONNECTION_REFUSED-"ERR_CONNECTION_REFUSED"错误可能有多种原因三、ERR_SSL_PROTOCOL_ERROR"ERR_SSL_PRO

MySQL日志管理、备份与恢复

绪论备份的主要目的是灾难恢复,备份还可以测试应用、回滚数据修改、查询历史数据、审计等。而备份、恢复中,日志起到了很重要的作用1、日志1.1日志保存位置MySQL的日志默认保存位置为/usr/local/mysql/data##配置文件vim/etc/my.cnf[mysqld]##错误日志,用来记录当MySQL启动、停

Redis 数据类型

1、String数据类型1.1概述String是redis最基本的类型,最大能存储512MB的数据,String类型是二进制安全的,即可以存储任何数据、比如数字、图片、序列化对象等1.2SET/GET/APPEND/STRLENredis127.0.0.1:6379>existsmykey#判断该键是否存在,存在返回1

Go并发的竞争条件

在一个线性(就是说只有一个goroutine的)的程序中,程序的执行顺序只由程序的逻辑来决定。例如,我们有一段语句序列,第一个在第二个之前(废话),以此类推。在有两个或更多goroutine的程序中,每一个goroutine内的语句也是按照既定的顺序去执行的,但是一般情况下我们没法去知道分别位于两个goroutine的

【元宇宙】管理元宇宙,以最好的方式引导它

同样地,元宇宙如此具有颠覆性一它是不可预测的、循序渐进的,而且仍然充满不确定性,我们不可能知道会出现什么问题,但我们可以思考如何最好地解决已经存在的问题,以及如何最好地引导它。作为选民、用户、开发者和消费者,我们有决定权。这不仅是关于我们的虚拟角色在虚拟空间中如何遨游的问题,而且是关于围绕着谁构建元宇宙、如何构建以及基

热文推荐