当前位置: 首页 > Web前端 > CSS

深入研究cssfloat

时间:2023-03-30 15:17:12 CSS

去年看到了张新旭的这篇文章,看了好几遍才看懂。后来想了一些道理,又忘记了。所以打算写下来,一是做个备份,二是希望与大家分享。这里我根据自己的理解对文章做了一些简化。完整版可以去http://www.zhangxinxu.com/wor...在这里可以看到浮动的本质:wrapping和destructivewrapping:另一种说法就是让元素内联——堵塞。例如,div标签的默认宽度显示为100%,但一旦设置了浮动,100%默认宽度将成为自适应内部元素的宽度。float其实是一个破坏性的display:inline-block属性,带有direction:要想理解浮动的破坏性,还得从浮动最原始的意义说起。浮动的意思其实就是让文字包围图片而已,仅此而已。float之所以会把带有float属性的图片包围起来,是因为float破坏了正常的lineboxes。让我们先来了解一下lineboxes模型。先看下面一段普通的HTML代码:

这是一行普通的文字,这里是一个em标签。

代码中的4种框(从内到外):内联框:?内联框不会分块显示内容,而是排成一行。如果外部标签包含内联属性(span、a、cite等),则属于内联框。如果是纯文本,则属于匿名内联框。文本不可见的box.content区域的大小与font-size的大小有关。包含框:p标签所在的包含框。此框包含其他框。为什么浮动可以让文字环绕图片?默认情况下,图文混合布局应该是这样的:图文基线对齐,图文在同一行,如下图:在上图中,图片是一个内联框,两边的文字也是内联框。由于lineboxes的高度是由里面最高的inlineboxes的高度决定的,所以这里lineboxes的高度就是图片的高度。此时图片和文字是同一个框类型的元素,在同一行。因此,默认情况下,图像只能与一行文本对齐。而如果你想让一张图片与多行文字对齐,你唯一能做的就是破坏正常的lineboxes模型。包含floating属性的图片和文字首先看一下添加float:left样式后图片的表现,见下图:一般情况下,图片本身就是一个inline-boxes,加上两者上的文字inline-boxessides来形成line-boxes,但是一旦将图片添加到float中,情况就完全不同了。浮动完全破坏了图片的行内框特征。至少有一件事是肯定的,图片的行内框不存在。图片一旦失去行内框的特性,就无法与行内框的文字对齐。从-boxes中分离出来,遵循它自己的方向属性,并横向排列。这个脱离lineboxes的浮动元素,其实就是一个body,一个空壳,一个appearance。因为它没有行内框。可能有人会问,没有inlinebox就没有呗,有什么大不了的?不,不!这个inlineboxes是一个很重要的概念。为什么行内框很重要?在现在的CSS世界里,所有的高度都是由两个CSS模型生成的,一个是box模型,对应的CSS是“height+padding+margin”,一个是linebox模型,对应的样式是“line-height””。前者的高度属性分为明显高度值和隐藏高度值。所谓隐藏高度值,就是指图片的高度。图片加载后,即使你看不到它的固有高度值也会生效height后者针对的是文本等内联框等元素(图片也属于内联框,但是它们的高度更强大比line-height高,所以他们的inlineboxes的高度等于自己的高度,没有响应line-height),inlineboxes的高度直接由line-height控制(这就是改变line-height的原因texttostretchoroverlap),而真正的高度表现是由每行中的许多inlineboxes组成的lineboxes(等于内部最高的inlinebox的高度),这些lineboxes的高度垂直堆叠形成containingbox的height,也就是我们看到的div或者p标签的高度。因此,对于linebox模型的元素来说,没有inlineBoxes,没有height,而floating就干了这么讨厌的事,它直接破坏了元素的行内框t,所以这些元素没有高度,按照上图的例子。浮动破坏了图片的inlinebox,导致两种结果:一是图片不能和文字一起显示,脱离了它原来的linebox链;另一种是没有高度(noinlinebox->nolinebox->nohigh)。而这些结果正是显示文字换行图像需要文字换行图像的原因。这里有一个动画,可以帮助我们理解图片文字环绕的原因:http://image.zhangxinxu.com/f.,“包裹和破坏”!wrap是横向缩小label占用的空间,destruction是销毁inlinebox。上面解释过,inlineboxes是高度形成的基础,如果floating破坏了inlineboxes,那么高度就没有了。正是因为浮动元素没有内联盒和内联盒的高度,所以其他内联盒元素可以重新整合排列在浮动元素周围。我们现在假设浮动不会破坏inlineboxes,所以图片虽然会显示在左边,但是会和文字形成一个新的高度包络(类似聚合),只能形成一个linebox一行文字,无法实现文字环绕效果,所以浮动会破坏内联框。floatvs绝对定位(absolute)理解了float之后,我们再来对比一下绝对定位和浮动元素。绝对定位元素也是“环绕式”和“破坏式”的,适用于任何元素。那么它们之间有什么区别呢?当使用float离开文档流时,其他盒子会忽略这个元素,但其他盒子里的文字仍然会让位给这个元素并环绕。对于使用absolute离开文档流的元素,其他框和其他框中的文本将忽略它。由此造成的显示差异是:文档流中的文本实体不会与浮动元素重叠,而是与绝对定位元素重叠。这是文字环绕显示的重要原因之一:虽然图片实际占用的高度为0,但由于其宽度实体(wrapping)的存在,同为内容区域实体的文字不会与其重叠(externalcontainerboxcontainingbox(p,div,ul,li)会重叠),这就像一个植物人站在篮球场上,虽然几乎不可能得分,运球等,但他的实体就在那里,它可以阻挡同一个水平空间的同类个体(也就是人)直接通过,想要通过就得绕道而行。但这并不能阻止整个团队前进的步伐。每次读这篇文章,我都有不同的感悟。张新旭老师对很多问题的理解非常深刻和独到,非常欣赏他的文章。本文还有几个知识点需要深入理解,比如cssline-height的一些深入理解和应用,绝对深入理解系列,我会找时间整理一下,有兴趣的小伙伴也可以往下阅读