文章目录
浮动
1. 浮动的简介
通过浮动可以使一个元素向其父元素的左侧或右侧移动
使用float
属性来设置于元素的浮动
none
默认值,元素不浮动left
元素向左浮动right
元素向右浮动
注意
- 元素设置浮动以后,水平布局的等式便不需要强制成立
- 元素设置浮动以后,会完全从文档流中脱离,不再占用文档流的位置,所以元素下边的还在文档流中的元素会自动向上移动
2. 浮动的特点
-
浮动元素会完全脱离文档流,不再占据文档流中的位置
-
设置浮动以后,元素会向父元素的左侧或右侧移动
-
浮动元素默认不会从父元素中移出
<style> .box1 { width: 100px; height: 100px; background-color: orange; float: left; } .box2 { width: 200px; height: 200px; background-color: red; } </style> <div class="box1"></div> <div class="box2"></div>
-
浮动元素向左或向右移动时,不会超过前边的浮动元素(先来后到的顺序)
<style> .box1 { width: 200px; height: 200px; background-color: orange; float: left; } .box2 { width: 200px; height: 200px; background-color: red; float: left; } .box3 { width: 200px; height: 200px; background-color: yellow; float: left; } </style> <div class="box1"></div> <div class="box2"></div> <div class="box3"></div>
-
浮动元素不会超过上边的浮动的兄弟元素,最多就是和它一样高
<style> .box1 { width: 300px; height: 300px; background-color: orange; float: left; } .box2 { width: 400px; height: 400px; background-color: red; float: left; } .box3 { width: 300px; height: 300px; background-color: yellow; float: right; } </style> <div class="box1"></div> <div class="box2"></div> <div class="box3"></div>
-
如果浮动元素的上边是一个没有浮动的块元素,则浮动元素无法上移
<style> .box1 { width: 200px; height: 200px; background-color: orange; } .box2 { width: 200px; height: 200px; background-color: red; float: left; } </style> <div class="box1"></div> <div class="box2"></div>
-
浮动元素不会盖住文字,文字会自动环绕在浮动元素的周围,所以我们可以利用浮动来设置文字环绕图片的效果
简单总结:
- 浮动目前来讲它的主要作用就是让页面中的元素可以水平排列,通过浮动可以制作一些水平方向的布局
- 元素设置浮动以后,将会从文档流中脱离,从文档流中脱离后,元素的一些特点也会发生变化
3. 脱离文档流的特点
块元素:
- 块元素不再独占页面的一行
- 脱离文档流以后,块元素的宽度和高度默认都被内容撑开
<style>
.box1 {
background-color: orange;
/* float: left; */
}
</style>
<div class="box1">hello</div>
行内元素:
- 行内元素脱离文档流以后会,特点和块元素一样,可设置宽高
<style>
span {
width: 200px;
height: 200px;
background-color: orange;
float: left;
}
</style>
<span>I am a Span</span>
脱离文档流之后的特点很像行内块元素,不过存在一些差异
<style>
span {
width: 200px;
height: 200px;
background-color: orange;
/* display: inline-block; */
float: left;
}
</style>
<span>I am a Span</span>
<span>I am a Span</span>
4. 简单布局
整体样式
目的
- 熟悉布局(块元素、浮动)
- 公共 css 部分复用
- 复习语义标签
代码
html 代码
<!-- 页眉 -->
<header></header>
<!-- 主体 -->
<main>
<!-- 左边栏 -->
<nav></nav>
<!-- 中心 -->
<article>
<!-- 内容上 -->
<div class="top"></div>
<!-- 内容下 -->
<div class="bottom">
<!-- 内容左 -->
<div class="left"></div>
<!-- 内容中 -->
<div class="middle"></div>
<!-- 内容右 -->
<div class="right"></div>
</div>
</article>
<!-- 右边栏 -->
<aside></aside>
</main>
<!-- 页脚 -->
<footer></footer>
css 代码
/* 公共部分 */
header,
main,
footer {
width: 1000px;
margin: 10px auto;
}
main nav,
main article,
main aside {
float: left;
/* 虽然设置浮动了,但整体大小是被内容撑开的,所以设置一个高度 */
height: 100%;
}
.bottom .left,
.bottom .middle,
.bottom .right {
float: left;
width: 220px;
height: 100%;
}
/* ==========整体布局-上========== */
header {
height: 100px;
background-color: silver;
}
/* ==========整体布局-中========== */
main {
height: 400px;
background-color: #bfa;
}
/* ------左边栏------ */
main nav {
width: 150px;
background-color: red;
}
/* ------中心------ */
main article {
width: 680px;
background-color: green;
margin: 0 10px;
}
/* ---上--- */
article .top {
height: 190px;
background-color: yellow;
margin-bottom: 10px;
}
/* ---下--- */
article .bottom {
height: 200px;
background-color: orange;
}
/* 左 */
.bottom .left {
background-color: lightblue;
}
/* 中 */
.bottom .middle {
background-color: gray;
margin: 0 10px;
}
/* 右 */
.bottom .right {
background-color: wheat;
}
/* ------右边栏------ */
main aside {
width: 150px;
background-color: blue;
}
/* ==========整体布局-下========== */
footer {
height: 100px;
background-color: tomato;
}
效果
5. 练习:w3school 导航条
去除默认样式,引入 reset.css
<link rel="stylesheet" href="css/reset.css" />
css 样式
/* 去除默认样式 */
a {
text-decoration: none;
}
/* ul整体布局 */
.menu {
width: 1211px;
height: 48px;
background-color: #e8e7e3;
margin: 100px auto;
}
/* li整体布局 */
.nav {
/* 浮动li元素 */
float: left;
width: 173px;
line-height: 48px;
}
.nav a {
/* 注意点:升级为块元素,使之继承父类宽高
否则鼠标悬浮在li元素上时,鼠标“箭头”不会进入a元素变成“小手” */
display: block;
/* 内容水平居中 */
text-align: center;
/* 字体样式 */
font-size: 14px;
color: #777777;
font-family: Verdana, Arial, "微软雅黑", "宋体";
}
/* 超链接悬浮效果 */
.nav a:hover {
background-color: #3f3f3f;
color: #e8e7e3;
}
html 代码
<ul class="menu">
<li class="nav"><a href="#">HTML/CSS</a></li>
<li class="nav"><a href="#">Browser Side</a></li>
<li class="nav"><a href="#">Server Side</a></li>
<li class="nav"><a href="#">Programming</a></li>
<li class="nav"><a href="#">XML</a></li>
<li class="nav"><a href="#">Web Building</a></li>
<li class="nav"><a href="#">Reference</a></li>
</ul>
效果
文章目录
高度塌陷与 BFC
6. 高度塌陷
在浮动布局中,父元素的高度默认是被子元素撑开的
当子元素浮动后,其会完全脱离文档流,子元素从文档流中脱离将会无法撑起父元素的高度,导致父元素的高度丢失
父元素高度丢失以后,其下的元素会自动上移,导致页面的布局混乱
所以高度塌陷是浮动布局中比较常见的一个问题,这个问题我们必须要进行处理!
别急,我们接着往下看
7. BFC
BFC(Block Formatting Context)块级格式化环境
- BFC 是一个 CSS 中的一个隐含的属性,可以为一个元素开启 BFC
- 开启 BFC 该元素会变成一个独立的布局区域
元素开启 BFC 后的特点:
- 不会被浮动元素覆盖
- 父子元素外边距不会重叠
- 可以包含浮动的元素
可以通过一些特殊方式来开启元素的 BFC:
-
设置为浮动(不推荐):很明显下方元素被覆盖了,总不能让所有元素都浮动吧
-
设置为行内块元素(不推荐):不再独占一行,宽度变了,同时与下方元素产生了一点空隙
-
设置
overflow
为非visible
值:既没有覆盖元素,也保持了独占一方的特性(保持了宽度),与下方元素也保持了最初的间隙常用的方式为元素设置
overflow:hidden
(overflow:auto
也是 ok 的) 开启其 BFC, 以使其可以包含浮动元素overflow:scroll
会有滚动条,可能并不需要的,所以不太推荐不过,这种方式也存在一定问题,如下,
overflow
并没有完全清除 div2 布局上受到的影响
总结
- 可以通过变成浮动元素,来防止自身被浮动元素覆盖(有点“以毒攻毒”那味了)
- 可以设置行内块,来防止自身及其他元素被浮动元素覆盖(如果说浮动是“独善其身”,那行内块就有点“兼济天下”的意思)
- 可以设置
overflow
属性,包含浮动元素(既“独善其身”,又“兼济天下”,但仍有缺陷)
我们可以打开Zeal
手册(《02-前端开发准备》有介绍),查看关于 BFC 的说明文档
打开Block formatting context
模块后,可以看到有很多开启 BFC 的方式
我这里大概翻译了一下,并整理了一份表格,应该看起来更直观一点(有些概念因为还没有学习,翻译和理解有误的地方还望谅解)
元素或属性 | 说明 |
---|---|
<html> |
文档根元素 |
float: left float: right |
浮动元素(float 不为none ) |
position: absolut position: fixed |
绝对定位元素 |
display: inline-block |
行内块元素 |
display: table-cell |
表格单元,默认值 |
display: table-caption |
表格标题,默认值 |
display: table display: table-row display: table-row-group display: table-header-group display: table-footer-group display: inline-table |
匿名的表格单元,分别是 HTML 表格、表行、表体、表头和表脚的默认值 |
overflow: hidden overflow: scroll overflow: auto |
overflow 不为visible 和clip 的块元素 |
display: flow-root |
|
contain: layout contain: content contain: paint |
|
display: flex display: inline-flex 的直接子元素 |
Flex 项,如果它们本身既不是flex ,也不是grid 或table 容器 |
display: grid display: inline-grid 的直接子元素 |
Grid 项,如果它们本身既不是flex ,也不是grid 或table 容器 |
column-count 不为auto column-width 不为auto |
Multicol 容器,包含column-count: 1 |
column-span: all |
应该总是创建一个新的格式化上下文,即使column-span: all 元素不在 multicol 容器中 |
但是,注意不管哪种方式,多多少少都会有些隐患、缺陷或者说“副作用”
8. clear
我们这里设计三个兄弟元素,对前两个元素进行float
的浮动属性设置,看下效果
由于 box1 的浮动,导致 box3 位置上移也就是 box3 受到了 box1 浮动的影响,位置发生了改变(注意,这里文字并没有被覆盖,《09-浮动》一节说过浮动的特点,其中第 7 点就是“文字环绕”的问题)
如果我们不希望某个元素因为其他元素浮动的影响而改变位置,可以通过clear
属性来清除浮动元素对当前元素所产生的影响
clear
作用:清除浮动元素对当前元素所产生的影响(本质是为元素添加一个margin-top
属性,值由浏览器自动计算)
可选值:
left
清除左侧浮动元素对当前元素的影响right
清除右侧浮动元素对当前元素的影响both
清除两侧中影响较大一侧元素的影响(注意,这里不是同时清除两侧的影响)
9. after
我们学习了上面知识后,了解了高度塌陷问题的解决方式,其中主要有
-
通过
overflow: hidden
等可以为元素开启 BFC -
通过
clear: both
等可以清除浮动对元素产生的影响
同时也了解到,这两种方式都有一定的弊端和隐患。那有没有一种更好的方式去解决高度塌陷的问题呢?
答案当然是:有!
我们直接上效果图
Q1:这里使用了一个伪元素选择器::after
,那有人会问了,跟在 box2 下直接定义一个 box3 有什么区别呢?
A:我们知道,网页的结构思想是:结构+表现+行为。在 box2 下直接定义一个 box3,属于结构;而使用伪元素选择器,属于表现
而高度塌陷问题属于表现问题,定义 box3 的目的是为了撑起 box1 的内容,属于表现,而不是结构,所以在 css 中定义::after
更符合网页的编程思想
Q2:为什么需要使用display: block
呢?
A:因为默认情况下,::after
伪元素是一个行内元素,如果不转为块元素,将仍然撑不起 box1 的高度
10. clearfix
我们在前面《盒模型》一节中说过垂直布局中边距重叠的问题:相邻的垂直方向外边距会发生重叠现象
如上图所示,子元素设置了一个margin-top
之后,父元素跟随子元素一起进行了移动
即我们之前说的父子元素间相邻外边距,子元素会传递给父元素(上外边距)
聪明的小伙伴已经想到了,用刚才说的伪元素选择器啊
好,我们先来看下效果
貌似是没有任何变化,到底是什么地方不对呢?
我们再来回顾下使用after
伪元素的心路历程:
- 使用无内容的 box3 撑起 box1 ==》表现代替结构(
::after
代替 box3) clear
清除浮动对元素产生的影响(还记得clear
的原理么?)
其实就是给元素设置了一个margin-top
属性,不过这个在开发者工具中是看不到的
既然如此,就相当于在 box2 下面添加一个 box3,然后给 box3 设置一个margin-top
属性
到此为止,
∵ 相邻的垂直方向外边距
这个条件仍然满足
∴ 会发生重叠现象
这个结论也依然成立
具体点就是,父子元素间相邻外边距,子元素会传递给父元素(上外边距)
,表现为 box1 和 box2 同步往下移动
那我们应该怎么做才能解决这个问题? 凭你们朴素的情感,应该怎么判? 当然就是让上述条件不满足呗!
怎么能够不满足?当然是让两个元素垂直外边距不相邻啊!
好,多说无益,我们直接上代码看效果!
我们用了before
伪元素选择器,目的当然是让 box1 和 box2 的外边距不相邻,但是好像并没有效果
我们再换成display: inline-block
属性看看
好像是解决了父元素布局的问题,但是子元素怎么还往下跑了一段距离? 是谁给的勇气?
因为inline-block
兼顾行内元素和块元素的特点,既可以设置宽高也不独占一行
在没有设置宽高时,会存在一个默认高度,所以inline-block
仍然行不通
还有一个属性,display: table
Bingo!实现了我们最终想要的效果
Q1:为什么没有使用 clear 属性?
A:不是说了吗?clear
是为了清除浮动对布局的影响,我们现在没有浮动的元素啊,我们要讨论的也不是浮动的问题
Q2:display 不是还有一个none
属性么,为什么不用呢?
A:none
属性是不占据位置,但是也不能让元素相邻的外边距分离啊
Q3:为什么table
值就可以呢?
A:这个问题问的非常好,算是问到点上了!我们上面在讲开启 BFC 的一些方法的时候,也提到了该属性。而且,应该牢记的是,元素开启 BFC 后的其中一个特点就是 父子元素外边距不会重叠
。当然,这里也需要合理选择伪元素选择器,使其外边距不相邻才行
另外,总结一下:
- 高度塌陷问题,一般用
::after
- 外边距重叠问题,一般用
::before
不知道到这里,大家能不能想明白这两件事情
那么问题来了,有没有一个两全其美的办法,既可以解决高度塌陷,又可以解决外边距重叠呢?
当然有!clearfix
这个样式就可以同时解决高度塌陷和外边距重叠的问题
当你在遇到这些问题时,直接使用clearfix
这个类即可,他就可以帮你轻松搞定 css 中的两大难题
.clearfix::before,
.clearfix::after {
content: "";
display: table;
clear: both;
}
其中.clearfix::before
是为了解决外边距重叠问题
.clearfix::before {
content: "";
display: table;
}
.clearfix::after
是为了解决高度塌陷问题
.clearfix::after {
content: "";
display: table;
clear: both;
}
两者合在一起,就可以完美地解决高度塌陷和外边距重叠这两大“世纪难题”了