从圣杯布局中,我彻底了解float,margin🤔

最近了解了圣杯布局和双飞燕布局,对 margin-right 和 float 了解更深了,写下这篇文章分享下我的收获

圣杯布局

先看看什么是圣杯布局。像下面这张图,有 title 和 footer,中间内容分成了三块,left,和 right 内容宽度固定,container 内容宽度随屏幕宽度变化而变化。这是在布局上的要求。这个要求很容易 flex 来实现,但是不满足加载顺序

圣杯对加载顺序也有要求,先加载 container,然后加载 left 和 right。DOM 解析是从前往后的,所以如果 left DOM 是在 container 之前,那么就会先加载 left 的 DOM 结构,并且先加载 left 涉及到的资源

上面的图像不像一个抽象的圣杯?

圣杯布局的写法是将 container 写在 left 和 right 之前,这样就可以满足加载顺序了。

好,基本要求了解了,那该如何实现呢?

由于网上有各种文章,这个话题都被说烂了,下面就不详细说代码了,只说重点的部分

html 复制代码
<!DOCTYPE html>
<html lang="en">
	<head>
		<title>圣杯布局</title>
	</head>
	<body>
		<div class="title">title</div>

		<div class="content">
			<div class="float container">container</div>
			<div class="float left">left</div>
			<div class="float right">right</div>
		</div>
		<div class="footer">footer</div>
	</body>
</html>

title 和 footer 的 DOM 结构很普通,放在最前面和最后面。主要看中间部分,container 的 DOM 结构确实是放在 left 和 right 前面

下面是各个 DOM 结构的样式代码

css 复制代码
.title,
.footer {
	width: 100%;
	height: 30px;
	background-color: antiquewhite;
}
.float {
	float: left;
}
.left,
.right,
.container {
	height: 500px;
	background-color: tomato;
}
.left {
	width: 100px;
	background-color: aquamarine;
}

.right {
	width: 200px;
	background-color: aqua;
}

.container {
	width: 100%;
}

.footer {
	clear: both;
}

为了在页面上明显地区分各个结构,将不同部分标上了不同的颜色,并且对 container,left,right DOM 添加了float: left样式

现在变成了下面这个样子:

可以看到,页面显示的内容和 DOM 结构排列一致,container 在 left, right 前面。

footer 要想不被 float 影响,就要使用 clear:both;

调整 left,理解 float

现在要使用定位样式,将 left 放在 container 的右边

css 复制代码
.content{
	padding: 0 200px 0 100px;
}

先对 content 添加了 padding 样式,为接下来的 left 和 right 腾出位置

css 复制代码
.left {
	width: 100px;
	background-color: aquamarine;
	/* 将left放到container的左边 */
	margin-left: -100%;
}

然后对 left 添加margin-left样式,想让 left 往左移。现在是这个样子:

可以看到 left 贴到了 container 的右边,首先,这不是最终位置,最终位置是贴到窗口的左边框。其次,我想问的是,为什么 left 加上了margin-left: -100%;后会到这个位置

margin-left 的作用是将当前元素往左移,margin-left: -100%;往左移动父元素宽度(content.width)的距离,即 content 的宽度 width。 又因为 content 元素的 box-sizing 是默认的content-box,所以 width 的 内容是不包含 padding 的宽度的。

现在假设一下,left 是紧挨着 container 右边的,那么往右移动content.width的距离后,确实会恰好紧挨着 container 左边的。但现实是,left 是放在 container 下面的,这个如何解释?

其他 left **就是**紧挨着在 container 右边的。因为,它们都是float:left;元素。而现在 left 在 container下面,只是因为被 container 挤下来了而已。如果把 container 的宽度放小一定程度,那就会看到 left 跑上去了,如果再缩小,还会看到 right 跑上去。

理解 float 的元素之间是紧紧挨着的,是理解圣杯布局样式的关键

再给 left 加点样式,让其贴到整个视口的左边

css 复制代码
.left {
	width: 100px;
	background-color: aquamarine;
	/* 将left放到container的左边 */
	margin-left: -100%;
	/* 相对定位 */
	position: relative;
	right: 100px;
}

对于relative来说,right:100px;意味当前元素的右边,距离原本的位置右边有 100px 的距离。效果就是往左移动 100px 的距离

调整 right,理解 margin

css 复制代码
.right {
	width: 200px;
	background-color: aqua;
	/* 将right放到container的右边 */
	margin-right: -200px;
}

right 元素的定位设置只有简单的margin-right: -200px;,就能实现准确定位:

太神奇了吧

理解这个现象,首先要理解 margin-right。

我们知道 margin-left 如果是负值的话,效果就相当于将自身往左移动,而对于 margin-right 来说,不是将自身往右移,而是将当前元素的右边元素左移。margin 的意思是元素之间的边距,如果边距为负,自然就会出现元素重叠的现象,那么为什么不是左边的元素叠放到右边,而是右边的元素叠放到左边呢?

这是因为页面布局就好像是印刷排版,是从左放到右边的,一行放满了,就另起一行重新放置。

这就是为什么当margin-left 为负值时,也是当前元素相对于当前元素的左边元素往左移。当 margin-right 为负值的时候,当前元素的右边元素相对于当前元素往左移

引入排版这个概念后,是不是就很好理解了

right 元素的 width 为 200px,设置margin-right 后,右边元素就会往左移动 200px,彻底地将 right 覆盖。就相当于 right 元素的宽度不存在一样,width 变成了 0;

前面我提到,float 元素就是紧挨着一起的,right 放在了下面,是因为被 container 挤下来的,那么如果 right 宽度为 0 了,还能被挤下来了吗?显然不会了,所以 right 跑到了上面去了。证明完毕

margin-right 还能这么玩,真是没想到啊

总结

这篇文章分享了我学习完圣杯布局之后,对 float 和 margin 概念理解更进一步了,真是不可思议啊🤔

  1. float元素就是互相紧挨着的,下面的元素是被上面给挤下来了
  2. margin就是元素之间的边距,如果边距为负,就会出现元素重叠的现象,并且总是右边的元素覆盖左边的元素

大家有收获吗,欢迎在评论区留言哦

相关推荐
cs_dn_Jie15 分钟前
钉钉 H5 微应用 手机端调试
前端·javascript·vue.js·vue·钉钉
开心工作室_kaic1 小时前
ssm068海鲜自助餐厅系统+vue(论文+源码)_kaic
前端·javascript·vue.js
有梦想的刺儿1 小时前
webWorker基本用法
前端·javascript·vue.js
cy玩具1 小时前
点击评论详情,跳到评论页面,携带对象参数写法:
前端
qq_390161772 小时前
防抖函数--应用场景及示例
前端·javascript
John.liu_Test3 小时前
js下载excel示例demo
前端·javascript·excel
Yaml43 小时前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事3 小时前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶3 小时前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo3 小时前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx