欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于CSS清理的实例教程

程序员文章站 2022-04-20 09:08:18
清理 虽然浮动可以便于页面布局,但同时会产生一些问题,也就是常说的副作用。浮动元素最常见的缺陷是:父元素的高度塌陷和影响兄弟元素的位置。 首先,看看父元素的高度塌陷。假设有一个...

清理

虽然浮动可以便于页面布局,但同时会产生一些问题,也就是常说的副作用。浮动元素最常见的缺陷是:父元素的高度塌陷和影响兄弟元素的位置。

首先,看看父元素的高度塌陷。假设有一个容器,其中两个子元素,一个子元素向左浮动,一个子元素向右浮动。代码如下:

.wrapper {

border: 2px dashed #ccc;

}

.wrapper > p {

width: 80px;

height: 60px;

border: 1px dashed #444;

}

.floatL {

float: left;

}

.floatR {

float: right;

}

box1

box2

上述容器 wrapper 的高度为auto,且只包含浮动元素。由于浮动元素脱离了文档流,因此,容器 wrapper 就相当于一个空标签,其高度就会塌陷为零,使得浮动元素溢出到容器外面。如图 529 所示:

关于CSS清理的实例教程

图5-29 浮动导致容器高度塌陷

这种塌陷会影响、甚至破坏布局,如果父元素没有边框,也不包含任何可见背景,这个问题就很难被注意到,但它却是一个很重要的问题。

再来看看浮动元素如何影响兄弟元素的位置。当容器的高度为 auto,且只包含浮动元素时,如果浮动元素的高度不相同,而剩余空间足够容纳后面的元素时,后面的元素就会上跳到剩余的空间。代码如下:

.wrapper {

border: 2px dashed #ccc;

}

main {

float: left;

}

aside {

float: right;

}

footer {

float: left;

}

main

aside

footer

上述的布局为两栏布局,主栏向左浮动,侧栏向右浮动,并且侧栏的高度小于主栏的高度。页脚便会上跳到侧栏的剩余空间。如图 530 所示:

关于CSS清理的实例教程DB2tSqy9jJz8z4" height="136" src="/uploadfile/Collfiles/20180222/20180222091355174.png" width="408" />

图5-30 浮动使相邻元素上跳

很显然,无论是高度塌陷,还是影响兄弟元素的位置,都不是使用浮动的目的。浮动只是为了改变元素的布局,却造成了不必要的影响。因此,需要清除浮动带来的影响。

CSS中,把清除浮动影响所进行的处理,叫做清理浮动(或清除浮动)。一般有两种处理思路:使用 clear属性和让容器创建一个BFC。

每种思路中都包含多种方法,但并不是每一种方法都尽善尽美,接下来简单介绍这些方法的原理及适用场合,可以根据实际情况,选择合适的方法。

使用 clear属性

CSS中的 clear属性,用来规定在元素的哪一侧不允许出现浮动元素,可选值有 none | left | right | both,默认值为 none,表示不清除,左右两侧均允许出现浮动元素。left 表示清除左侧,在左侧不允许出现浮动元素;right 表示清除右侧,在右侧不允许出现浮动元素;both 表示清除两侧,左右两侧均不允许出现浮动元素。

1)使用带clear属性的空元素

这也是W3C推荐使用的方法,首先在CSS中定义一个清理的 class,然后在浮动元素的后面,使用一个空元素

。如:

.clear {

clear: both;

}

box1

box2

这种方法的优点是简单、代码少、浏览器兼容性好。但是,需要添加无语义的html元素,违背了表现和内容相分离的原则,代码不够优雅,增加了后期维护的难度。

2)借用邻接元素处理

什么都不做,给浮动元素后面的那个元素添加 clear属性。假如在浮动元素后面有一个 p 元素,可以为 p 元素添加 clear属性,来间接清除浮动。如:

box1

box2

如果你很明确的知道接下来的元素是什么,这个方法很不错,它不需要 hack,不添加额外的元素。但是,使用这种方法,必须确保浮动元素后面确实有元素。如果没有元素,巧妇难为无米之炊,也没有办法。

3)使用CSS的 :after 伪元素

结合 :after 伪元素(注意这不是伪类,而是伪元素,代表一个元素之后最近的元素)和触发布局的 IE hack,可以完美兼容当前各大主流浏览器。

给包含浮动元素的容器添加一个 clearfix 的 class,然后给这个 class 添加一个 :after 伪元素,在元素末尾添加一个看不见的块元素,让这个块元素来清除浮动。

.clearfix:after {

content: ".";

clear: both;

display: block;

height: 0;

visibility: hidden;

}

box1

box2

通过CSS伪元素,在容器的末尾,插入一个点 ".",然后通过 height 和 visbility 属性使其不可见,再为插入的点设置 clear属性来清除浮动,其原理跟上述两种方法类似。

事实上,上述方法插入任何内容,都可以清除浮动。当然,如果插入一个空格的话,就不必设置 height 和 visbility 属性,代码会跟简洁。如:

.clearfix:after {

content: "";

clear: both;

display: block;

}

需要注意的是,由于IE7及以下的版本不支持 :after 伪元素,因此还需要为 .clearfix 设置width、或 height、或 zoom 等一系列属性,来触发布局(即,使IE私有属性 hasLayout 的值为 true)。如:

.clearfix {

*zoom: 1;

}

在这些属性值中,zoom 用于设置元素的缩放比例,取值 1 就会使用元素的实际尺寸。因此,使用 zoom: 1 既可以触发布局,又不会对元素造成其他影响,相对而言比较安全。

让容器创建BFC

可以利用BFC特性,来清除浮动。准确的讲,说清除浮动不太合适,应该说是让容器创建一个BFC,来包含浮动元素。可以为容器设置以下属性,来创建一个新的BFC,间接实现清除浮动的效果:

float: left | right

position: absolute | fixed

overflow: hidden | auto | scroll

display: inline-block | table-cell | table | flex | inline-flex

虽然设置上述属性都可以创建BFC,实现清除浮动的效果,但是,float、position、display 属性可能会影响整体布局。因此,最常用的还是设置 overflow 属性。

1)让容器浮动

让容器浮动后,容器就会创建一个新的BFC,使它可以包含浮动元素。计算BFC的高度时,浮动子元素也参与计算。因此,容器的高度就表现正常,其他框的位置也就正常了。

.wrapper {

float: left;

border: 2px dashed #ccc;

}

让容器浮动后,容器的高度确实没有塌陷,但是,容器的宽度可能会发生变化,因为浮动元素的宽度是有其内容决定的(显式设置 width 属性者除外),这可能会影响整体布局。

2)为容器添加 position 属性

如果为容器设置 position: absolute 或 position: fixed,容器就会创建一个新的BFC,使它可以包含浮动元素。

.wrapper {

position: absolute;

border: 2px dashed #ccc;

}

另外,由于IE7及以下的版本不支持BFC,还需要触发布局。设置 position: absolute,IE6和IE7都可以触发布局。但是,IE6不支持 position: fixed,还需要为容器设置 zoom: 1,来触发布局。

3)为容器添加 overflow 属性

如果为容器设置 overflow: hidden 或 overflow: auto,容器就会创建一个新的BFC,使它可以包含浮动元素。

.wrapper {

overflow: hidden;

border: 2px dashed #ccc;

}

另外,由于IE7及以下的版本不支持BFC,还需要触发布局。在IE7中,把 overflow属性设置为 visible 之外的值,就可以触发布局,IE6则不行。因此,在IE6中,可以为容器设置 zoom: 1,来触发布局。

这个方法不需要额外元素,有着较好的语义性,也比较简单。但是,需要要记住,overflow 属性不是为清除浮动而定义的,注意不要隐藏了不该隐藏的内容或触发了不必要的滚动条。

说明:BFC 与 hasLayout

从表现上来说,hasLayout 跟 BFC 的功能很相似,只是 hasLayout 自身存在很多问题,导致了 IE6-7 中的一系列 bug。

既然 hasLayout 有着跟 BFC 相似的功能,而 IE7 及以下的版本不支持 BFC。因此,为了避免不同浏览器下的表现差异,在实际开发中,需要创建 BFC 的元素,同时也要触发 hasLayout。

事实上,在实际开发中,很多莫名其妙的问题,都是由此产生的。当然同样地,如果一个元素没有创建 BFC,也要尽量保证它没有触发 hasLayout 。