Go to comments

HTML+CSS宝典 CSS基础 浮动

视觉格式化模型大体将页面中的盒子排列分为三种方式

1. 常规流

2. 浮动

3. 定位


上一篇已经学习了常规流,常规流里面里面分为行盒和块盒

块盒:横向撑满包含块,然后纵向上,有外边距的合并

行盒:下一个行盒的头部接上,上一个行盒的尾巴


下面学习另外一种排序浮动,浮动在页面中也是经常遇到的一种排列方式,首先看一下浮动的应用场景


一、浮动应用场景

第一种,文字环绕


网页上有一张图片,图片周围有一些文字,

通常是图片靠左边,然后右边文字把图片环绕起来,

还有一种是图片在右边,然后文字把图片环绕起来。


当初官方的标准中,浮动解决的也是文字环绕的问题,

但是后来浮点解决了更多的问题,大家用浮动做出更加丰富的效果,不仅仅只限于文字环绕。


第二种,横向排列


就是把一些盒子,横向排列起来,这也是一种常见的应用场景。


横向排列可以使用行块盒,也可以使用浮动,行块盒除了有空白折叠的问题,

其实行块盒还有一些问题在进阶阶段的课程再学习,这跟行盒的参考线有关,行盒其实是非常复杂的,在基础部分不学那么的复杂,在进阶部分在详细的学习。


行块盒本身排列的方式是行盒的排列方式,所以会带来一些问题,

因此更多的时候横向排列一般都是使用浮动,如果学习了 css3 还会有更丰富的横向排列方式,比如弹性盒模型、网格布局等等


css2 里面横向排列一般都使用浮动,而且浮动也是兼容性最好的一种方案,IE6, IE5 这些低版本浏览器都可以实现浮动,所以浮动是非常重要的知识点。


二、浮动的基本特点

一个元素生成的盒子,默认肯定是不会浮点的,要变成浮动需要修改css的 float 属性的值


修改 float 属性的值为 left 或 right 都可以

float: left    左浮动,元素靠上、靠左排列,在整个包含块里面靠上、靠左排列(包含块是父元素的内容盒)

float: right  右浮点,元素面靠上、靠右排列,在包含块里……


Ps:

靠上两个字应该写在前面,因为优先级是先靠上,再靠左 或 再靠右


float: none

浮动的默认值为 none,就是不浮动,不浮动就是常规流


1、元素浮动后必定为块盒

当一个元素浮动后( 浮动后的意思是,设置为左浮点或右浮点 ),元素必定为块盒 ( 会更改 display 属性为 block 块盒 )。


看一个例子,span 元素默认是行盒,设置为浮动 float: left

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>span元素浮动</title>
<style>
  span{
    border:3px solid;
    float: left;
  }
</style>
</head>
<body>

<span>span元素</span>

</body>
</html>

计算出来的值变成了 block,也就是说浮动会改变盒子的类型,如果盒子不是块盒一定会强制变成块盒

image.png


浮动的元素一定是块盒

1. 浮动里面不存在行盒,全部都是块盒

2. 所以说 span 元素浮动起来,跟 div 元素浮动起来效果是一样的

3. 浮动这种排列方式下,不用去考虑行盒,行盒只有在常规流。包括后面学到的定位,定位过的元素一定也是块盒


2、浮动元素的包含块为父元素的内容盒(和常规流一样)

浮动元素常规流一样,也是在父元素的内容盒里面,浮动元素坐标系按照父元素的内容盒参考,靠上靠左排列/靠上靠右排列,也是参考父元素的内容盒。


看下面这个例子,

父元素 .container 没有 boder 也没有 padding,蓝色的背景区域就是子元素的内容盒,两个 div 子元素分别左浮动,右浮动

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>浮动</title>
<style>
    .container{
      width:300px;height:300px;background-color:lightblue;
    }
    .container div{
      height:60px;width:60px;background-color:red;
    }
    .container .left{
      float:left;
    }
    .container .right{
      float:right;
    }
</style>
</head>
<body>

  <div class="container">
    <div class="left"></div>
    <div class="right"></div>
  </div>

</body>
</html>

两个 div 子元素,一个靠上靠左,一个靠上靠右,在父元素的内容盒里面活动跟常规流里面是一样的

   


这是关于浮动最基本的特点,浮动的特点很多,下面的特点是浮动盒子的尺寸


三、浮动时盒子的尺寸

浮动盒子的尺寸跟常规流是有区别的


1、宽度为 auto 时适应内容宽度

常规流:常规流盒子宽度为 auto 的时候,宽度吸收剩余空间,撑满包含块的宽度

浮动:浮动时并没有要求撑满,所以当宽度为 auto 的时候,表示适应内容的宽度


看下面的例子,left元素、right元素都是浮动元素,不设置这两个子元素的宽度,他们的宽度是多少?

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>浮动元素的宽度</title>
<style>
  .container{
    width: 300px;
    height: 300px;
    background-color: lightblue;
  }
  .container div{
    height: 60px;
    /* width: 60px; */
    background-color: red;
  }
  .container .left{
    float:left;
  }
  .container .right{
    float:right;
  }
</style>
</head>
<body>

  <div class="container">
    <div class="left"></div>
    <div class="right"></div>
  </div>

</body>
</html>

看不见 left、right 两个元素

   


因为浮动的盒子里面没有内容,没法适应内容的宽度,所以 left 元素的边框盒宽度是0,right 元素边框盒也是0

image.png


浮动盒子的特点,浮动盒子没有要求一定要撑满包含块,宽度为auto 的时候是适应内容的宽度,不是吸收剩余空间。


如果给浮动元素里面加些文本,宽度是自适应的

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>浮动元素的宽度</title>
<style>
  .container{
    width: 300px;
    height: 300px;
    background-color: lightblue;
  }
  .container div{
    height: 60px;
    /* width: 60px; */
    background-color: red;
  }
  .container .left{
    float:left;
  }
  .container .right{
    float:right;
  }
</style>
</head>
<body>

  <div class="container">
    <div class="left">文字文字文字</div>
    <div class="right">文字</div>
  </div>

</body>
</html>

宽度是自适应的

文字文字文字    文字


这是浮动盒子宽度值为 auto 的时候,和常规流盒子不一样的地方,

下面学的是浮动盒子高度值为 auto 的时候,这个时候与常规流是一样的。


2、高度为 auto 时候,与常规流一样,适应内容的高度

常规流:常规流高度为 auto 的时候,盒子高度适应内容的高度

浮动:高度值为 auto 无论在什么排列方式下,含义都是一样的,适应内容的高度


看下面例子,把两个浮动子元素的高度注释掉,只留盒子里面的文本

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>浮动元素的高度</title>
<style>
  .container{
    width: 300px;
    height: 300px;
    background-color: lightblue;
  }
  .container div{
    /* height: 60px; 注释浮动元素的高度 */
    /* width: 60px; */
    background-color: red;
  }
  .container .left{
    float:left;
  }
  .container .right{
    float:right;
  }
</style>
</head>
<body>

  <div class="container">
    <div class="left">文字文字文字</div>
    <div class="right">文字</div>
  </div>

</body>
</html>

显示的效果是,适应内容的高度了

文字文字文字    文字


border、padding 跟常规流是一样,设置多少就是多少,没什么好说的,

下面是尺寸的下一个特点 margin 属性。


3、margin 值是 auto 表示的是 0

在常规流中:

左右的 margin 设置为 auto 的时候,是吸收剩余空间,只不过吸收能力没有 width 宽度那么强,

也就是说常规流水平方向上,如果宽度为 auto,margin 也为 auto,宽度会把剩余空间吸收完,margin 什么都没有。


浮动:

margin 为 auto时,在浮动的情况下,无论什么方向(四个方向),表示的是0,没有剩余空间这一说。


看下面例子,给两个浮动的 div 元素的 margin 值设置为 auto

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>浮动元素设置margin</title>
<style>
  .container{
    width: 300px;
    height: 300px;
    background-color: lightblue;
  }
  .container div{
    background-color: red;
    margin: auto; /* 设置margin的值为auto */           
  }
  .container .left{
    float:left;
  }
  .container .right{
    float:right;
  }
</style>
</head>
<body>

  <div class="container">
    <div class="left">文字文字文字</div>
    <div class="right">文字</div>
  </div>

</body>
</html>

页面上没有任何变化

文字文字文字  文字


选中 div 元素,页面显示上看不到黄色区域(黄色区域就是 margin)

image.png


查看盒模型,也没有 margin

image.png

所以说 margin 属性在浮动下,auto 值就变成了 0


如果给 margin 设置固定的值,margin 当然会生效了

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>浮动元素设置margin</title>
<style>
  .container{
    width: 300px;
    height: 300px;
    background-color: lightblue;
  }
  .container div{
    background-color: red;
    margin: auto; /* 设置margin的值为auto */           
  }
  .container .left{
    float:left;
    margin: 30px; /* 设置margin的值为固定值*/  
  }
  .container .right{
    float:right;
  }
</style>
</head>
<body>

  <div class="container">
    <div class="left">文字文字文字</div>
    <div class="right">文字</div>
  </div>

</body>
</html>

.left 元素设置的 30 像素的 margin 值生效了

文字文字文字    文字


4、边框、内边距、百分比的设置与常规流是一样的

1. 除了高度 height 的百分比之外

2. 其它的百分比设置(padding、margin-top…)是相对的是包含块的宽度,就是父元素内容的宽度(高度的百分比的知识,看上一篇)


5、总结

浮动时候盒子的尺寸

1. 宽度、高度、margin这些固定尺寸,没什么好说的(按照尺寸)

2. 宽度、高度都为 auto 的时候,都表示适应内容

3. margin 为 auto的时候直接是 0

浮动盒子尺寸是非常简单的,主要是浮动时盒子的位置(盒子的排列)


四、浮动时盒子的排列

盒子排列的规则比较多,其实也很简单


1、总体规则

最基本的排列方式

1. 左浮动的盒子,靠上靠左排列

2. 右浮动的盒子,靠上靠右排列


看例子,有很多个子元素 .item 盒子全部左浮动排列齐了

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>左浮动的盒子</title>
<style>
  .container{
    width: 500px;
    height: 200px;
    background-color: lightblue;
  }
  .item{
    float: left; /* 左浮动 */
    width: 50px;
    height: 50px;
    border: 1px solid;
    background-color: red;
    color: #fff;
  }
</style>
</head>
<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
    <div class="item">11</div>
    <div class="item">12</div>
    <div class="item">13</div>
    <div class="item">14</div>
    <div class="item">15</div>
    <div class="item">16</div>
    <div class="item">17</div>
    <div class="item">18</div>
    <div class="item">19</div>
    <div class="item">20</div>
  </div>
</body>
</html>

一个一个挨着,靠上靠左排列

image.png


变成右浮动,靠上靠右排列

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>右浮动</title>
<style>
  .container{
    width: 500px;
    height: 200px;
    background-color: lightblue;
  }
  .item{
    float: right; /* 左浮动 */
    width: 50px;
    height: 50px;
    border: 1px solid;
    background-color: red;
    color: #fff;
  }
</style>
</head>
<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
    <div class="item">11</div>
    <div class="item">12</div>
    <div class="item">13</div>
    <div class="item">14</div>
    <div class="item">15</div>
    <div class="item">16</div>
    <div class="item">17</div>
    <div class="item">18</div>
    <div class="item">19</div>
    <div class="item">20</div>
  </div>
</body>
</html>

靠上靠右排列

image.png


浮动盒子在网页中做并排排列呢?就是因为依次排列的这个特点


2、常规流盒子和浮动盒子混排的情况

3. 浮动盒子 在 包含块中排列时,会避开常规流块盒 


前面有常规流盒子,浮动的盒子会避开前面的常规流盒子

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>浮动盒子会避开前面的常规流盒子</title>
<style>
  .container{
    width: 500px;
    height: 200px;
    background-color: lightblue;
  }
  .item{
    float: left; /* 浮动 */
    width: 50px;
    height: 50px;
    border: 1px solid;
    background-color: red;
    color: #fff;
  }
  .mormal{
    height: 30px;
    background-color: #008c8c;
  }
</style>
</head>
<body>
  <div class="container">
    <div class="mormal">常规流盒子</div>
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
    <div class="item">11</div>
    <div class="item">12</div>
    <div class="item">13</div>
    <div class="item">14</div>
    <div class="item">15</div>
    <div class="item">16</div>
    <div class="item">17</div>
    <div class="item">18</div>
    <div class="item">19</div>
    <div class="item">20</div>
  </div>
</body>
</html>

下面的浮动的盒子,会避开上面的常规流盒子

image.png

这是浮动盒子 和 常规流盒子混排的情况下,常规流盒子在前面的情况下,后边的浮动盒子要避开常规流


但是返过来情况就不同了,

如果把常规流块盒子(这里都说的是块盒)排在浮动盒子后面,浮动的盒子覆盖掉后面的常规流盒子。


4. 常规流块盒 在 排列时候,完全看不见浮动盒子 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>浮动的盒子覆盖掉后面的常规流盒子</title>
<style>
  .container{
    width: 500px;
    height: 200px;
    background-color: lightblue;
  }
  .item{
    float: left;
    width: 50px;
    height: 50px;
    border: 1px solid;
    background-color: red;
    color: #fff;
  }
  .mormal{
    height: 30px;
    background-color: #008c8c;
  }
</style>
</head>
<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
    <div class="item">11</div>
    <div class="item">12</div>
    <div class="item">13</div>
    <div class="item">14</div>
    <div class="item">15</div>
    <div class="item">16</div>
    <div class="item">17</div>
    <div class="item">18</div>
    <div class="item">19</div>
    <div class="item">20</div>
    <div class="mormal">常规流盒子</div>
  </div>
</body>
</html>

浮动盒子漂在上面,覆盖常规流块盒子

image.png


 background-color:red   把浮动盒子背景颜色去掉,就看到被覆盖的常规流盒子了

image.png


这里说一点:

实际上常规流盒子 和 浮动盒子 混排的时候规则有点复杂的,

而且浮动盒子本身的排列规则细节也比较多,只不过平时开发的时候用不到那么多复杂的情况,

如果要知道完整的排列规则,后面袁老师的扩展课会详细的讲。


上面四点是盒子排列,下面是文字环绕


四、文字环绕

5. 行盒在排列的时,会避开浮动的盒子。


做一个文字环绕的效果

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  .container{
    width: 600px;
  }
  img{
    width: 120px;
  }
  p{
    color: #008c8c;
  }
</style>
<title>文字环绕</title>
</head>
<body>

<div class="container">
  <img src="http://ruyic.com/blog/uploads/image/201904/155591911913470.png" alt="">
  <p>
    Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ratione officia similique explicabo nulla tenetur eligendi voluptas corrupti mollitia ea impedit ipsa facilis repudiandae harum in quidem delectus architecto ipsum autem aliquid totam ullam beatae illum, molestiae aspernatur. Minima ad, maxime error esse suscipit, quis delectus id hic, tempora ducimus vel voluptate! Error corrupti est asperiores? Placeat eveniet fuga dignissimos blanditiis dolorum qui, rem repellat neque eligendi! Temporibus unde voluptatem quidem, commodi minus sint quae qui sequi illum pariatur, vero eligendi? Optio blanditiis inventore impedit magni cupiditate saepe ex nesciunt eum iusto eos, vero dolor nostrum velit repudiandae est. Provident ipsam ab eum aliquam! In, maxime, minima neque quod accusamus earum quisquam suscipit odit autem ullam perspiciatis sit exercitationem dicta illum!
  </p>
</div>
 
</body>
</html>

图片虽然是行盒,但是 p 元素是块盒要独占一行,所以是下面这样的排列


Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ratione officia similique explicabo nulla tenetur eligendi voluptas corrupti mollitia ea impedit ipsa facilis repudiandae harum in quidem delectus architecto ipsum autem aliquid totam ullam beatae illum, molestiae aspernatur. Minima ad, maxime error esse suscipit, quis delectus id hic, tempora ducimus vel voluptate! Error corrupti est asperiores? Placeat eveniet fuga dignissimos blanditiis dolorum qui, rem repellat neque eligendi! Temporibus unde voluptatem quidem, commodi minus sint quae qui sequi illum pariatur, vero eligendi? Optio blanditiis inventore impedit magni cupiditate saepe ex nesciunt eum iusto eos, vero dolor nostrum velit repudiandae est. Provident ipsam ab eum aliquam! In, maxime, minima neque quod accusamus earum quisquam suscipit odit autem ullam perspiciatis sit exercitationem dicta illum!


文字环绕图片的效果怎么做呢?

1. 把 p 元素变成行盒  display: inline 


Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ratione officia similique explicabo nulla tenetur eligendi voluptas corrupti mollitia ea impedit ipsa facilis repudiandae harum in quidem delectus architecto ipsum autem aliquid totam ullam beatae illum, molestiae aspernatur. Minima ad, maxime error esse suscipit, quis delectus id hic, tempora ducimus vel voluptate! Error corrupti est asperiores? Placeat eveniet fuga dignissimos blanditiis dolorum qui, rem repellat neque eligendi! Temporibus unde voluptatem quidem, commodi minus sint quae qui sequi illum pariatur, vero eligendi? Optio blanditiis inventore impedit magni cupiditate saepe ex nesciunt eum iusto eos, vero dolor nostrum velit repudiandae est. Provident ipsam ab eum aliquam! In, maxime, minima neque quod accusamus earum quisquam suscipit odit autem ullam perspiciatis sit exercitationem dicta illum!


2. p元素变成行盒之后,p元素的第一行跟图片作为一行,这样的排列方式仍然不是我们想要


3. 这时候非常简单,只需要给图片 img 加一个  float: left  就可以了

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
  .container{
    width: 600px;
  }
  img{
    width: 120px;
    float: left; /* 图片加浮动 */
  }
  p{
    color: #008c8c;
    /* display: inline; 这个有点记不清楚是否需要加了 */
  }
</style>
<title>实现文字环绕</title>
</head>
<body>

<div class="container">
  <img src="http://ruyic.com/blog/uploads/image/201904/155591911913470.png" alt="">
  <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ratione officia similique explicabo nulla tenetur eligendi voluptas corrupti mollitia ea impedit ipsa facilis repudiandae harum in quidem delectus architecto ipsum autem aliquid totam ullam beatae illum, molestiae aspernatur. Minima ad, maxime error esse suscipit, quis delectus id hic, tempora ducimus vel voluptate! Error corrupti est asperiores? Placeat eveniet fuga dignissimos blanditiis dolorum qui, rem repellat neque eligendi! Temporibus unde voluptatem quidem, commodi minus sint quae qui sequi illum pariatur, vero eligendi? Optio blanditiis inventore impedit magni cupiditate saepe ex nesciunt eum iusto eos, vero dolor nostrum velit repudiandae est. Provident ipsam ab eum aliquam! In, maxime, minima neque quod accusamus earum quisquam suscipit odit autem ullam perspiciatis sit exercitationem dicta illum!</p>
</div>
 
</body>
</html>

文字环绕图片效果


Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ratione officia similique explicabo nulla tenetur eligendi voluptas corrupti mollitia ea impedit ipsa facilis repudiandae harum in quidem delectus architecto ipsum autem aliquid totam ullam beatae illum, molestiae aspernatur. Minima ad, maxime error esse suscipit, quis delectus id hic, tempora ducimus vel voluptate! Error corrupti est asperiores? Placeat eveniet fuga dignissimos blanditiis dolorum qui, rem repellat neque eligendi! Temporibus unde voluptatem quidem, commodi minus sint quae qui sequi illum pariatur, vero eligendi? Optio blanditiis inventore impedit magni cupiditate saepe ex nesciunt eum iusto eos, vero dolor nostrum velit repudiandae est. Provident ipsam ab eum aliquam! In, maxime, minima neque quod accusamus earum quisquam suscipit odit autem ullam perspiciatis sit exercitationem dicta illum!


环绕效果是怎么回事?这里涉及到一些知识点


好好解释一下:

1. 首先 p 元素是块盒,浏览器默认样式表里是  display: block 

image.png

因为 p 元素是块盒,所以 p 元素在排列的时候,完全无视前面的 img 元素这个浮动盒子,


所以,选中p元素,看p元素选中的阴影部分占据了整个空间,只不过图片把左上那块遮住了,整个红色画出的是p元素的区域,先把这些理解

image.png


2. 然后接下来解释的是,p 元素的文字是怎么回事,

按理说文字应该从整块 p 元素的区域(红色的区域)开始排列,为什么文字避开了浮动的图片元素?


这是因为在浮动元素里面有一个规则:行盒在排列时,会避开浮动盒子。


这就奇怪了,这里的 p 元素不是行盒,他为什么会避开浮动盒子呢?

有这样一条规则,我们要注意一下,如果文字没有在行盒中,浏览器会自动生成一个行盒包裹文字,该行盒叫做匿名行盒。


意思如果文字是在块盒里面的,浏览器会直接生成一个行盒来包裹文字,

可以想象成下面这样,p 元素里面出现一个 span 元素把文字包裹起来了,这是浏览器自动处理的。

<p>

    <span>

        Lorem, ipsum dolor sit amet consectetur adipisicing elit. Dolore suscipit 

    </span>

</p>


这样就表示文字永远只在行盒里面,所以之前学习行盒的时候说,行盒就可以把它看做是内容。

文字就是内容,所以文字一定在行盒里面,哪怕把文字放到块盒里面,浏览器也会生成一个行盒来包裹文字,当然生成的行盒是看不见的,该行盒他叫做匿名行盒。


如果把文字直接包裹在行盒里面,就不会生成匿名行盒了,如果没有包裹在行盒里面会生成匿名行盒来包裹文字,

所以我们看到的p元素里面的文字依然是行盒,行盒排列的时候避开了浮动元素

但是被图片 img 元素覆盖那一块 p 元素的空间是存在的,只是里面的行盒文字避开了图片,于是做出了一个文字环绕效果。


文字环绕效果非常简单,只需要把图片浮动起来,

如果想让图片出现在右边就用右浮动  float: right 


Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ratione officia similique explicabo nulla tenetur eligendi voluptas corrupti mollitia ea impedit ipsa facilis repudiandae harum in quidem delectus architecto ipsum autem aliquid totam ullam beatae illum, molestiae aspernatur. Minima ad, maxime error esse suscipit, quis delectus id hic, tempora ducimus vel voluptate! Error corrupti est asperiores? Placeat eveniet fuga dignissimos blanditiis dolorum qui, rem repellat neque eligendi! Temporibus unde voluptatem quidem, commodi minus sint quae qui sequi illum pariatur, vero eligendi? Optio blanditiis inventore impedit magni cupiditate saepe ex nesciunt eum iusto eos, vero dolor nostrum velit repudiandae est. Provident ipsam ab eum aliquam! In, maxime, minima neque quod accusamus earum quisquam suscipit odit autem ullam perspiciatis sit exercitationem dicta illum!


然后还有一个小细节,

图片和文字之间挨着有点近,能不能离远一点呢?


离远一点应该设置,

图片的 margin-right ?

还是设置p元素的 margin-left ?


如果设置p元素的  margin-left: 50px  ,下面的效果是从边缘生效的,因为 p 元素是无视浮动元素的,所以设置的是 p 元素的 margin-left,是距包含块左边的距离


image.png


所以这里应该设置图片的

 margin-right: 20px; 

 margin-bottom: 20px; 


Lorem ipsum, dolor sit amet consectetur adipisicing elit. Ratione officia similique explicabo nulla tenetur eligendi voluptas corrupti mollitia ea impedit ipsa facilis repudiandae harum in quidem delectus architecto ipsum autem aliquid totam ullam beatae illum, molestiae aspernatur. Minima ad, maxime error esse suscipit, quis delectus id hic, tempora ducimus vel voluptate! Error corrupti est asperiores? Placeat eveniet fuga dignissimos blanditiis dolorum qui, rem repellat neque eligendi! Temporibus unde voluptatem quidem, commodi minus sint quae qui sequi illum pariatur, vero eligendi? Optio blanditiis inventore impedit magni cupiditate saepe ex nesciunt eum iusto eos, vero dolor nostrum velit repudiandae est. Provident ipsam ab eum aliquam! In, maxime, minima neque quod accusamus earum quisquam suscipit odit autem ullam perspiciatis sit exercitationem dicta illum!


4、不会合并外边距

5. 外边距合并不会发生

在浮动盒子里面不会发生外边距合并,只有在常规流里面才会发生外边距合并,

脱离的常规流,不管是浮动还是后面学的定位,都不会发生外边距合并。


五、高度坍塌

文字环绕、横向排列这两个是浮动最核心的应用场景,学完这两个之后看一个问题,

浮动盒子在开发网页中有一个非常常见的问题叫高度坍塌,


我们要学会高度坍塌是怎样造成的,并且还要学会如何来解决高度坍塌,因为在使用浮动布局的时候,

第一是个高度坍塌非常常见,

第二是高度坍塌很多时候是造成网页布局混乱的根源。


看一个例子,.container 表示一个容器

1. 没有高度,高度自动,

2. 设置  padding: 30px  的内边距

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>高度坍塌</title>
<style>
  .container{
    background-color: lightblue;
    padding: 30px;
  }
</style>
</head>
<body>

  <div class="container">

  </div>

</body>
</html>

页面效果如下


上下有 30 像素的内边距,高度是0,能看到背景

image.png


在容器 .container 里面,加上10个浮动元素

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>高度坍塌</title>
<style>
  .container{
    background-color: lightblue;
    padding: 30px;
  }
  .item{
    float: left;
    width: 50px;
    height: 50px;
    margin: 6px;
    background-color: red;
    color: #fff;
  }
</style>
</head>
<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
  </div>
</body>
</html>

为什么浮动盒子跑到容器外面去了?

image.png


再看一下容器 .container 元素的高度仍然是 0,这种现象就叫做高度坍塌

image.png


高度坍塌的根源:常规流盒子的自动高度,在计算时,不会考虑浮动盒子。

意思是常规流盒子高度是自动适应内容,他在计算高度时候,不会考虑浮动的盒子,他只考虑常规流的盒子。


也就是说外面的 .container 这个容器怎么样才能被撑高呢?

只有容器里面是常规流盒子,高度才会撑起来


比如在容器里面加一个常规流的盒子

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>高度坍塌</title>
<style>
  .container{
    background-color: lightblue;
    padding: 30px;
  }
  .item{
    float: left;
    width: 50px;
    height: 50px;
    margin: 6px;
    background-color: red;
    color: #fff;
  }
</style>
</head>
<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
    <div style="height:30px;background-color:#008c8c;">常规流盒子</div>
  </div>
</body>
</html>

现在的效果是

1. 容器里面的常规流盒子排列的时候,完全无视浮动盒子

2. 外面容器的高度有所增加,增加的原因是,因为里面有了常规流的盒子,跟浮动盒子没有关系

image.png


这是关于为什么会造成高度坍塌,面试的时候这样回答:

浮动盒子脱离了常规流,因此常规流盒子在高度计算的时候不会考虑浮动盒子,

当然这是指自动高度,如果手动设置高度那就不一样了。


怎么来解决这个问题呢?

解决的方式是清除浮动,清楚浮动涉及到一个 css 属性 clear


clear 属性有这样几个属性值

none  默认值none,就是不清除

left     清除左浮动,该元素必须出现在,前面所有左浮动盒子的下方

right   清除右浮动,该元素必须出现在,前面所有右浮动盒子的下方

both   清除左右浮动,该元素必须出现在,前面所有浮动盒子的下方


清除浮动的意思不是说不浮动了,

清除浮动的意思是应用了  clear: left  的元素,该元素必须出现在前面所有左浮动盒子的下面。


看例子,在容器最后加一个div元素,给这个 div 加一个类样式 .clearfix 表示处理高度坍塌

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>清除浮动</title>
<style>
  .container{
    background-color: lightblue;
    padding: 30px;
  }
  .item{
    float: left;
    width: 50px;
    height: 50px;
    margin: 6px;
    background-color: red;
    color: #fff;
  }
  .clearfix{
    height:60px;
    background-color: blue;
    clear: both; /* 清除浮动 */
  }
</style>
</head>
<body>
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
    <div class="clearfix"></div>
  </div>
</body>
</html>

这个 .clearfix 元素出现在容器最后,就解决了高度坍塌的问题,因为这个 div 撑开了容器的高度,不是因为浮动元素撑开的

image.png

这种方式要写一个空元素,没有什么意义,通常不会太用这种方式


所以还有一种方式原理是一样的,也是最常用(最主流)的清楚浮动的方法

1. 用伪元素选择器在容器最后面添加了一个伪元素 .clearfix::after 

2. 首先伪元素里面内容为空  content: "" 

2. 然后伪元素默认是行盒,把他变成块盒 display: block 

3. 再在伪元素里清除浮动  clear: both 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>清除浮动</title>
<style>
  .container{
    background-color: lightblue;
    padding: 30px;
  }
  .item{
    float: left;
    width: 50px;
    height: 50px;
    margin: 6px;
    background-color: red;
    color: #fff;
  }
  .clearfix::after{ /* 伪元素选择器给容器,最后面添加了一个元素 */
    content:"";
    display: block; /* 伪元素默认是行盒,设置成块盒 */
    clear: both;
  }
</style>
</head>
<body>
  <div class="container clearfix">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
  </div>
</body>
</html>

让这个伪元素出现在所有浮动元素下面,从而撑开外面的 div 父元素,相当于人为的加了一个子元素

image.png


6. 在浮动盒子里面,不会发生外边距合并

只有在常规流里面,才会发生外边距合并,脱离了常规流,浮动和定位都不会发生外边距合并


六、浮动练习

movie.html


movie.css


common.css


reset.css




Leave a comment 0 Comments.

Leave a Reply

换一张