【百度前端学院学习笔记】Day6 浮动/BFC

内容来自于:
MDN floats
注:这一节MDN的中文翻译(带分栏样式)和英文原版(带wrapping)内容不一样。
CSS核心概念Block Formatting Contexts
详说 Block Formatting Contexts (块级格式化上下文)

一、什么是浮动?

浮动曾被用来实现整个网站页面的布局,它使信息列得以横向排列(默认的设定则是按照这些列在源代码中出现的顺序纵向排列)。目前出现了更新更好的页面布局技术,所以使用浮动来进行页面布局应被看作传统的布局方法。

比如:图片是块元素,下面的的文字<p>也是块元素,给图片设置一个float:left,就可以让<p>贴到图片的右边。
在这里插入图片描述
比如,让一个<p>的首字母设置float:left,就可以实现首字下沉的效果。
在这里插入图片描述
再比如,三个<div>(包含<h2><p>)可以通过float实现分栏的效果。
在这里插入图片描述

二、普通流 / 浮动 / 绝对定位

CSS中的定位机制: 普通流,浮动,绝对定位 (其中"position:fixed" 是 “position:absolute” 的一个子类)

  • 普通流(normal flow): 在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行块级元素则会被渲染为完整的一个新行(每个block元素默认占据父类元素的100%宽度), 除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定。

  • 浮动 (Floats): 在浮动布局中,元素首先按照普通流的位置出现,然后根据浮动的方向尽可能的向左边或右边偏移,其效果与印刷排版中的文本环绕相似。
    浮动增加了一种横向思维,设置了float属性的块元素将不再默认占据父类元素100%的宽度,而是根据widthpaddingbordermargin这样的属性来瓜分父元素的宽度。
    由于不属于normal flow,因此父类元素的高度并不会因为它包含的float元素而改变。举个极端的例子,一个父类元素只包含float元素,不存在其他normal flow元素,因此就表现出高度为0(高度塌陷)的情况。在实际布局中,往往这并不是我们所希望的,所以需要闭合浮动元素,使其包含框表现出正常的高度。

  • 绝对定位 (Absolute Positioning): 暂时没学到。

三、BFC/Flow Root

3.1 什么是BFC?

Block Formatting Contexts (块级格式化上下文) 是CSS2中的叫法,在CSS3中它被称为Flow Root,并增加了一些新的触发条件和特性。注意:BFC也属于normal flow。

从样式上看,具有 BFC 的元素与普通的容器没有什么区别,但是从功能上,具有 BFC 的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且 BFC 具有普通容器没有的一些特性,例如可以包含浮动元素,例如清除浮动的方法(如 overflow 方法)就是触发了浮动元素的父元素的 BFC ,使到它可以包含浮动元素,从而防止出现高度塌陷的问题。

"通俗一点来讲,可以把 BFC 理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。"

简单来说,BFC 就是一种属性,这种属性会影响着元素的定位以及与其兄弟元素之间的相互作用。

3.2 BFC 的特性

从整体上看,BFC 是隔离了的容器,这个具体可以表现为三个特性:

3.2.1 特性一:外边距折叠(Margin collapsing)

同一个BFC属性的容器内部,会产生外边距折叠,这在我的【百度前端学院学习笔记】Day5 盒子模型2.3节有提到过。

<head>
<style>
div{
    width: 100px;
    height: 100px;
    background: lightblue;
    margin: 100px;
}
</style>
</head>
<body>
    <div></div>
    <div></div>
</body>

在这里插入图片描述
可以看到两个<div>之间只有100px的间隔而不是200px,因为这两个元素都在同一个BFC容器<body>中。
如果把这两个方块放在两个独立的BFC容器中,情况就不一样了:

<div class="container">
    <p></p>
</div>
<div class="container">
    <p></p>
</div>
.container {
    overflow: hidden;
}
p {
    width: 100px;
    height: 100px;
    background: green;
    margin: 100px;
}

两个方块之间隔开了200px。为什么呢?因为overflow: hidden;触发了BFC属性,两个<div class="container">成为了两个互相独立的BFC容器
在这里插入图片描述

3.2.2 特性二:BFC 可以包含浮动的元素(解决高度坍缩)

这也正是使用 overflow: hiddenoverflow: auto方法闭合浮动的原理,使用 overflow: hidden 或 overflow: auto 触发浮动容器的 BFC 特性,从而可以包含浮动元素,闭合浮动。

W3C 的原文是“‘Auto’ heights for block formatting context roots”,也就是 BFC 会根据子元素的情况自动适应高度,即:使其子元素中包括浮动元素。
可以参考这个示例

3.2.3 特性三:BFC 可以规避浮动元素

试看下面的例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
        width: 90%;
        max-width: 900px;
        margin: 0 auto;
        }

        p {
        line-height: 2;
        word-spacing: 0.1rem;
        width: 1200px;
        height: 200px;
        background-color: lightcoral;
        }
        img{
            float:left;
            margin-right: 20px;
        }
    </style>
</head>
<body>
    <h1>Simple float example</h1>

    <img src="https://mdn.mozillademos.org/files/13340/butterfly.jpg" alt="A pretty butterfly with red, white, and brown coloring, sitting on a large leaf">

    <p> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et a urna. Ut id ornare felis, eget fermentum sapien.</p>

    <p>Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.</p>
</body>
</html>

在这里插入图片描述
虽然两个p元素的文字部分没有被图片遮挡(content部分自动由于是 行内元素 环绕了浮动元素),但是可以清楚地通过粉红色的背景看到,这两个p元素的content部分确被图片遮挡了,这里可以触发p元素的BFC属性,达到如下图所示的效果:

        p {
        line-height: 2;
        word-spacing: 0.1rem;
        width: 400px; //为了方便说明,我把p元素的宽度改小了一些,这样<p>和<img>可以共存一行
        height: 200px;
        background-color: lightcoral;
        overflow: auto; //新增了overflow属性,以触发BFC
        }

在这里插入图片描述

height: 300px;

如果我把p元素的高度改变一下,使得只有一个p元素和img在一行,另外一个则自动回归到normal flow的样式(BFC本就属于normal flow)。
在这里插入图片描述

3.2.4 BFC 与 hasLayout,一个兼容性的问题

除了使用 overflow: hidden 触发 BFC 外,还使用了一个 *zomm: 1 的属性,这是 IEhack ,因为 IE6-7 并不支持 W3C 的 BFC ,而是使用私有属性 hasLayout 。从表现上来说,hasLayout 跟 BFC 很相似,只是 hasLayout 自身存在很多问题,导致了 IE6-7 中一系列的 bug 。触发 hasLayout 的条件与触发 BFC 有些相似。

为元素设置 IE 特有的 CSS 属性zoom:1触发 hasLayout ,zoom 用于设置或检索元素的缩放比例,值为“1”即使用元素的实际尺寸,使用 zoom: 1 既可以触发 hasLayout 又不会对元素造成其他影响,相对来说会更为方便。

这时我们需要注意一个问题:既然 hasLayout 有着跟 BFC 相似的功能,那么在实际开发中,就要为需要触发 BFC 的元素同时触发 hasLayout ,这样 BFC 和 hasLayout 具有的一些特殊性质可以在现代浏览器和 IE 中同时产生,避免一个元素在不同浏览器间的表现因为 BFC 或 hasLayout 出现差异。事实上,在实际开发中很多莫名其妙的问题其实都是因此而产生的。当然同样地,如果一个元素没有触发 BFC ,也要尽量保证它没有触发 hasLayout 。

就像下面这样:

.clearfix {
  overflow: auto;
  zoom: 1; //兼容IE6-7
}

3.3 如何触发BFC?

  • body 根元素默认是BFC
  • 浮动元素: float 除 none 以外的值
  • 绝对定位元素: position (absolute、fixed)
  • display 为 inline-block、table、table-cells、table-caption、flex(CSS3里新增了flow-root
  • overflow 除了 visible 以外的值 (hidden、auto、scroll)
  • fieldset 元素

三、浮动消除?

关于消除浮动的方法无非两种:

  • 其一,通过在浮动元素的末尾添加一个空元素,设置 clear:both属性,after伪元素其实也是通过 content 在元素的后面生成了内容为一个点的块级元素;
    它的缺点是:创造了很多无用的标签,混淆了语义化和样式分离的原则,与html的语义化原则相违背。
  • 其二,通过设置父元素 overflow 或者display:inline-block、table、table-cells、table-caption、flex、flow-root 属性来闭合浮动。
  • CSS3里还可以设置display: flow-root,flow-root是CSS3里BFC的扩展概念。 overflow会影响页面的外观:比如强制隐藏超出边框的内容,或者添加不想要的滚动条,而用display: flow-root则可以避免这些问题,这是CSS3的一种进化。

具体的实现可以看这篇文章:
那些年我们一起清除过的浮动

其中有一点需要注意:

:before::before写法是等效的; :after::after写法是等效的,前者是CCS2的写法,后者是CSS3的写法。:before/:after的兼容性要比::before/::after好 ,不过在H5开发中建议使用::before/::after比较好。

注意:

  • 这些伪元素 要配合content属性一起使用
  • 这些伪元素 不会出现在DOM中,所以不能通过js来操作,仅仅是在 CSS 渲染层加入
  • 这些伪元素 的特效通常要使用:hover伪类样式来激活
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值