专栏首页多云转晴两个CSS知识点:BFC和选择器权重

两个CSS知识点:BFC和选择器权重

BFC

BFC 全称 Block Formatting Context,翻译过来就是块格式化上下文,它是 CSS 规范的一部分。

可以用一些 CSS 属性为一个元素创建出 BFC。决定元素的内容如何渲染以及与其他元素的关系和交互。BFC 有一个重要的特点:具有隔离作用。

通过下列方式可以创建块格式化上下文:

  • 根元素 <html>
  • 浮动(float,但值不能是 none);
  • 绝对定位元素(positionabsolute 或者 fixed);
  • overflow 值不为 visible 的块元素;
  • display 值为 flow-root 的元素;
  • 行内块元素(displayinline-block);
  • displayflow-root,它可以创建无副作用的 BFC;
  • 弹性元素(displayflexinline-flex 元素的直接子元素);
  • 网格元素(displaygridinline-grid 元素的直接子元素`);
  • 多列容器(元素的 column-countcolumn-width 不为 auto);
  • 表格单元格(displaytable-cell,HTML 表格单元格默认为该值);
  • 表格标题(displaytable-caption,HTML 表格标题默认为该值);
  • 匿名的表格单元格元素(元素的 displaytabletable-rowinline-table 等);

两个典型的例子:

  • 如何让浮动内容和周围的内容等高?
  • 如何解决 margin 塌陷?

让浮动内容和周围的内容等高

比如下面的代码:

<style>
  #main{
    background-color: gold;
  }
  .child1{
    height: 200px;
    width: 100px;
    float: left;
    background-color: green;
  }
</style>
<div id="main">
  <div class="child1"></div>
</div>

child1 使用了 float,浮动脱离了文档流,child1 创建了 BFC。而 #main 元素没有设置确切的高度,也没有创建 BFC,就造成了高度的塌缩。

父元素没有展示出来

要解决这个问题可以给 #main 元素也创建 BFC,创建方式有很多种,比如 display: flow-root 或者 overflow: hidden

#main{
  background-color: gold;
  overflow: hidden;
}

等高

解决 margin 塌陷

例如:

<style>
  #main{
  height: 200px;
  width: 200px;
  margin-top: 100px;
  background-color: gold;
}
.child1{
  margin-top: 50px;
  height: 100px;
  width: 100px;
  background-color: green;
}
</style>
<div id="main">
  <div class="child1"></div>
</div>

结果就发现,只有父元素的 margin 生效了,解决这个问题是给 #main 元素创建 BFC,让子元素与外部元素隔离。

#main{
  height: 200px;
  width: 200px;
  margin-top: 100px;
  background-color: gold;
  overflow: hidden;
}

结论:处于同一个 BFC 中的元素相互影响,可能会发生 margin 塌陷。 一开始 #main 元素和他的子元素 child1 都不具备 BFC,都处于根元素的 BFC 中,也就产生了影响。#main 元素创建 BFC 后,内部的子元素就与外部做了隔离。

clear 属性

利用浮动可以创建出基本的页面布局,也可以实现文字环绕效果,例如:

<style>
  #main{
    border: 1px solid red;
    overflow: hidden;
  }
  p{
    margin: 0;
  }
  .child1{
    width: 100px;
    height: 100px;
    background-color: rgba(20, 100, 0, .6);
    float: left;
  }
</style>
<div id="main">
  <div class="child1"></div>
  <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Ullam fugiat, incidunt culpa voluptates commodi soluta, cupiditate sequi corporis atque nihil provident magni quos veritatis, dolorem velit temporibus autem pariatur earum?</p>
</div>

效果:

文字环绕

但有时候浮动会影响到周围元素,尤其是把周围元素遮盖住,这是我们不希望看到的。

CSS 提供了 clear 属性可以给一个元素清除浮动。例如下面的代码:

<style>
  #main{
    border: 1px solid red;
    overflow: hidden;
  }
  .child1{
    width: 100px;
    height: 30px;
    background-color: gold;
    float: left;
  }
  .child2{
    width: 100px;
    height: 30px;
    background-color: green;
  }
  .middle{
    width: 200px;
    height: 30px;
    background-color: purple;
  }
</style>
<div id="main">
  <div class="child1"></div>
  <div class="middle"></div>
  <div class="child2"></div>
</div>

child1 左浮动后,middle 就会被遮挡。

遮挡

要想完整显示 middle 的内容可以使用 clear: left,表示清除左边的浮动,这样它会移动到浮动元素的下方。

.middle{
  clear: left;
}

clear-left

clear 属性不仅可以应用于非浮动块,也可以应用于浮动块。例如下面的代码,假如 child1child2 都是浮动元素,并且 child1 是左浮动,child2 是右浮动。如果给 child2 加入 clear: left,那么 child2 的上边框会与 child1 的下边框对齐。

<div class="wrapper">
  <div class="child1"></div>
  <div class="child2"></div>
</div>

浮动

清除左浮动

假设 wrapper 元素没有固定的高度,那么高度就会塌缩。

高度塌缩

如果想要 wrapper 自适应即包含所有浮动元素,那就需要清除浮动或者给 wrapper 元素创建 BFC。清除浮动可以这么做:

.wrapper::after {
  content: "";
  display: block;
  clear: both;
}

总结

BFC 即:格式化上下文,它既不是一个 CSS 属性,也不是一段代码,而是 CSS2.1 规范中的一个概念,决定元素的内容如何渲染以及与其他元素的关系和交互。BFC 有五条规则:

  1. BFC 有隔离作用,内部元素不会受外部元素的影响(反之亦然)。
  2. 一个元素只能存在于一个 BFC 中,如果能同时存在于两个 BFC 中,那么就违反了 BFC 的隔离规则。
  3. BFC 内的元素按正常流排列,元素之间的间隙由元素的外边距(margin)控制。
  4. BFC 中的内容不会与外面的浮动元素重叠。
  5. 计算 BFC 的高度,需要包括 BFC 内的浮动子元素的高度。

选择器权重

类型

例子

权重

ID 选择器

#root

100

class 选择器

.wrapper

10

属性选择器

[type='text']

10

标签和伪类

div

1

伪元素

::first-letter

1

行内样式

<p style="height:20px">

1000

通配符

*

0

关系选择符(+>、``、||~)与通配符一样,都是没有权重的。

如果一个样式属性后面加上 !important 规则,此声明将覆盖任何其他声明。也可以认为它的优先级是最高的。

继承和通配符

例如下面的代码:

<style>
  *{
    color: red;
  }
  p{
    color: green;
  }
</style>
<p>OK!!!
  <span>span span</span>
</p>

span 元素的字体颜色是什么颜色?

答案是 red,这说明通配符的权重要比继承权重大。如果去掉通配符,那么 span 的字体颜色将继承 p 元素的字体颜色。

关系选择器

  1. 在下列关系选择器中,找出相邻选择器,能匹配相邻兄弟元素的是?

A. .bfc+div B. .bfc div C. .bfc > div D. .bfc~div

答案是 A

第二个选项表示后代选择器,儿子元素、孙子元素都可以选择到; 第三个选项表示子代选择器,只有 .bfc 的子元素可以选择到; 第四个选项表示通用的兄弟选择器,不管相不相邻都可以选择到;

  1. 以下属性选择器表示属性值以“val-”开头的是?

A. [attr^="val"] B. [attr~="val"] C. [attr|="val"] D. [attr$="val"]

答案 C

属性选择器通过已经存在的属性名或属性值匹配元素。例如:

input[type="text"]{
  color: red;
}
  • [attr^="val"] 表示属性值以 val 开头,题目是说以 val- 开头,所以不正确;
  • [attr~="val"] 表示属性值用空格分割为多个值,其中至少有一个值是 val,例如 class 属性就可以有多个值;
  • [attr|="val"] 表示带有以 attr 命名的属性的元素,属性值为 val 或以 val- 为前缀。选取有自定义属性的元素时可以使用该选择器(data-*)。
  • [attr$="val"] 表示属性值以字符串 val 结尾;
  • [attr*="val"] 表示选取 attr 属性值中包含 val 字符串的元素。

除此之外,还有一种格式:

[attr operator value i]

它表示在属性选择器的右方括号前添加一个用空格隔开的字母 i(或 I,大小写不敏感),可以在匹配属性值时忽略大小写。如:

/* 包含 "insensitive" 的链接,不区分大小写 */
a[href*="insensitive" i] {
  color: cyan;
}

/* 包含 "cAsE" 的链接,区分大小写 */
a[href*="cAsE" s] {
  color: pink;
}

参考资料:

视觉化模型:

https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Visual_formatting_model

本文分享自微信公众号 - Neptune丶(Neptune_mh_0110)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-19

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • HTML5 File API 使用技巧

    在 HTML5 的 input 标签中,新增了一个 type=file 属性的表单控件。这个控件可以让我们能调出文件选择窗口然后读取这些文件的内容成为可能。

    多云转晴
  • HTML5 File API

    在 HTML5 的 input 标签中,新增了一个 type=file 属性的表单控件。这个控件可以让我们能调出文件选择窗口然后读取这些文件的内容成为可能。

    多云转晴
  • 排序算法(一)

    数组排序算法是一个经典的算法问题,这类排序算法非常多,比如我们熟知的冒泡排序、插入排序、快速排序等算法。这篇文章主要说一下五种排序算法:

    多云转晴
  • 没人看系列----css 随笔

    kmonkey
  • 理解CSS布局和块格式化上下文

    块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与...

    D2
  • CSS3三维变形,其实很简单!

    HTML5学堂:空间的变化一直是视觉感官上最吸引人的东西,而如果要把这些空间上的变化用代码在浏览器上实现出来,就需要深入的来了解CSS3的transform 3...

    HTML5学堂
  • 【前端】:浏览器渲染模式

    在很久以前的网络上,页面通常有两种版本:为网景(Netscape)的 Navigator准备的版本以及为微软(Microsoft)的 Internet Expl...

    WEBJ2EE
  • CSS_边距填充

    填充:指向一个元素的内部,增加空间,(内边距),与外边距不同,填充会改变元素的大小。随着填充的增加,元素会被撑大。

    bye
  • 【云+社区年度征文】2020一网打尽CSS世界

    一个水平流上只能单独显示一个元素,因此理论上都可以配合clear属性来清除浮动带来的影响。

    奋飛
  • css3的学习笔记

    1.opacity ----------------------取值0-1之间,给整个元素和其所有子元素设置透明度级别

    IMWeb前端团队

扫码关注云+社区

领取腾讯云代金券