CSS浮动全面解析+应用

685 阅读7分钟

在解析浮动之前,有必要先说一下常规流,所谓的常规流,通俗来说就是正常排列的元素,常规流元素的排列当然也有一些规则,具体规则说明如下。

1. 常规流

1.1. 视觉格式化模型(布局规则)将页面中的盒子排列方式分为三种:

1、常规流
2、浮动
3、定位

1.2. 常规流

所有元素,默认情况下,都属于常规流布局
总体规则:块盒独占一行,行盒水平依次排列

1.3. 包含块(containing block)

每个盒子都有它的包含块,包含块决定了盒子的排列。
绝大部分情况下,盒子的包含块,为其父元素的内容盒。

1.4. 水平方向的width和margin

width默认为auto,auto的含义:自动吸收剩余宽度。
每个块盒的总宽度(内容+内边距+边框+外边距),必须等于其包含块内容盒的宽度
child的width(默认指content的宽度) = parent的内容盒-(child的边框+内边距+外边距)
margin默认值为0,改成auto的话,水平方向同样会吸收剩余空间
widthmargin同时为auto的时候,width的吸收能力更强。
若child的宽度、内边距、边框,外边距加起来还小于parent的内容盒宽度的话,剩余空间被margin-right吸收
在常规流中块盒居中解决方案:定宽,左右margin设置为auto。
  上面方案原理:左右margin拥有相同的吸收能力,在宽度固定的情况下,左右margin各自分配一半的剩余空间

1.5. 垂直方向的height和margin

高度为auto指的是高度随内容撑开
垂直方向的margin设置为auto表示垂直方向的margin0

1.6.关于百分比取值

child的宽度、内边距,外边距的百分比取值都是相对于包含块parent的宽度。
parent高度为auto的时候(会被child自动撑开),child设置高度为百分比无效
parent高度设置了固定高度的情况下,child的高度的百分比是相对于包含块parent的高度。
  .parent {
    width: 300px;
    height: 200px;
    padding: 10px;
    background-color: wheat;
    border: 10px solid red;
    background-clip: content-box;
    margin: 0 auto;
  }

  .child {
    height: 10%;
    padding: 10px;
    background-color: blue;
    border: 10px solid red;
    background-clip: content-box;

    /* width: 100px;
    margin-left: auto;
    margin-right: auto; */

    /* width: auto;
    margin-left: -60px;
    margin-right: -60px; */

    width: 50%;
    /* box-sizing: border-box; */
  }
  <div class="parent">
    <div class="child"></div>
  </div>

1.7. 相邻盒子的外边距合并

1、兄弟元素外边距合并
  常规流中的两个块盒上下外边距相邻会进行合并,最终取较大的外边距的值作为两者之间的距离。
```css body{ margin: 0; padding: 0; } .box1{ height: 100px; background-color: pink; } .box2{ height: 100px; background-color: wheat; margin-top: 30px; margin-bottom: 50px; } .box3{ height: 100px; background-color: magenta; margin-top: 60px; } ```
  <div class="box1"></div>
  <div class="box2"></div>
  <div class="box3"></div>
2、父子元素的外边距合并
  常规流中的两个父子元素外边距相邻,也会进行合并,同样取最大的作为共同的外边距。
    body{
      margin: 0;
    }
    .parent{
      height: 150px;
      background-color: purple;
      margin-top: 100px;
      /* border: 3px solid orange; */
      /* padding-top: 1px; */
      padding-top: 50px;
    }
    .child{
      height: 50px;
      background-color: magenta;
    }
  <div class="parent">
    <div class="child"></div>
  </div>
  想达到不合并的效果可以通过给父元素加边框或内边距来隔开两个元素,就不合并了。


2. 浮动

浮动是兼容性最好的水平排列的方案。

2.1 浮动的基本特点

1、通过float属性使元素变为浮动,float默认为none,即为常规流。
2、元素浮动后,必定为块盒(一定位,也是块盒)
  因为会自动更改元素的display属性值为block
3、浮动元素的包含块,同样为其父元素的内容盒,即使父元素在不浮动的情况下高度为0
  .box1{
    margin-left: 100px;
    border: 3px solid blue;
  }
  span{
    border: 3px solid red;
    float: left;
  }
 <div class="box1">
   <span>Lorem ipsum dolor sit amet consectetur adipisicing elit. Porro cumque aut, modi similique totam possimus facere vel laboriosam ipsum. Sint distinctio veritatis dolores dolore totam? Voluptatum delectus ullam quod quas!
   </span>
 </div>

2.2 浮动元素的宽度

  宽度为auto的情况下,宽度会自动适应文本内容宽度(常规流下会吸收所有的剩余空间)
    关于这点也是符合常理的,比如你设置一个盒子左浮动,如果宽度又撑满整个父盒子的话,
    那怎么让此盒子居左呢,因为这时始终是撑满外部盒子的状态了。
  .box2{
    width: 300px;
    height: 300px;
    background-color: wheat;
  }
  .item1{
    height: 100px;
    background-color: magenta;
    float: left;
    opacity: 0.6;
    border: 3px dashed maroon;
  }
  .item2{
    height: 100px;
    background: radial-gradient(at left top, red, red 50%, blue 50%, blue);
  }
  <div class="box2">
    <div class="item1">
      Lorem ipsum dolor
    </div>
    <div class="item2"></div>
  </div>

2.3 浮动元素的高度

  高度为auto的情况下,适应内容的高度,高度在各种情况下基本都是适应内容的高度

2.4 浮动元素的外边距

  浮动元素外边距设置为auto的情况下,为0。常规流下元素外边距的auto为自动吸收剩余空间
  如果是实际值的话,当然会生效
  .box4{
    width: 200px;
    height: 200px;
    background-color: wheat;
  }
  .item1{
    width: 100px;
    height: 100px;
    background-color: red;
    margin: 0 auto;
    float: left;
  }
  <div class="box4">
    <div class="item1"></div>
  </div>

2.5 百分比值

  宽度、内边距、外边距都是相当于包含块的宽度,边框不能取值百分比值

2.6 排列规则

  1left:元素靠上靠左排列
  2right:元素靠上靠右排列
  .box{
    width: 300px;
    height: 200px;
    background: wheat;
    color: #fff;
  }
  .item{
    width: 50px;
    height: 50px;
    margin: 2px;
    /* background: red; */
    float: left;
    opacity: 0.9;
    border: 2px solid brown;
  }
  .normal{
    background-color: magenta;
    color: blue;
    height: 50px;
  }
  <div class="box">
    <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="normal"></div>
  </div>
  3、浮动盒子在包含块中排列时,会避开常规流盒子
即使将常规流长度固定,依然会占据一整行的空间
    块盒浮动起来后,就不再独占一行,但依然是一个矩形块,不超过一行的话,别的盒子可以排列在后面,超过一行的话,因为要保持矩形,后面肯定不能再紧跟着盒子了。详情情况下下面五幅图。






  4、常规流盒子在排列时,会无视浮动盒子。常规流盒子和浮动盒子混排的时候,情况比较复杂,而且浮动盒子本身的细节也比较多。
  .box{
    width: 300px;
    height: 200px;
    background: wheat;
    color: #fff;
  }
  .item{
    width: 50px;
    height: 50px;
    margin: 2px;
    /* background: red; */
    float: left;
    opacity: 0.9;
    border: 2px solid brown;
  }
  .normal{
    background-color: magenta;
    color: blue;
    height: 50px;
  }
  <div class="box">
    <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="normal"></div>
  </div>
  5、行盒在排列时,会避开浮动盒子
    如果文字没有在行盒中,浏览器会自动生成一个行盒(匿名行盒)包裹文字,也就意味着,文字永远只能在行盒里面
  .box1{
    height: 50px;
    width: 50px;
    /* background-color: magenta; */
    float: left;
    border: 2px solid maroon;
  }
  .box2{
    background-color: brown;
    width: 200px;
  }
  <div class="box1"></div>
  <div class="box2">
    Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quos unde quasi neque harum totam, deserunt fugit voluptatem temporibus. Ducimus asperiores quia culpa tempora illo nihil et? Obcaecati nihil ad voluptate.
  </div>

2.7 文字环绕思路:

    1、图片元素是行盒,一般的思路会这样考虑,想要p紧挨着图片排列,现在因为p标签是块盒独占一行,所以不能与图片同行,那么将p标签改成行盒,是不是就可以了呢? 结果能看到,文字与图片的对齐方式不是我们所期望的。 
    2、正确的实现方案:盒子左浮动即可。
  img{
    float: left;
    margin-right: 10px;
  }
  p{
    background-color: pink;
  }
  p span{
    border: 2px solid blue;
    line-height: 2;
  }
  <img src="01.jpg" alt="">
  <p>
    <span>
    Lorem ipsum dolor, sit amet consectetur adipisicing elit. Repudiandae deleniti ea non blanditiis quaerat ipsum consequatur, id, accusantium enim cupiditate eaque, rem cumque aperiam sint recusandae iusto. Sapiente, ex obcaecati.lorem
    </span>
  </p>

2.8 高度坍塌解决方案

  根源:常规流盒子在计算自动高度时,不会考虑浮动盒子的高度
  解决方案:通过伪元素after,设置成块盒之后,清除浮动
    清除浮动的含义:该元素出现在前面所有浮动盒子的下方
  .box{
    border: 3px solid blue;
  }
  .box .item{
    width: 50px;
    height: 50px;
    background-color: red;
    float: left;
  }
  .clear::after{
    content: '';
    display: block;
    clear: both;
  }
  <div class="box clear">
    <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>