CSS——让“盒子”动起来:① 浮动

栏目: CSS · 发布时间: 5年前

内容简介:前言:前 10 篇文章,我们基本上都是在用“理论”学习“理论”,那从这篇开始,我们试着用“实践”来学习理论,然后又用于实践。一个原则:把代码拷贝到 JS Bin 上,对照效果搞懂每行代码的“是什么”、“为什么”、“怎么样”?假设我们需要有个东西,然后它的排版不是依照盒模型的定义——从上往下依次排列,而是从左到右这种结构,那么我们需要考虑到使用“浮动”。
本文推荐 PC 端阅读~

本文版权归 “公众号 | 前端一万小时” 所有,未经授权,请勿转载!
复制代码
CSS——让“盒子”动起来:① 浮动
css_10
复制代码
CSS——让“盒子”动起来:① 浮动
1. 浮动元素有什么特征?对父容器、其他浮动元素、普通元素、文字分别有什么影响?
2. 清除浮动指什么?如何清除浮动?两种以上方法。
复制代码

前言:前 10 篇文章,我们基本上都是在用“理论”学习“理论”,那从这篇开始,我们试着用“实践”来学习理论,然后又用于实践。

一个原则:把代码拷贝到 JS Bin 上,对照效果搞懂每行代码的“是什么”、“为什么”、“怎么样”?

1 为什么需要“浮动”?

假设我们需要有个东西,然后它的排版不是依照盒模型的定义——从上往下依次排列,而是从左到右这种结构,那么我们需要考虑到使用“浮动”。

例如一个网站的头部,一部分在左边,一部分在右边。首先,“ 部分 ”的表示我们会用 div ,而 div 是块级元素,按理说它会从上到下,占据一整行,不可能整列排列。那这个时候我们就需要“浮动”。

2 “浮动”是怎么用的,有什么表现效果?

2.1 放不下会换行

一个“浮动盒”会向左或向右移动,直到其外边(outer edge)挨到 包含块边沿 或者另一个浮动盒的外边。如果没有足够的水平空间来浮动,它会向下移动,直到空间合适或者不会再出现其它浮动了。

:link:源码及效果展示

html

<div class="ct">
  <div class="box box1">1</div>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
</div>
复制代码

css

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
  float: left;
/*:rocket:直接在你需要浮动的元素上加 float 属性。*/

}
.box1{
  background: blue;
}
.box2{
  background: pink;
}
复制代码
CSS——让“盒子”动起来:① 浮动

:vs:对比:

:link:源码及效果展示

css

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
  float: right;
}
/*:rocket:站在浏览器的角度看,它会挨着顺序依次渲染*/

.box1{
  background: blue;
}
.box2{
  background: pink;
}
复制代码
CSS——让“盒子”动起来:① 浮动

2.2 被卡住的情况

:link:源码及效果展示

html

<body>
<div class="ct">
  <div class="box box1">1</div>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
</div>
</body>
复制代码

css

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
  float: left;
}
.box1{
  background: blue;
  height: 120px;
}
.box2{
  background: pink;
}

/*依然站在浏览器的角度,从上往下渲染文档,
当依次渲染完 1、2 后,渲染 3 的时候,右边放不下,
然后他要被挤下去,挤下去后它会和 2 的下边缘开始向左移动移动碰到 1 右下角时,动不了了,
1 被卡住了。所以我们在设置高度不一样时,会出现一个“卡住”的问题。*/
复制代码
CSS——让“盒子”动起来:① 浮动

2.3 当浮动元素与文本有交集的时候

:link:源码及效果展示

html

<body>
<div class="ct">
  <div class="box box1">1</div>
  <p>挨到包含块边沿或者另一个浮动盒的外边。
如果存在行盒,浮动盒的外 top (边)会与当前行盒的 top (边)对齐。
如果没有足够的水平空间来浮动,它会向下移动,直到空间合适或者不会再出现其他浮动了。
  </p>
  <div class="box box2">2</div>
  <div class="box box3">3</div>
</div>
</body>
复制代码

css

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
  float: left;
}
.box1 {
  background: blue;
  width: 140px;
  height: 120px;
}
.box2 {
  background: pink;
}
复制代码
CSS——让“盒子”动起来:① 浮动

:trophy:可以得到:

普通流中的一个元素,如果没有设置定位和浮动,那它和浮动元素在一起之后,它会被浮动元素所遮挡。

:bulb:进一步验证:

:link:源码及效果展示

css

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  width: 100px;
  height: 100px;
  background: red;
  float: left;
}
.box1 {
  background: blue;
  height: 120px;
  width: 140px;
  opacity: 0.2;  /*:rocket:设置透明度来观察*/
}
.box2 {
  background: pink;
}

/*:rocket:但里边的文字并没有被这个浮动元素所遮挡,那他呈现的这个效果是:
这个段落 p 是看不到这个浮动元素的,而文字看得到,并且围绕这个浮动元素排列。
*/
/*:rocket:即展现出来的一个规则就是:
当一个普通元素碰到一个浮动元素后,这个普通元素看不见这个浮动元素,
但普通元素里边的文字看得见这个浮动元素。
*/
复制代码
CSS——让“盒子”动起来:① 浮动

2.4 浮动元素脱离了普通流

脱离普通流是指:他的父容器在去计算宽高的时候,发现不了浮动元素。即,父容器不会被里面的浮动元素撑开;

:warning:注意:和 absolute 不一样。

:link:源码及效果展示

html

<div class="ct">
  <div class="box box1">1</div>
  <div class="box box2">2块盒看不见浮动的 box1,但我是文本我能看见</div>
  <div class="box box3">3</div>
</div>
复制代码

css

.ct {
  width: 280px;
  height: 300px;
  border: 1px solid;
  margin: 100px;
}
.box {
  color: #fff;
  width: 100px;
  height: 100px;
  background: red;
}
.box1 {
  background: blue;
  float: left;
  opacity: 0.6;
}
.box2 {
  background: pink;
  height: 110px;
  width: 110px;    
}
复制代码
CSS——让“盒子”动起来:① 浮动

2.5 块级元素浮动宽度收缩,行内元素浮动以块级特性去呈现

:link:源码及效果展示

html

<body>
<div class="box">这是div</div>
<span>这是span</span>
</body>
复制代码

css

.box {
  color: #fff;
  float: left;
  background: red;
}
span {
  color: #fff;
  float: left;
  background: blue;
  width: 100px;
  height: 50px;
  margin: 10px;
} 

/*:rocket:块级元素设置浮动之后,它就呈现出 inline-block 这种感觉,他的宽度会收缩。*/
/*:rocket:行内元素设置为浮动之后,它就呈现了块级的特性,
也有 inline-block 的感觉,就把行内元素变成可以设置宽高、margin 等,
但没有居中这些东西。
*/
复制代码
CSS——让“盒子”动起来:① 浮动

3 “浮动”的使用场景

3.1 两栏布局(左侧固定宽度,右侧自适应; 右侧固定宽度,左侧自适应)

:link:源码及效果展示——左侧固定宽度,右侧自适应

html

<div class="aside">侧边栏固定宽度</div>
<div class="main">内容区块自适应宽度</div>
复制代码

css

.aside {
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;
  float: left;
}
.main {
  color: #fff;
  margin-left: 160px;
/*:rocket:表示左边的这 160px 的范围我不用了*/

  background: blue;
  height: 500px;
}
复制代码
CSS——让“盒子”动起来:① 浮动

:vs:对比(右侧固定宽度,左侧自适应):

:link:源码及效果展示

html

<div class="aside">侧边栏固定宽度</div>
<div class="main">内容区块自适应宽度</div>
复制代码

css

.aside {
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;
  float: right;
}
.main {
  color: #fff;
  margin-right: 160px;
/*:rocket:表示右边的这 160px 的范围我不用了*/

  background: blue;
  height: 500px;
}
复制代码
CSS——让“盒子”动起来:① 浮动

3.2 三栏布局——两侧宽度固定,中间自适应(注意 HTML 中的 menu aside main 的顺序!)

:link:源码及效果展示

html

<div class="menu">侧边栏固定宽度</div>
<div class="aside">侧边栏固定宽度</div>
<div class="main">内容区块自适应宽度</div>
复制代码

css

.menu {
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;
  
  float: left;
}
.aside { 
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;
  
  float: right;
}
.main {
  color: #fff;
  margin-right: 160px;
  margin-left: 160px;
/*:rocket:加左右 margin 就把位置撑开了*/

  background: blue;
  height: 500px;
}
复制代码
CSS——让“盒子”动起来:① 浮动

:warning:如果 HTML 中的 menu aside main 的顺序变了:

:link:源码及效果展示

html

<div class="menu">侧边栏固定宽度</div>
<div class="main">内容区块自适应宽度</div>
<div class="aside">侧边栏固定宽度</div>

<!--顺序一旦变了,后边的 aside 就会跳行,跑到下边去了。
原因:假设我是浏览器,我需要对着 html 来画出对应的图像,
首先画 menu ,结合其样式,左浮;
但这里我们遇到了 main ,这个 main 是一个块级元素,它会占据一整行的宽度;
那接下来的 aside 就只有在 main 的基础上往右下流动。-->
复制代码

css

.menu {
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;
  float: left;
}
.aside { 
  color: #fff;
  width: 150px;
  height: 400px;
  background: red;
  float: right;
}

.main {
  color: #fff;
  margin-right: 160px;
  margin-left: 160px;
/*加左右 margin 就把位置撑开了*/

  background: blue;
  height: 500px;
}
复制代码
CSS——让“盒子”动起来:① 浮动

3.3 利用浮动实现“导航条”

3.3.1 “导航条”靠左

:link:源码及效果展示

html

<ul class="navbar">
  <li><a href="#">1首页</a></li>
  <li><a href="#">2产品</a></li>
  <li><a href="#">3服务</a></li>
  <li><a href="#">4关于</a></li>
</ul>
复制代码

css

.navbar {
  list-style: none;
}
.navbar>li {
  float: left;
  margin-left: 15px;
}

/*:rocket:当然我们用 inline-block 也可以实现效果,
但不同方式需要注意的问题不一样:
使用浮动我们需要注意撑开容器;而用 inline-block 我们需要注意它的缝隙。
*/
复制代码
CSS——让“盒子”动起来:① 浮动

3.3.2 “导航条”靠右

:link:源码及效果展示

html

<body>
<ul class="navbar">
  <li><a href="#">1首页</a></li>
  <li><a href="#">2产品</a></li>
  <li><a href="#">3服务</a></li>
  <li><a href="#">4关于</a></li>
</ul>
</body>
复制代码

css

.navbar {
  float: right;
/*:rocket:把 ul 整体进行右浮动*/

  list-style: none;
}
.navbar>li {
  float: left;
/*:rocket:但 ul 里边的东西都是靠左的*/

  margin-left: 15px;
}
复制代码
CSS——让“盒子”动起来:① 浮动

:vs:对比:

:link:源码及效果展示

html

<ul class="navbar">
  <li><a href="#">1首页</a></li>
  <li><a href="#">2产品</a></li>
  <li><a href="#">3服务</a></li>
  <li><a href="#">4关于</a></li>
</ul>
复制代码

css

.navbar {
  list-style: none;
}
.navbar>li {
  float: right;
/*:rocket:直接改这里是不行的,因为站在浏览器的立场是按文档顺序来渲染的*/

  margin-left: 15px;
}
复制代码
CSS——让“盒子”动起来:① 浮动

4 清除“浮动”

4.1 为什么要清除浮动?

因为任何东西有利有弊。

4.1.1 第一,浮动对后续元素位置产生影响(渲染时,因为块元素看不见,但里边的文字看的见)

:link:源码及效果展示

html

<div id="content">
  <div class="menu">侧边栏固定宽度</div>
  <div class="aside">侧边栏固定宽度</div>
  <div class="main">内容区块自适应宽度</div>
</div>
<div id="footer">我是 footer,但我的样式出现了问题</div>
复制代码

css

.menu {
  color: #fff;
  width: 150px;
  height: 300px;
  background: red;
  float: left;
}
.aside { 
  color: #fff;
  width: 150px;
  height: 300px;
  background: red;
  float: right;
}
.main {
  color: #fff;
  margin-right: 160px;
  margin-left: 160px;
  background: blue;
  height: 200px;
}
#footer {
  color: #fff;
  background: grey;
}
复制代码
CSS——让“盒子”动起来:① 浮动
CSS——让“盒子”动起来:① 浮动

4.1.2 第二,父容器高度计算出现问题

:link:源码及效果展示

html

<ul class="navbar">
  <li><a href="#">1首页</a></li>
  <li><a href="#">2产品</a></li>
  <li><a href="#">3服务</a></li>
  <li><a href="#">4关于</a></li>
</ul>
复制代码

css

.navbar {
  list-style: none;
  border: 1px solid #ccc;
  /*加一个背景色也没效果:
  background: pink;*/

}
.navbar>li {
  float: left;
  margin-left: 15px;
}


/*:rocket:由于浮动元素脱离了文档流,所以他的父元素是看不见他的。
这里对于 navbar 来说,他认为里边没有什么 li 来把它撑开,
因为 li 已经浮动了,那没有东西撑开它,它就会认为高度为 0。*/
复制代码
CSS——让“盒子”动起来:① 浮动

4.2 清除浮动的方法

4.2.1 清除浮动实现的原理和方法

:link:源码及效果展示

html

<ul class="navbar">
  <li><a href="#">1首页</a></li>
  <li><a href="#">2产品</a></li>
  <li><a href="#">3服务</a></li>
  <li><a href="#">4关于</a></li>
  
  <li class="clear"></li>
<!-- :rocket:想解决这个没办法撑开的问题,
那么就要求这个源文档中要有一个没有被浮动的的元素——普通元素。--> 

</ul>
复制代码

css

.navbar {
  list-style: none;
  border: 1px solid #ccc;
}
.navbar>li {
  float: left;
  margin-left: 15px;
}

.navbar .clear {
  float: none;
  clear: left;
}
/*:rocket:通过清除浮动来获得一个普通元素,进而撑开这个父容器*/
复制代码
CSS——让“盒子”动起来:① 浮动
  • 清除浮动 clear: left; ——这个 clear 可以用在任何元素上,不管你是不是浮动元素。要求该盒的 top 、border 边位于源文档(就是 html 文档结构中)中 在此之前的元素形成的所有左浮动盒的 bottom 外边下方 (如果没有左浮动盒,那你清除左浮动也就没有意义)。
  • 清除浮动  clear: right; ——要求该盒的 top border 边位于源文档中在此之前的元素形成的所有右浮动盒的 bottom 外边下方。
  • 清除浮动  clear: both; ——只要源文档中该盒前边有浮动元素,那么就在这个浮动元素下方。

1. :vs:对比

我们上边是用一个造了一个 li 来实体化普通元素,那我们可否有更简化的方法——伪元素(伪元素的一个作用就是去代替标签)。

:link:源码及效果展示

html

<ul class="navbar">
  <li><a href="#">1首页</a></li>
  <li><a href="#">2产品</a></li>
  <li><a href="#">3服务</a></li>
  <li><a href="#">4关于</a></li>
</ul>
复制代码

css

.navbar {
  list-style: none;
  border: 1px solid #ccc;
}
.navbar>li {
  float: left;
  margin-left: 15px;
}

.navbar::after {
  content: '';
/*:rocket:写了一个元素,你必须要有 content */

  display: block;
/*:rocket:注意这里如果没有这个 block ,是不会生效的,
因为写了 after ,只是表示是一个匿名的行盒,即一个字符串。
然而他必须是块级元素,他才会下去。*/

  clear: both;
}
/*:rocket:用伪元素这样写就是表示:
我在源文档 navbar 的最后生成了一个 block 元素,
然后清除浮动,他就会位于浮动盒子的下方,
进而撑开了 navbar 这个父容器。*/
复制代码
CSS——让“盒子”动起来:① 浮动

2. :vs:再对比

:link:源码及效果展示

为了通用性,我们常常 .clearfix::after; ——就是为了修复浮动所产生的问题。

html

<ul class="navbar clearfix">
<!--:rocket:凡是需要清除浮动的地方我们都可以加一个这个样式就可以通用-->

  <li><a href="#">1首页</a></li>
  <li><a href="#">2产品</a></li>
  <li><a href="#">3服务</a></li>
  <li><a href="#">4关于</a></li>
</ul>
复制代码

css

.navbar {
  list-style: none;
  border: 1px solid #ccc;
}
.navbar>li {
  float: left;
  margin-left: 15px;
}

.clearfix::after {
/*:rocket:为了通用性,我们直接 clearfix ,然后在 HTML 文档中,
哪里需要清除浮动,就直接加一个这个类名进去就可以了。*/

  content: '';
  display: block;
  clear: both;
}
复制代码

4.2.2 解决上边由“浮动”带来的问题

:link:源码及效果展示

html

<div id="content" class="clearfix">
<!--:rocket:意思就是:这三个元素下边还有一个元素,
然后这个元素会在这三个元素的下方,进而就会撑开这个 content 。-->

  <div class="menu">侧边栏固定宽度</div>
  <div class="aside">侧边栏固定宽度</div>
  <div class="main">内容区块自适应宽度</div>
</div>
<div id="footer">我是 footer,但我的样式出现了问题</div>
复制代码

css

.menu {
  color: #fff;
  width: 150px;
  height: 300px;
  background: red;
  float: left;
}
.aside { 
  color: #fff;
  width: 150px;
  height: 300px;
  background: red;
  float: right;
}
.main {
  color: #fff;
  margin-right: 160px;
  margin-left: 160px;
  background: blue;
  height: 200px;
}
#footer {
  color: #fff;
  background: grey;
}


.clearfix::after {
/*:rocket:为了通用性,我们直接 clearfix ,
然后在 HTML 文档中,哪里需要清除浮动,就直接加一个这个类名进去就可以了。*/

  content: '';
  display: block;
  clear: both;
}
复制代码
CSS——让“盒子”动起来:① 浮动

:trophy:小总结:

所以以后我们想去实现一个水平布局,就有了两种方法:

  • 第一,inline-block——不需要清除浮动,简单,在设置居中时更方便,适合子内容不多的元素水平排列。但要注意缝隙问题,以及对齐(上对齐);
  • 第二,float——没缝隙问题,适合稍大的布局。但需要解决的问题是父元素不会被撑开而导致的很多问题。

5 浮动和负 margin

两个浮动元素,如果因放不下导致其中一个下移,对下移的元素设置负 margin 值大于自身的宽度可将其上移。

:link:源码及效果展示

html

<div class="container">
  <div class="box box1">box1</div>
  <div class="box box2">box2</div>
</div>
复制代码

css

* {
  margin: 0
}
.container {
  width: 400px;
  height: 400px;
  border: 1px solid red;
}
.box1 {
  width: 300px;
  height: 100px;
  background: pink;
  float: left;
}
.box2 {
  width: 110px;
  height: 100px;
  background-color: red;
  float: left;

  margin-left: -10px;  
/*:rocket:浏览器计算的时候就相当于宽度减去这个 10 ,然后就是 100,那就正好放上去。*/ 
}
复制代码

后记:下篇我们将讨论与“浮动”对应的“定位”是怎样让“盒子”动起来的。后续文章都是重中之重,每一篇都干货满满!

加油!


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Designing Data-Intensive Applications

Designing Data-Intensive Applications

Martin Kleppmann / O'Reilly Media / 2017-4-2 / USD 44.99

Data is at the center of many challenges in system design today. Difficult issues need to be figured out, such as scalability, consistency, reliability, efficiency, and maintainability. In addition, w......一起来看看 《Designing Data-Intensive Applications》 这本书的介绍吧!

SHA 加密
SHA 加密

SHA 加密工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具