《深入理解 CSS 布局:常规流、浮动流与定位流》

138 阅读5分钟

视觉格式化模型

盒子模型:规定单个单个盒子的排列规则。

但是页面中有很多元素。有很多的盒子,这些盒子的排列方式就是由视觉格式化模型所规定。

视觉格式化模型(布局规则):页面中的多个盒子排列规则。

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

  • 常规流
  • 浮动流
  • 定位流

常规流(文档流、普通文档流、常规文档流)

所有元素默认情况下都属于常规流布局

总体规则:块盒独占一行,行盒水平排列

包含块(containing block):每个盒子都有它的包含块,包含块决定了盒子的排列区域。

绝大部分情况下:盒子的包含块都为其父元素的内容盒。

包含块参考文章:juejin.cn/post/732141…

常规流中块盒排列规则

  • 每个块盒的总宽度(margin+border+padding+content),必须刚好等于包含块的宽度
  • 宽度的默认值是auto;将剩余的空间吸收掉
  • margin的默认值也是auto,也是将剩余空间吸收掉
  • 宽度吸收能力强于宽度
  • 若宽度、边框、内边距、外边距计算后、仍然有剩余空间,该空间被margin-right吸收掉
    <style>
    .parent{
        width:100px;
        height:100px
    }
    .child{
        with:10px;
        height:10px;
        margin:auto;
    }
    </style>
    <div class="parent">
        <div class="child"></div>
    </div>

结合上面长常规流中块模型排列规规则,知道为何child只会左右居中不会上下居中了把。

因为每个块盒的总宽度(margin+border+padding+content),必须刚好等于包含块的宽度;如果marginauto;margrin最会把水平剩余空间吸收掉。

常规流中百分比的取值

paddingwidthmargin的所有百分比取值,都是相对于包含块的宽度。

height的百分比:

  • 含块的高度是否取决于子元素的宽度(子元素高度设置了百分比,父元素没有设置高度),高度设置无效
  • 包含块的高度不取决于子元素,此时的百分比相对于包含块的高度

上下外边距的合并(经典面试题)

两个常规流块盒,上下边距相邻,会进行合并。两个外边距取最大值。

浮动流(css2属性,兼容性非常好)

常见使用场景:

  • 文字环绕
  • 横向排列

浮动方式:修改float属性为

  • left:左浮动、元素靠上、靠左
  • right 右浮动、元素靠上、靠右

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

浮动的基本特点

  • 设置元素浮动后,元素一定变成块盒(盒子如果是行盒变成块盒),所以浮动元素一定是块盒
  • 浮动元素的包含块和常规流一样,为父元素的内容盒

浮动元素的盒子尺寸规则

  • 宽度为auto时,和常规流不同,常规流中盒子宽度为auto时吸收包含块剩余空间,而浮动流中盒子宽度为auto表示盒子自适应内容区宽度
  • 高度为auto时和常规流一样,适应内容区高度
  • marginauto时,值为0
  • 边框,内边距的百分比设置与常规流一样,都是相对于父元素包含块的宽度

浮动盒子排列规则

  • 左浮动、元素靠上、靠左
  • 右浮动、元素靠上、靠右
  • 浮动盒子在包含块中排列时,会避开常规流盒子。
  • 常规流盒子排列无视浮动流
  • 行盒在排列时,会避开浮动盒子(图片文字环绕效果实现原理)。

注意浏览器有一个规则,如果文字没有在行盒中,浏览器会自动生产一个行盒(匿名行盒,看不见)。

定位流

手动控制元素在包含块的精准位置

涉及到的定位属性position

positon属性

只要一个元素定位的取值不是static那么就认为该元素是一个定位元素、定位元素会脱离常规流(相对定位除外)。

  • 默认值:static、静态定位(不定位)
  • relative:相对定位
  • absolute:绝对定位
  • fixed:固定定位

一个脱离了文档流的元素特点:

  • 文档流中的元素摆放时,会忽略脱离了文档流的元素
  • 文档流中元素计算高度时,会忽略脱离了文档流的元素(常见面试题的高度坍塌就是此原因)

高度塌陷

高度塌陷的根源:常规流盒子自动计算高度,在计算的时候,不考虑浮动盒子;

清除浮动;涉及css属性:clear

  • 默认值:none
  • left:清除左浮动,该元素必须出现在前面所有左浮动盒子的下方
  • right:清除右浮动,该元素必须出现在前面所有右浮动盒子的下方
  • both:清除左右浮动,该元素必须出现在前面所有浮动盒子的下方

相对定位

不会导致元素脱离文档流,只是让元素在原来的位置上偏移。

涉及css属性:positon:relative、top、right、left、bottom

相对定位的偏移不会影响其他盒子

绝对定位

涉及css属性:positon:absolute、top、right、left、bottom

  • 宽度为auto,适应内容
  • 包含块变化:找祖先元素中第一个定位元素,该元素的填充盒为其包含块。

固定定位

其他情况与绝对定位一致

但是包含块不同:固定为视口(浏览器的可视窗口,初始化包含块为html,可视化窗口是你可能看见的区域),如果最近的右变形元素那么其包含块为该元素的content内容盒。

多个元素定位重叠时-堆叠上下文解决

设置z-index,通常情况下值越大越靠近用户。

补充

  • 绝对定位和固定定位元素一定是块盒
  • 绝对定位元素和固定定位元素一定不是浮动
  • 没有外边距合并