[object Object]

HTML与css(三)

2020年5月7日星期四 HTML/CSS

Table of Contents generated with DocToc (opens new window)

# [1] 性能优化

编写高质量的 CSS 代码主要体现在 2 个方面:可读性和可维护性和高性能。对于一名前端工程师来说,如何平衡“追求高性能”和“可维护性”是一个很值得思考的问题。

# 属性缩写

# 盒模型缩写

如: 边框框的宽度(border-width),边框的外观(border-style),边框的颜色(border-color); margin;padding 等等

# 背景缩写

background-image: url("images/flower.jpg");
background-repeat: no-repeat;
background-position: 80px 40px;

/* 缩写 */
background: url("images/flower.jpg") no-repeat 80px 40px;
1
2
3
4
5
6

# 字体缩写

注意:如果使用字体简写形式,我们至少要指定 font-family 和 font-size 属性,其他属性如果没有指定则将自动使用默认值。在简写形式中,font-size 值和 line-height 值之间是需要加入斜杠“/”的

ont-family:"微软雅黑";
font-size:12px;
font-weight:bold
line-height:1.5em;

/* 缩写 */

font:"微软雅黑" 12px/1.5em bold;
1
2
3
4
5
6
7
8

# 语法压缩

  1. 空白符:纵向书写 以及横向书写(发布时压缩)
  2. 结尾分号:最后一个属性的结尾分号可以省略
  3. url()的引号: background-image 和 cursor:url(default.cur),default 就可以不写引号
  4. 属性值为“0”: 属性值为 0 的可以不添加单位
  5. 属性值为“以 0 开头的小数: 0.5em 可以写成 .5em
  6. 合并相同的定义 : 使用群组选择器合并相同的部分样式
  7. 利用继承进行合并 在 CSS 中,很多属性是可以继承的。
  • 文本相关属性:font-family、font-size、font-style、font-weight、font、line-height、text-align、text-indent、word-spacing。
  • 列表相关属性:list-style-image、list-style-position、list-style-type、list-style。
  • 颜色相关属性:color。

# 图片压缩

图片的传输量在一个页面的传输量中往往占的比重很高,因此对图片大小的压缩尤为重要。 在实际开发中,JPEG.jpg 和 GIF 是最常见的图片格式。深入理解这三种图片格式适合在哪种情况下使用,并且如何减少图片大小非常重要。

  1. JPEG 可以很好地处理大面积色调的图像,适合存储颜色丰富的复杂图像,如照片、高清图片等。此外,JPEG 不支持透明。
  2. jpg 是一种无损格式,可以无损压缩以保证页面打开速度。此外.jpg 支持透明。
  3. GIF 格式图像效果较差,但是可以制作动画。 也就是说,如果想要展示色彩丰富而高品质图片,可以使用 JPEG 格式;如果是一般图片,为了减少体积,可以使.jpg 格式;如果是动画图片,可以使用 GIF 格式。

# 高性能的选择器

了解选择器在浏览器中的解析原理以及不同选择器的解析速度 能够使我们的 css 性能速度锦上添花,选择器在浏览器中的解析原理 : #column .content div{ color:red} 事实上浏览器对选择器的解析是从右往左的 首先找到所有的 div 然后查找该元素是否存在具有 content 类的元素,最后再以及匹配的父级元素上继续查找是否还有 id 为 column 的元素

不同选择器的解析速度:

#column .content div {
  .....;
}
#column .test {
  .....;
}
#test {
  .....;
}
1
2
3
4
5
6
7
8
9

实际上第三个性能最好直接查找 id 选择器 快速定位,第一个性能最差 匹配量较大,书写的最右边的选择器我们称之为关键选择器 对执行效率有着决定性的影响 谷歌工程师 Steve Souders 对 css 选择器的匹配效率从高到低做了一个排序:

ID选择器
class选择器
元素选择器
相邻选择器  m+n{}    (相邻与兄弟选择器的区别:前者选去取后面相邻的一个  后者选区后面的所有  m~n{})
子选择器  m>n{}
后代选择器  m n{}
通配符选择器 *{}
属性选择器
伪类选择器
1
2
3
4
5
6
7
8
9

若我们想更好的使用高性能选择器需要注意一下技巧

  1. _{}表示选区页面所有的选择器 #wrapper _{}表示选取 wrapper 下面的所有元素通配符的匹配了非常大 一般情况下不建议使用 效率也非常低;
  2. 不要在 id 选择器以及 class 选择器前面添加元素名div#wrapppe{},这是多余的;
  3. 选择器最好不要超过三层 位置靠右的选择器选择条件尽可能精确
  4. 避免使用后代选择器 尽量少用子选择器: 后代选择器匹配量比较大,应该避免使用。如果非要用的话,建议使用子选择器代替。但是子选择器匹配量也不小,如果有其他选择器如 id 选择器或 class 选择器等代替,也尽量少用子选择器。不过我们要注意一下,尽量少用不等于不用,不要为了减少子选择器的使用而增加过多的 id 和 class,以致 id 和 class 泛滥成灾。

对于小项目来说,这的确没多大影响。但是对于一个大型项目,特别是访问量每天达几百万次的网站来说,哪怕是一点点的性能提升也是非常重要的。当然,就算是做小项目,写一手优雅的代码是高手们的一种良好习惯。因为高手也讲究“诗意的栖居”。在确保 CSS 的可读性和可维护性良好的前提下,再去考虑高性能的选择器。

# [2] css 技巧

# 元素水平居中

  1. 对于块元素来说,不管父元素的宽度如何,只要给块元素指定宽度,这个方法就有效。如果没有给块元素指定宽度,则块元素默认会占满允许的最大宽度,此时这个方法是没有效的。因此想要使用“margin:0 auto”来实现块元素的水平居中,就一定要指定块元素的宽度

  2. 对于行内元素(inline)以及复合行内元素(inline-*),我们可以使用“text-align:center”来实现水平居中。也就是说,“text-align:center”不仅可以用于文字,也可以用于行内元素以及复合行内元素。

# 元素垂直居中

  1. 对于单行文字来说,我们定义 line-height 和 height 这两个属性的值相等就可以实现垂直居中。

  2. 如果父元素高度固定,文字可能是两行或者更多行,如何实现多行文字的垂直居中呢?

实现的关键是,用一个 span 标签把所有文字包含起来,然后定义 span 为 inline-block 元素,之后使用 inline-块元素垂直居中的方式来处理即可。对于 inline-块元素垂直居中的实现方式,我们在下面会讲解。大家可以对比理解一下。

<style type="text/css">
  p {
      display: table-cell;
      vertical-align: middle;
      width: 400px;
      height: 120px;
      border: 1px dashed gray;
  }
     span {
    display: inline-block;
  }
</style>
<body>
  <p>
    <span>
      《web前端开发精品课·HTML和CSS基础教程》<br />
      《web前端开发精品课·HTML和CSS进阶教程》<br />
      《web前端开发精品课·CSS3教程》</span
    >
  </p>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  1. 对于块元素,直接利用 position,减半 left 和 top 偏移即可

  2. 对于行内块元素的垂直居中,我们可以使用“display:table-cell”结合“vertical-middle”来实现。结合之前“display:table-cell”这一节介绍的内容,我们很容易理解其原理。

div {
  display: table-cell;
  vertical-align: middle;
}
img {
  vertical-align: middle;
}
1
2
3
4
5
6
7

# CSS Sprite

同一张背景图使用 background-position 背景定位取得:

  • 最大的优点就是减少 http 请求数从而提高页面的加载速度,除此之外还减少了图片整体的大小
  • 最大的缺点就是不方便后期维护 需要精确计算每个小背景图位置 注意事项:
  1. 建议在开发后期使用雪碧图我不是开发前期使用,否则维护麻烦
  2. 有条理的组织雪碧图 将小背景按照类别,风格,大小划分好 便于后期维护
  3. 控制雪碧图的大小 不要超过 200kb 对于大于 200kb 的我们可以按照类别划分成多个雪碧图比较好
  • CSS Sprite Generator 官网地址 : http://css.spritegen.com/ 在线生成大背景图 还可以定义小背景图的位置透明度 以及背景色
  • Sprite Cow 官网地址: http://www.spritecow.com 可以自动生成雪碧图的某个代码

# Icon Font

icon font 图标技术,使用字体文件取代图片文件实现小图标的效果 iconfont 网站图标库下载的文件:

.eot 微软开发的用于嵌入页面的字体  IE专用的字体格式
.woff W3组织推荐的标准   web字体的最佳格式
.ttf  Mac OS和Window操作系统中最常见的字体格式
.svg    W3C组织制定的开放标准的图形格式
1
2
3
4

下载好图标字体文件代码并且放入网站目录,在 css 中使用@font-face 定义字体,在 html 中,元素添加 class="iconfont",在元素添加图标对于应的字符串

icomoon 国外最大的图标分享网站 https://icomoon.io/

# [3] css 重要概念

# 什么是包含块

包含块 containing block,包含块是视觉格式化模型中的一个重要概念,它与 CSS 盒子模型类似。包含块也可以理解为一个矩形盒子,这个矩形的作用是为这个矩形内部的后代元素(子元素、孙元素等)提供一个参考。一个元素的大小和定位往往是由该元素所在的包含块决定的。

我们都知道,如果有两个 div,一个是父元素,另外一个是子元素,父元素会决定子元素的大小和定位。包含块是什么呢?简单来说,就是可以决定一个元素大小和定位的元素。

通常情况下,一个元素的包含块是由离它最近的“块级祖先元素”的“内容边界”决定的。但当元素被设置为绝对定位时,此时该元素的包含块是由离它最近的“position:relative”或“position:absolute”的祖先元素决定。一个元素生成的盒子会扮演该元素的内部元素包含块的角色。也就是说,一个元素的 CSS 盒子为它的内部元素建造了包含块。

# 包含块的判定以及包含块的范围

一个元素会为它的内部元素创建包含块,内部元素的大小以及定位都跟它的包含块有关。那么是不是说一个元素的包含块就是它的父元素呢?答案是否定的。

  1. 根元素(HTML 元素),是一个页面中最顶端的元素,它没有父元素。根元素存在的包含块,被称为“初始包含块(initial containing block)。
  2. 如果元素的 position 属性为 fixed,那么它的包含块是当前可视窗口,也就是当前浏览器窗口。
  3. 如果元素的 position 属性为 static 或 relative,那么它的包含块是它最近的块级祖先元素创建的。祖先元素必须是 block、inline-block 或者 table-cell 类型。
  4. 如果元素的 position 属性为 absolute,那么它的包含块是由最近的 position 属性不为 static 的祖先元素。这里的祖先元素可以是块元素,也可以是行内元素。

# 层叠上下文

理解层叠上下文,不仅可以帮助我们深入理解 z-index 对元素堆叠顺序的控制,而且对于我们深入理解浮动和定位也是非常重要的

# 什么是层叠上下文?

  1. 层叠上下文,是 HTML 中的一个三维的概念。从“z-index 属性”这一节我们知道,虽然一个网页是平面的,但实际上网页是三维结构,除了 x 轴、y 轴,它还有 z 轴。z 轴往往都是用来设定层的先后顺序的。
  2. 层叠上下文跟块级格式上下文(BFC)相似,是可以创建出来的。也就是说,跟创建 BFC 一样,你可以在 CSS 中添加一定的属性来将某个元素创建一个层叠上下文出来。

如果一个元素具备以下任何一个条件(不考虑 CSS3),则该元素会创建一个新的层叠上下文

(1) 根元素。
(2)z-index不为auto的定位元素。
1
2

# 什么是层叠级别?

层叠级别,即 stacking level。同一个层叠上下文的背景色以及内部元素,谁在上谁在下,这些都是由层叠级别”来决定的。也就是说,层叠级别是针对同一个层叠上下文而言的。

层叠级别与层叠上下文,是两个不同的概念,大家要认真理解好。

在同一个层叠上下文中,层叠级别从低到高排列

(1)背景和边框(父级):也就是当前层叠上下文的背景和边框。
(2)负z-index:z-index为负值的“内部元素”
(3)块盒子:普通文档流下的块盒子(block-level box)
(4)浮动盒子:非定位的浮动元素(也就是排除了position:relative的浮动盒子)
(5)行内盒子:普通文档流下的行内盒子(inline-level box)
(5)z-index:0:z-index为0的“内部元素”
(6)正z-index:z-index为正值的“内部元素”
1
2
3
4
5
6
7

img

(1)除了“背景和边框”这一条是当前层叠上下文之外,其他的都是针对当前层叠上下文内部的元素。 (2)关于块盒子(block-level box)和行内盒子(inline-level box),我们在下一节“BFC 和 IFC”中会给大家介绍。注意,inline-block 元素不是块盒子,而是行内盒子。 (3)父元素内部的元素(即后代元素),如果它是一个 z-index 取值不为 auto 的定位元素,则这个元素会创建新的层叠上下文。不过这个由内部元素创建的层叠上下文依旧属于父层叠上下文的一部分。也就是说,层叠上下文是可以嵌套的,内部元素所创建的层叠上下文均受制于父元素创建的层叠上下文。

这里问大家一个问题,为什么行内元素的层叠级别要比浮动元素和块元素的高呢?我明明感觉浮动元素和块元素要更高一点啊。我们先来看一个分析图如下图所示。

img

背景和边框一般为装饰属性,所以层叠级别最低。浮动元素和块元素一般用作布局,而行内元素都是内容。对于一个页面来说,最重要的当然是内容。因此,一定要让内容的层叠级别相当高。

# 层叠上下文的特点

一个元素在 z 轴方向上的堆叠顺序,是由“层叠上下文”和“层叠级别”这两个因素决定的:

(1)同一个层叠上下文中,我们比较的是“内部元素层叠级别”。层叠级别大的元素显示在上,层叠级别小的元素显示在下。 (2)同一个层叠上下文中,如果两个元素的层叠级别相同(即 z-index 值相同),则后面的元素堆叠在前面元素的上面,遵循“后来者居上”原则。 (3)不同的层叠上下文中,我们比较的是“父级元素层叠级别”。元素显示顺序以“父级层叠上下文”的层叠级别来决定显示的先后顺序,与自身的层叠级别无关。

比如文字环绕效果:一个元素浮动之后,它的层叠级别比普通文档流的块级盒子的层叠级别要高。此时浮动元素会“浮”到上面去,脱离文档流

# [4] BFC 和 IFC

在 CSS 中,页面中任何一个元素都可以看成是一个盒子。在普通文档流(normal flow)中,盒子会参与一种格式上下文(formatting context)。这个盒子可能是块盒子(block-level box),也可能是行内盒子(inline-level box)。一个盒子只能是块盒子或者是行内盒子,不能同时是块盒子又是行内盒子。其中块盒子参与 BFC(块级格式上下文),行内盒子参与 IFC(行级格式上下文)。

# 格式上下文(formatting context)

格式上下文是 W3C CSS2.1 规范中的一个重要概念。它指的是页面中的一块渲染区域,并且这个格式上下文有一套自己的渲染规则。格式上下文决定了其内部元素将如何定位,以及和其他元素之间的关系。

  • 块级格式上下文(Block Formatting Context,BFC)。
  • 行级格式上下文(Inline Formatting Context,IFC)。

# 盒子(box)

盒子,又称 CSS 盒子,是 CSS 布局的基本单位。简单来说,一个页面就是由很多个盒子组成的(具体请参考 CSS 盒子模型)。元素的类型和 display 属性决定了盒子的类型。不同类型的盒子,会参与不同的格式上下文

如下是常见的 display 属性

属性值 说明
inline 行内元素
block 块级元素
inline-block 单元格
table 以表格形式显示,类似 table 元素
table-row 以表格形式显示,类似 tr 元素
table-cell 以表格单元格形式显示,类似 td 元素
none 隐藏元素

# 块盒子

块盒子,即 block-level box。元素类型(即 display 属性)为 block、table、list-item 的元素,会生成块盒子。块盒子会参与块级格式上下文。也就是说,元素类型为 block、table、list-item 的元素都会参与块级格式上下文(BFC)。

# 行内盒子

行内盒子,即 inline-level box。元素类型(即 display 属性)为 inline、inline-block、inline-table 的元素,会生成行内盒子。行内盒子会参与行级格式上下文。也就是说,元素类型为 inline、inline-block、inline-table 的元素都会参与行级格式上下文(IFC)。

除了 block-level box 和 inline-level box 这两种盒子,在 CSS 中还有一个 run-in box 盒子。不过 run-in box 是 CSS3 新增的,在此不介绍。

# BFC

BFC,全称 Block Formatting Context(块级格式上下文)。它是一个独立的渲染区域,只有块盒子(block-level box)参与。块级格式上下文规定了内部的块盒子是如何布局的,并且这个渲染区域与外部区域毫不相关。

# 创建 BFC

W3C 标准中对 BFC 的定义:浮动元素,绝对定位元素(position 为 absolute 或 fixed),元素类型(即 display 属性)为 inline-block、table-caption、table-cell,以及 overflow 属性不为 visible 的元素将会创建一个新的块级格式上下文(BFC)

如果一个元素具备以下任何一个条件,则该元素都会创建一个新的 BFC,也就是说,如果我们要创建一个新的 BFC,只需要在 CSS 中添加上面任意一个属性即可。创建新的 BFC 可以帮助我们解决很多问题

  • 根元素。
  • float 属性除了 none 以外的值,也就是“float:left”和“float:right”。
  • position 属性除了 static 和 relative 以外的值,也就是“position:absolute”和“position:fixed”。
  • overflow 属性除了 visible 以外的值,也就是“overflow:auto”“overflow:hidden”和“overflow:scroll”。
  • 元素类型(即 display 属性)为 inline-block、table-caption、table-cell。

注意一下,根元素也会创建 BFC,在默认情况下一个页面中所有的元素都处于同一个 BFC 中。这是默认的,不需要我们去设置。不过理解这一点对于我们后面理解很多东西十分重要。虽然这些属性都可以创建 BFC,但是也会产生一些效果。如下:

  • float:left 和 float:right 会将元素移到左边或右边,并被其他元素环绕。
  • overflow:hidden 会将超出元素的内容隐藏。
  • overflow:scroll 会产生多余的滚动条。
  • display:table 可能引发响应性问题。

因此如果我们要创建一个 BFC,一定要根据需求来选择最恰当的属性。这里要注意一下,类型为 flex 和 inline-flex 的元素也会创建 BFC,只不过这些是 CSS3 的内容

最开始提到:元素类型(即 display 属性)为 block、table、list-item 的元素,会生成块盒子(block-level box),然后块盒子会参与 BFC。其实从这句话我们已经得到明确答案了:block、table、list-item 等类型的元素的是参与 BFC,而不是创建 BFC。

# BFC 特点

W3C 标准描述 BFC 的特点共有两条:

  • 在一个 BFC 中,盒子从顶端开始垂直一个接着一个地排列,两个相邻盒子之间的垂直间距由 margin 属性决定。在同一个 BFC 中,两个相邻块盒子之间垂直方向上的外边距会叠加。
  • 在一个 BFC 中,每一个盒子的左外边界(margin-left)会紧贴着容器的左边(border-left)(对于从右到左的格式化,则相反),即使存在浮动元素也是如此。 从上面的 W3C 标准定义,我们可以得出以下几点重要结论(非常重要,请字斟句酌地理解记忆)。
  1. 在一个 BFC 内部,盒子会在垂直方向上一个接着一个地排列。
  2. 在一个 BFC 内部,相邻的 margin-top 和 margin-bottom 会叠加。
  3. 在一个 BFC 内部,每一个元素的左外边界会紧贴着包含盒子的左边,即使存在浮动也是如此。
  4. 在一个 BFC 内部,如果存在内部元素是一个新的 BFC,并且存在内部元素是浮动元素。则该 BFC 的区域不会与 float 元素的区域重叠。
  5. BFC 就是页面上的一个隔离的盒子,该盒子内部的子元素不会影响到外面的元素。
  6. 计算一个 BFC 的高度时,其内部浮动元素的高度也会参与计算。

有些新手觉得很奇怪,为什么在一个 BFC 中,盒子会在垂直方向上一个接着一个排列呢?如果在一个 BFC 中有一个盒子是 span 这种行内元素,岂不是不符合了?再次提醒一下,能够参与 BFC 中的盒子是块盒子(block-level box)。就算在这个 BFC 中存在一个行内元素,这个行内元素参与的是 IFC 而不是 BFC,别搞混

# BFC 用用途

上面给大家介绍了 BFC 的特点以及如何创建一个新的 BFC。说了那么多,那 BFC 究竟有什么用呢?BFC 的用途很多,常见的有三个。

  1. 创建 BFC 来避免垂直外边距叠加。

外边距叠加,准确地说,是在同一个 BFC 中,两个相邻的 margin-top 和 margin-bottom 相遇时,这两个外边距将会合并为一个外边距,即“二变一”。其中,叠加之后的外边距高度等于发生叠加之前的两个外边距中最大值。之所以垂直外边距会发生叠加,其实这都是 BFC 的特点

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title></title>
    <style type="text/css">
      #wrapper {
          width: 200px;
          border: 1px solid gray;
          overflow: hidden; /*创建一个新的BFC*/
      }
      #a,
      #b {
          height: 60px;
          line-height: 60px;
          text-align: center;
          font-size: 30px;
          color: White;
          background-color: Purple;
      }
      #a {
        margin-bottom: 20px;
      }
      #b {
        margin-top: 30px;
      }
    </style>
  </head>
  <body>
    <div id="wrapper">
      <div id="a">A</div>
      <div id="b">B</div>
    </div>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

在这个例子中,我们使用“overflow:hidden”为父元素创建一个 BFC,也就是说父元素是一个 BFC 了。因此 A 和 B 位于同一个 BFC 中。。由于在同一个 BFC 中,相邻两个盒子的垂直外边距会叠加,因此 A 和 B 的垂直距离为 30px。 细心的小伙伴们就有疑问了:我不给父元素添加“overflow:hidden”来创建新的 BFC,垂直外边距也会发生叠加,这是什么情况?大家别忘了根元素本身就是一个 BFC,如果我们没有为父元素创建 BFC,则默认情况下 A 和 B 就是处于根元素的 BFC 中。

在实际开发中,如果我们想要避免垂直外边距叠加,怎么办呢?根据第二个结论“同一个 BFC 中,相邻的 margin-top 和 margin-bottom 会叠加”,既然相邻的 margin-top 和 margin-bottom 必须处于同一个 BFC 才会发生叠加,那么我们把这两个元素放在不同的 BFC 中,就可以解决

<style type="text/css">
  #wrapper {
      width: 200px;
      border: 1px solid gray;
      overflow: hidden; /*创建一个BFC*/
  }
  #bfc-box {
      overflow: hidden; /*创建一个BFC,避免外边距叠加*/
  }
  #a,
  #b {
      height: 60px;
      line-height: 60px;
      text-align: center;
      font-size: 30px;
      color: White;
      background-color: Purple;
  }
  #a {
    margin-bottom: 20px;
  }
  #b {
    margin-top: 30px;
  }
</style>
<body>
  <div id="wrapper">
    <div id="a">A</div>
    <div id="bfc-box">
      <div id="b">B</div>
    </div>
  </div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

在这个例子中,A 和 B 处于不同的 BFC,其中 A 处于#wrapper 元素的 BFC 中,B 处于#bfc-box 元素的 BFC 中,所以不会发生垂直外边距叠加。这里注意一下,假如我们不给#bfc-box 元素添加“overflow:hidden”,A 和 B 也会发生垂直外边距叠加。此时 A 和 B 都不属于相邻的元素,它们为什么还会发生外边距叠加呢? 结论:我们再来看看第二个结论“同一个 BFC 中,相邻的 margin-top 和 margin-bottom 会叠加”,这里的相邻不是指“相邻的兄弟元素”,而是指相邻的 margin-top 和 margin-bottom。

(2)创建 BFC 来清除浮动。

们都知道可以使用“overflow:hidden”来清除浮动,但很少知道为什么。根据第六个结论“计算 BFC 的高度时,其内部浮动子元素的高度也会参与计算”可以知道,如果一个元素是一个 BFC,则计算该元素高度的时候,内部浮动子元素的高度也得算进去。

<style type="text/css">
  #wrapper {
      width: 200px;
      border: 1px solid black;
      /* overflow:hidden */

  }
  #first,
  #second {
      width: 80px;
      height: 40px;
      border: 1px solid red;
  }
  #first {
    float: left;
  }
  #second {
    float: right;
  }
</style>
<body>
  <div id="wrapper">
    <div id="first"></div>
    <div id="second"></div>
  </div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

在这个例子中,由于父元素没有定义高度,因此父元素无法把浮动子元素包裹起来,这就会造成父元素高度塌陷。我们给父元素添加overflow:hidden可以解决这个问题,原因如下: 这是因为“overflow:hidden”使得父元素变成了一个 BFC,由于 BFC 在计算它自身高度的时候,会把浮动子元素的高度算进去,因此最终父元素的高度等于浮动子元素的高度。此时就相当于清除了浮动。当然我们也可以通过给父元素添加“display:inline-block”“float:left”等来创建新的 BFC 来实现浮动的清除。

案例二: 不需要文字环绕图片

<style type="text/css">
  #wrapper {
      width: 400px;
      height: 200px;
      border: 1px solid gray;
      padding: 10px;
  }
  img {
    float: left;
  }
  #content {
    background-color: #ffacac;
    /* overflow:hidden */
  }
</style>
<div id="wrapper">
  <img src="images/ailianshuo.jpg" alt="" />
  <div id="content">很多文字...</div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

根据层叠上下文的知识我们知道:一个元素浮动之后,它的层叠级别(stacking level)比普通文档流的块级盒子的层叠级别要高。此时浮动元素会“浮”到上面去,脱离文档流,在这个例子中,我们为#content 元素添加“overflow:hidden”,此时#content 元素变成了一个新的 BFC 根据第四点结论:在一个 BFC 内部,如果存在内部元素是一个新的 BFC,并且存在内部元素是浮动元素,则该 BFC 的区域不会与 float 元素的区域重叠。

(3)创建 BFC 来实现自适应布局。

自适应两列布局,指的是在左右两列中,其中有一列的宽度为自适应,另外一列宽度是固定的。在之前的章节中,我们介绍过使用负 margin 技术来实现自适应左右两列布局。这里我们介绍另外一种实现方式,那就是使用 BFC 创建自适应两列布局

<style type="text/css">
  #sidebar
  {
    float:left;
    width:100px;
    height:150px;
    background:#FF6666;
  }
  #content
  {
    height:200px;
    background-color:#FFCCCC;
    /* overflow:hidden */
  }
</style>
<body>
  <div id="sidebar"></div>
  <div id="content"></div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

上面代码效刚好满足了结论的第三点“在一个BFC中,内部每一个元素的左外边界会紧贴着包含盒子的左边,即使存在浮动也是如此,在这个例子中,我们为#content元素添加“overflow:hidden”,此时#content元素变成了一个新的BFC, 我们改变浏览器的宽度,就很容易可以看出自适应左右两列布局实际效果是怎样的。这个例子跟“BFC 避免文字环绕”的例子是一样的道理。

# 后记

  1. 在前端之路走得更快更远。人生苦短,时间更多应该用来追逐自己喜欢的东西,而不是在一些弯路上白白浪费

  2. 在进阶的学习中,当你为那些高级技巧所折服时,还是要认真说一句:HTML和CSS进阶注重的并不是学到了多少开发技巧,而是学会了代码规范以及性能优化等,毕竟网站的性能与可维护性是才是最重要的

  3. 实际上通过查看别人的源码来学习,也是实践的一部分

Last Updated: 最后更新 2022-12-15 09:58:24