CSS 当中的 float

CSS 当中的 float

算是一篇系列文章吧,主要涉及到 CSS 当中的 floatdisplaypositionvertical-alignline-height 这几个属性,因为在平常开发当中也只是拿来使用,并没有十分深入的去了解它们,所以就打算在这里从头开始慢慢的梳理一遍,也当是复习复习了,我们就先从 float 开始

特性

CSS 中,是存在流的概念的,在正常情况下页面总是从左到右,从上到下布局,这种被称为正常的流,但是有很多情况,正常流是没办法实现的,因此我们需要一些手段来破坏流,从而实现一些特殊的布局,而本节的主角 float 就具备破坏流的特性

在还是新手阶段的时候,我们通常在布局的时候,总喜欢用 float 来实现,例如一个三栏布局,左右固定,中间自适应,则会通过 float 来一列一列把它们砌起来,这样的布局看上去是实现了目的,但是也是极其容易崩溃,只要高度或者宽度稍微有些变化,整个页面都会错乱,这是因为 float 的设计初衷并不是用来布局的,其本意仅仅是实现图片文字环绕效果,即图片左浮动,文字环绕图片,也就是下面这样的效果

一个元素如果设置了 float 属性,它会表现出如下特性

  • 包裹性
  • 块状化
  • 高度塌陷
  • 没有 margin 合并

其中的高度塌陷和没有 margin 合并的内容我们在之前的 BFC 章节当中都已经详细介绍过了,所以这里就不在展开了,详细内容可以参考链接,所以这里我们只介绍包裹性和块状化两个特性

包裹性

包裹性包含了包裹和自适应两个特性,包裹指的是一个浮动元素,如果子元素宽度足够小,则浮动元素的宽度就是该子元素的宽度,比如下面这个例子

1
2
3
<p style="float:left;">
<span>这是浮动元素的子元素</span>
</p>

运行以后可以发现,父元素 p 的宽度就是它的子元素 span 的宽度,也就是说父元素是将子元素 span 给包裹了起来,而自适应指的是如果浮动元素的父元素有设置宽度,并且浮动元素的子元素宽度超出了父元素,则浮动元素的宽度最终表现为父元素的宽度,如下

1
2
3
4
5
<div style="width:100px;">
<p style="float:left;">
<span>这是浮动元素的子元素</span>
</p>
</div>

运行以后可以发现,浮动的元素 p 的宽度和父元素一样也是 100px

块状化

块状化的意思是,一旦元素 float 的属性不为 none,则其 display 计算值就是 block 或者 table,举个例子,我们使用 JavaScript 来进行测试,如下

1
2
3
4
5
6
7
var span = document.createElement('span')
document.body.appendChild(span)

console.log('1.' + window.getComputedStyle(span).display) // inline

span.style.cssFloat = 'left'
console.log('2.' + window.getComputedStyle(span).display) // block

运行完了以后观察两者的输出值可以发现这里存在一个问题,既然元素设置 float 后,元素就块状化了,那么怎么还能产生包裹性的效果呢?要回答这个问题,需要重新阐述下块状化的意思,这里的块状化意思是可以像 block 元素一样设置宽和高,但并不是真正的块元素,因此下面这些属性是多余的,并且如果你使用的代码编辑器有提示功能的话,它也会提示你存在多余这个问题

1
2
3
4
5
6
7
8
9
span {
display: block; /* 多余属性 */
float: left;
}

div {
float: left;
vertical-align: middle; /* 多余属性 */
}

作用机制

我们还是以之前的例子来进行了解

1
2
3
4
<div>
<span>标题</span>
<a style="float:right">链接</a>
</div>

这个页面展示的情况我们已经知晓,即在标准浏览器下,标题会和链接在同一行展示,并且链接会浮动在右边,但是如果标题非常长,一行放不下呢,链接是浮动在第一行还是第二行呢?答案是第二行,要想解释这个,我们得先理解两个概念,一个是浮动锚点,一个是浮动参考

  • 浮动锚点是 float 元素所在的流中的一个点,这个点本身并不浮动,表现得就像是一个没有 marginpaddingborder 的空的内联元素
  • 浮动参考指的是浮动元素对齐参考的实体

float 元素的浮动参考是行框盒子,也就是 float 元素在当前行框盒子内定位,因此上面的例子链接会在第二行展示,但是也有一种情况是,浮动元素前后并没有内联元素,因此也就不存在行框盒子,这时候就是浮动锚点在起作用,因为浮动锚点表现得像一个内联元素,有内联元素,自然就有行框盒子,只是这个盒子看不见也摸不着罢了

# CSS

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×