资讯专栏INFORMATION COLUMN

CSS魔法堂:说说Float那个被埋没的志向

legendmohe / 1479人阅读

摘要:时其宽度始终保持占满宽度的态度。清除浮动就是为浮动影响的范围划边界。那么可归结为的父容器包裹所有子元素。注意属性值不能为空白,否则无法清除浮动。

前言

 定位系统中第一难理解就是Normal flow,而第二就非Float莫属了,而Float难理解的原因有俩,1. 一开头我们就用错了;2. 它跟Normal flow靠得太近了。本文尝试理清Float的特性和行为特征,若有纰漏望各位指正。

被埋没的志向——文字环绕

 回忆一下我们一般什么时候会想用浮动呢?是多列布局还是多列布局呢:)?其实它向往的却是这个

 它想干的就是这个——文字环绕,而且CSS2中除了浮动外没有其他属性可实现上述的效果。
 那到底如何理解它的实现原理呢?下面我们采取分步剖析的方式来深入探讨吧!

切断关联看Float

"float"
Value: left | right | none | inherit
Initial: none
Applies to: all
Inherited: no
 当设置float:left后,元素对应的margin left edge会尽可能向所属的containing block的左边框靠近,若同一行中存在位于左侧的元素设置了float:left,则即会尽可能向该兄弟元素的margin right edge靠近.


(由于float:left突出不了效果,因此采用float:right作例子。其中蓝色区域就是containing block范围,绿和红色块采用向右浮动)
 当设置浮动后,display:inline的实际值将被改写为display:block,因此不要再为display:inline;height:100px;line-height:0;float:left导致盒子content height为100px感到惊讶了。也不要为即使剩余空间不足以存放整个display:inline;float:left盒子,导致整个盒子下移到下一行排版而惊讶了.(若为Normal flow则会根据white-spacing、word-wrap和word-break决定盒子内部分内容换行,而不是整个盒子换行)简单来说并不是float:left让盒子具有不为五斗米折腰的气质,而是display:block的功劳,又由于浮动的盒子会以水平方向排版,因此我们可以以display:inline-block来理解浮动定位的水平排版和换行行为。

I"m span I"m span too


 当设置浮动后,虽然display的实际值为block但就width:auto而言,我认为display更像是采用inline-block,宽度由子元素决定。这就是包裹性了!
(float:right同理,只是方向不同而已)
注意:在仅考虑浮动元素本身的前提下,float:left的效果与display:inline-block而父容器direction:ltr的效果是一样的,不同的是浮动元素不纳入父容器高度的计算当中

float:left


float:none

头痛的开始——基于Normal flow看Float

 用割裂的方式理解float并不难,难就难在结合Normal flow看Float。下面我们一起来探讨吧!警告,前方高能,前方高能!!

以Normal flow为基础

 不管是Absolute positioning还是Float均以Normal flow作为定位基础,也就是说先假设有一个虚拟盒子以Normal flow进行定位,然后在这个基础上添加Float的特性并影响其他盒子的布局。而浮动定位对于盒子自身而言仅影响其在水平方向上的定位,因此对于inline-level box而言其垂直方向上的定位并没有发生变化,而对于block-level box而言因Collapsing margins的失效有可能会引起垂直方向上的移动。

float:left

值得注意的是,浮动定位的虚拟盒子实际上是不占空间的。因此才有后续的浮动闭合和清除浮动的事。

压榨line box


 文字环绕很明显就是活生生地把文字向两边挤,为"大哥"留下个位置,而且小弟们不要走太远,必须时刻拥护着大哥。那大哥是如何圈住小弟们的呢?那得借助外力——line box。文字是以字形(glyph)的形式渲染,和它同一行的inline-level boxes均位于同一个line box中。而line box可谓是夹在containing block和浮动盒子之间勉强生存。

These days it takes a diverse and complex collection of components to power a web browser. It’s fair to think of all those parts coming together as a single piece of machinery, and we often talk about our web platform as an “engine”.

 若line box的宽度不足以容纳glyph和inline-level boxes时,会在下方产生N个新的line boxes并在必要时拆分inline-level boxes,然后将glyph和inline-level boxes分布到各行的line boxes当中。

脚踩block-level box

 相对line box,block-level box就显得不屈不挠了。width:auto时其宽度始终保持占满containing block宽度的态度。但位于同一个stacking context中的浮动定位的盒子虽然和常规流中的盒子拥有相同的z-index(都是auto),但浮动定位的盒子拥有额外的优先级,导致它总位于常规流中的盒子之上。(关于分层显示的内容可参考《CSS魔法堂:你真的理解z-index吗?》)

float:left
通过创建BFC翻身做主人

 同样是盒子,为啥你就可以在我上面呢?你有Float罩着,我也找弄个新的BFC来跟你抗衡。我们知道通过float:left|rightposition:absolute|fixeddisplay:inline-block|table-cell|table|table-captionoverflow:auto|scroll|hidden均可让盒子产生新的BFC。而产生BFC的盒子间天生排斥彼此。(但可通过后天的努力position:relative让他们又互有交集^_^)
 那现在的问题是采用Normal flow定位模式的会产生新的BFC的盒子到底是紧跟在Float定位盒子的后面,还是另起一行呢?答案是两者都有可能,具体看剩余的宽度是否足以容纳该盒子。其实就是如同设置父容器产生BFC,而该盒子采用Float定位模式。不信,你看

float:left

是"浮动闭合"还是"清除浮动"?

 我想各位都看过各种版本的clearfix实现,而最简单粗暴的方式就是添加一个

来清除浮动。我还听过另一个名称——"浮动闭合",那到底两者有什么区别呢?在作区分之前我们先要明确问题的本身。
 对于height:auto的容器而言,我们希望它能恰好包裹着所有子元素,但不幸的是采用浮动定位模式的子元素将不纳入父容器的高度计算当中,那就会出现子元素戳穿父容器的风险。
 从之前的内容我们了解到文字和inline-level boxes会环绕Float定位的盒子,而block-level box则被它踩在脚下。但现在希望后续盒子不再与Float定位的盒子有任何瓜葛。
 面对这两种需求,我们分别得出"浮动闭合"和"清除浮动"两套方案。

浮动闭合

 就是让height:auto的父容器包裹所有子元素,包括Float定位的子元素。方式很简单,就是好让父容器产生BFC。

清除浮动

 就是为浮动影响的范围划边界。方式也很简单,就是以一个clear:left|right|both的盒子作为边界即可,其实就是引入空隙(clearance)。
 首先clear属性仅对block-level box有效clear:left表示盒子的margin-left-edge不与浮动盒子接触,而clear:right表示盒子的margin-right-edage不与浮动盒子接触,clear:both自然是左右两条margin-edge均不与浮动盒子接触啦。有点虚,直接看疗效吧!

float:left
clear:left
float:right
clear:right

 简单地说就是float:leftclear:left来清除,float:rightclear:right来清除。而我们会发现一个怪异的现象,那就是设置clear:left|right|both的盒子的border top edge紧接着Float定位盒子的margin bottom edge,其实这是clearance来作祟。当设置clear:left|right|both的盒子A的border top edge与Float定位盒子B的margin box重叠时,那么就会在A的margin box和border top edge之间引入clearance,恰好让A的的border top edge恰好不与B的margin bottom edge重叠。

.clearfix方案

 不管是浮动闭合也好,清除浮动也罢,我们的目的往往是两者结合——Float定位的范围与Normal flow定位的范围分明,且采用Normal flow的父容器包裹所有子元素。那么可归结为Normal flow的父容器包裹所有子元素。因此得到如下的HTML Markup

而具体的方案如下:
方案1

.clearfix::after{
  content: ".";
  display: block;
  clear: both;
  line-height: 0;
  visibility: hidden;
}
.clearfix{
  *zoom: 1; /*for IE5.5/6/7*/
}

伪元素after表示创建一个display:block,innerText是content属性值的元素作为该元素的最后一个子元素。注意content属性值不能为空白,否则无法清除浮动。
方案2

.clearfix::after{
  content: "u200B"; /*通过零宽空白字符,省略visibility属性*/
  display: block;
  clear: both;
  line-height: 0;
}
.clearfix{
  *zoom: 1; /*for IE5.5/6/7*/
}

注意:若页面不是采用UTF-8编码方式,那么u200B表示的将不是零宽空白字符,从而导致方案2出问题。
方案3
由Nicolas Gallagher大湿提出的

.clearfix::before, .clearfix::after{
  content: "";
  display:table;
}
.clearfix::after{
  clear: both;
}
.clearfix{
  *zoom: 1; /*for IE5.5/6/7*/
}

这里有2个奇妙的地方:

通过display:table让即使content为空白时,也能独占据一行,且高度为0;(原理是display:table会生成一个block-level box包裹着伪元素after)

通过伪元素before消除父容器margin-top与第一个Normal flow的子元素的margin-top产生margin collapsing效果。

浮动真的是定位模式的一员吗?

 我们可以通过position属性来设置Normal flow或Absoluting positioning,但却要通过float属性来设置Float,这让我一度怀疑Float到底是不是定位模式的一员呢?
 我是这样理解的,Normal flow(包括Relative positioning)与Absoluting positioning是非我即你的关系,而Float和Relative positioning则是可叠加影响定位效果的关系,显然必须另设一个属性来设置更恰当。

期待更美的文字环绕

 有没有发现通过float:left|right我们仅能得到要么图片靠左要么图片靠右的文字环绕效果,那如果我们希望得到如下的四周环绕的效果呢?

 虽然已有案例是通过absolute positioning模拟出类似的效果,但布局排版固定导致无法适应大部分场景。如果有个float:both属性值那该多好啊!另外大家是否觉得以下的环绕效果更有艺术范呢?

 听说通过CSS3的shapes特性可以实现四周环绕和上面非四四方方的环绕效果,日后好好研究研究!
2016/04/19补充-参考《CSS网站布局实录-基于Web标准的网站设计指南(第2版)》的5.2.2 不规则文字环绕


初中时候语文老师说我会是个写作天才,因为我写的东西足够真实,取材身边,造句简单,用语文书垫桌脚的同时翻烂了韩寒的1988,那时督促我已经成为她的习惯。时至今日再次遇见语文老师时候我惭愧的告诉她我已经不写文了,也没有像她说的那样成为一个天才,我只能微微一笑告诉她我至少还没停下笔。
总结

重构了几次总算写完了,想写得清楚而又不哆嗦真心不易,继续努力:)
尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/5375753.html^_^肥子John

感谢

KB011: 浮动(Floats)
KB009: CSS 定位体系概述
CS001: 清理浮动的几种方法以及对应规范说明
CSS float浮动的深入研究、详解及拓展(一)
CSS float浮动的深入研究、详解及拓展(二)
https://www.w3.org/TR/CSS2/visuren.html#flow-control
CS001: 清理浮动的几种方法以及对应规范说明
Faking ‘float: center’ with Pseudo Elements
说说标准——CSS核心可视化格式模型(visual formatting model)之十:控制紧接浮动的排列-clear 特性
那些年我们一起清除过的浮动

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/115173.html

相关文章

  • CSS魔法:小结一下Box Model与Positioning Scheme

    摘要:魔法堂重新认识和魔法堂你一定误解过的魔法堂就这个样魔法堂说说那个被埋没的志向深入细节后会发现中定位模式之间,和之间存在千丝万缕的关系,必须以俯瞰的角度捋一下。当采用时,属性的实际值会被重置为。由于和则需要通过来引入来提供盒子定位微调的功能。 前言  对于Box Model和Positioning Scheme中3种定位模式的细节,已经通过以下几篇文章记录了我对其的理解和思考。 《CSS...

    szysky 评论0 收藏0
  • CSS魔法:"那不是bug,是你不懂我!" by inline-block

    摘要:那不是,是我不懂而已。的用途之一西文是以空格来分隔单词的,而汉字间则无需空格分隔,但为了统一西文东亚和的排版,于是抽象出一个名为的概念用于分隔词义单元,则作为的值域,而定义域就是语言信息。 前言 每当来个需要既要水平排版又要设置固定高宽时,我就会想起display:inline-block,还有为了支持IE5.5/6/7的hack*display:inline;*zoom:1;。然后发...

    cucumber 评论0 收藏0
  • CSS3魔法说说Multi-column Layout

    摘要:注意会生成新的,因此不会出现效果。图中蓝色线框,位于内,作为间的分隔线。不可否认求学之路的艰辛苦闷。如此的努力,为了仅仅是能在大学逍遥快活一番这动机实在让人心寒,也正因如此造就了大学生的堕落。人类文明进步最有力的证明。 前言  是否记得《读者文摘》中那一篇篇优美感人的文章呢?那除了文章内容外,还记得那报刊、杂志独有的多栏布局吗? 当我们希望将报刊、杂志中的阅读体验迁移到网页上时,最简单...

    gitmilk 评论0 收藏0
  • CSS魔法:你一定误解过Normal flow

    摘要:后来终于知道是某位大神将翻译为文档流而已。。。。。。另外单纯设置效果与采用是一样的魔法堂就这个样,而浮动定位也是基于。相对定位的最强武器就是个属性了,好明显它们默认值均是。 前言  刚接触CSS时经常听到看到一个词文档流,那到底什么是文档流呢?然后会看到绝对定位和浮动定位能脱离文档流,从这句可以看到文档流和绝对定位、浮动定位是同一个范畴的概念,再后来在W3C标准文档找到关于Absolu...

    Hancock_Xu 评论0 收藏0
  • CSS魔法:重拾Border之——不仅仅是圆角

    摘要:撸代码实现首页检验单查询成品通用标准审核圆角的何止是啊上图的变成椭圆形了,而且中的文字好像飘到外面。我们可以看到两边相交所形成的矩形的对角线,将作为边的相交点。 前言  当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-top-left/right...

    _Dreams 评论0 收藏0

发表评论

0条评论

legendmohe

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<