准确理解CSS clear:left/right的含义及实际用途

这篇文章发布于 2014年06月9日,星期一,00:11,归类于 CSS相关。 阅读 121993 次, 今日 3 次 52 条评论

 

零、说点什么

好久没更新了。并不是在折腾什么大作,而是广度学习与实践中,加上婚礼等诸多大事,所以产出较少。

今天这篇也只是小作,博客是自己很好的学习工具,只要我学习不止,博客也会不断更新的。

我们平时一般都使用clear:both清除浮动,貌似就干这一件事件。用得很开心,但似乎理解上懵懵懂懂,我其实也是,早年的时候,测试过CSS clear:left/right,虽知其作用(80%确定而已),但不知其机理。

有必要再次整理下,温故知新。可能很多同行都没有注意left/right值,或者可能理解上含糊,或者不知道其实际意义在何处。So, follow me!

一、理解clear: left/clear: right

我不清楚大家是不是跟我一样,我之前文章,写浮动那一块的时候,以及后来,都是以“clear:both清除浮动”这样的陈述出来的。因此,当想到clear: left的时候,自然会认为是“清除左浮动”,clear: right是清除右浮动。

其实现在想想,这样的理解与表示是不严谨的欠考虑的。

一般,现在中文圈流传的表述是:

clear语法:
clear : none | left | right | both

取值:
none : 默认值。允许两边都可以有浮动对象
left : 不允许左边有浮动对象
right : 不允许右边有浮动对象
both : 不允许有浮动对象

w3.org官方的解释是:「元素盒子的边不能和前面的浮动元素相邻」。

我个人觉得官方解释更好一点。

无论是我“清除左/右浮动”,还是业界流传的“不允许左/右边有浮动对象”,其意思都是,设置的clear的元素让浮动元素如何如何。也就是我让别人如何如何~~大家可以仔细体会,细细感受下……

而官方的说法则是“设置了clear的元素不能怎样怎样”。也就是我自己如何如何~~大家可以再次感受下……

为何官方解释更好呢?难道是“己所不欲勿施于人”的缘故?哈,这个解释赞的,方便记忆。更通俗的原因是:

务必记住这句话:“float是魔鬼,会影响其他相邻元素;但是clear是小白,其只会影响自身,不会对其他相邻元素造成影响!

但是,官方的解释似乎拗口,缺少点灵性。于是,我根据自己的感性认知,做了如下理解:

clear语法:
clear : none | left | right | both

取值:
none : 默认值。
left : 左侧抗浮动
right : 右侧抗浮动
both : 两侧抗浮动

“抗”这个拟人化的动词的发起者是设置了clear属性的元素,既形象又释义准确。

实例出真知
您可以狠狠地点击这里:clear:left/right的作用效果demo

左侧抗浮动

例如上图所示的clear:left作用示意:图片左浮动,化身魔鬼,要影响后面相邻的元素。一般的元素都逃不了被影响被束缚的命运。除非拥有clear技能。例如,这里clear:left左侧抗浮动,也就是,左侧的浮动根本就奈何不了我——我还是原原本本在下面显示。

但是,如果图片是右浮动,则clear:left仍逃不过沦陷的命运,可以看到父级容器的高度塌陷了!

单纯的clear:left就像是招潮蟹,一侧雄起,一侧不举。
招潮蟹

因此,考虑到通用性,在抗浮动的处理中,我们都是使用clear:both. 用意很明显:我不必关心你是左浮动还是右浮动,我都通通免疫。

因此,我们才会有下面这段雕琢后的清除浮动通用CSS:

.fix { *zoom: 1; }
.fix:after { content: ''; display: table; clear: both; }

下面又有问题了,貌似我们接触的clear基本上都是both值,似乎left, right值的出现就是鸡肋,没什么用。真的是这样吗?

二、clear:left/right的实际用途

clear:left/right最实际也是最常见的用途就是实现垂直环绕布局

出个简单的题目,下图所示的布局实现,你的HTML结构会是?
布局

哈,我猜想下,估计你会把“头像img”和“姓名”放在同一个父级容器中,而这个父级容器左浮动;然后右侧的信息元素浮动跟随(自适应布局),对不对?

这是业界主流做法,其实是没什么问题的?

不过,你有没有细细思考过这样一个问题:“为何大家几乎都是这种HTML结构设计?”

实际上,按照我不专业的理解,头像、姓名、自我描述应该是平级的兄弟关系。从语义来看,貌似“头像、姓名”硬生生变成儿子和女儿是不妥的吧~~

当我们只知道票子放银行钱会变多,我们就只会存钱理财。同样的,并不是我们不想尝试其他的结构实现布局,而是,我们不知道方法。说穿了,就是对clear:left/right理解不透,不够重视!

如何“头像”、“姓名”、“自我描述”三兄弟平起平坐,同时达到我们想要的布局效果呢?就是借助clear:left, 半壁clear属性配合float属性可以实现“垂直环绕布局”。

何为“垂直环绕布局”?上面提供的demo中有示意:
垂直环绕布局

两个图片实际上都是右浮动(float: right)的,这种情况下,显然,图片会是一行排排站。但是,如果后面一张图片设置了右侧抗浮动声明:clear: right. 则,后面一张图片就会落下来,形成垂直布局;加上自身的浮动特性依旧存在,于是,两张图片犹如一个浮动整体。这就是典型的“垂直环绕布局”。

于是,我们如下HTML以及CSS,就有符合题目要求的新型布局方式啦!

<div style="width:500px;font-size:12px;overflow:hidden;_zoom:1;">
    <span style="float:left;width:96px;...">头像</span>
    <strong style="float:left;clear:left;...">姓名</strong>
    <p style="margin-left:106px;...">我是一个帅哥……</p>
 </div>
头像姓名

我是一个帅哥……

至此,三兄弟终于平起平坐啦!

更新于2017年1月1日
后来经过我的实践与研究,得到了一个惊人的结论,凡是clear:left或者clear:right起作用的地方,一定可以使用clear:both替换!

原因在于,clear属性是让自身不能和前面的浮动元素相邻,注意这里“前面的”3个字,而float属性要么就left要么就right,不可能同时存在。由于clear属性对“后面的”浮动元素不闻不问,因此,当clear:left有效的时候,clear:right必定无效,也就是此时clear:left等同于设置clear:both,反之亦然。

所以,clear:leftclear:right这两个声明就没有任何使用的价值,至少在CSS世界中是如此,直接使用clear:both吧。

三、结语

没睡午觉,好困哪,年轻时候,这个情境下,一定会附首打油诗,现在,不是没有情致,而是身体hold不住。

二十出头状如牛,文章夜行诗回眸。如今而立渐秃头,结语基本打酱油。

嗯哪,希望本文的点内容能够对您的学习有所帮助,感谢阅读,欢迎交流!

(本篇完)

分享到:


发表评论(目前52 条评论)

  1. yg说道:

    寫的真的最詳細了!不過有一點想問的是span不是inline的嗎?為何能設定width?

  2. echeverra说道:

    能把css研究这么透彻的也只有张鑫旭大神了,受教了。

  3. 无形大象说道:

    不赞同文章后面的一个观点。clear:left 或者 clear:right 和 clear:both 还是有区别的,不可以混为一谈,我记得我以前做过一个效果,就只能用 clear:right , 而不能用 clear:both 。

  4. 小孟说道:

    二十出头状如牛,有错别字哦

  5. 膜拜god-张说道:

    请问,张老师,只有一行文本,或者一行inline水平元素的时候,怎么用text-align:justify
    实现两端对齐呢。
    百度上说,需要这行在末尾加一个空标签,然后设置这个标签为inine-block水平,width:100%;。
    使父级一行变两行。然后父级固定高度,在设置overflow-y:hidden。
    请问有没有更好的方法呢?不加新标签,固定父级高度呢?

  6. 姬荣锋说道:

    文章写得很生动,令我受益匪浅,感谢作者的无私奉献

    但个人对于“惊人的结论”不敢苟同,可以设想以下情况:某元素设置“clear:left”,“前面的元素”选择性设置“float:left”或“float:right”——这时“clear:left”的作用是“clear:both”无法替代的,可见“clear:left”和“clear:right”这两个声明并不是毫无使用价值

  7. Becessary说道:

    =============================================================
    张大大,你好,很容易遇见上面代码的情况;
    理想的:clear:both后,div3 的高度是其内容的所需的高度,这里即:50px;
    但实际情况是,clear后,div3的高度更高。
    不是很理解这种情况;

  8. saber说道:

    讲的不错

  9. 1111说道:

    废话太多,分散读者注意,费力加成

  10. 吴杨捷说道:

    张老师深入浅出,赞!!!

  11. guodaxia说道:

    我这里使用浮动出现一个这样的情况,浮动式针对块级标签的吗?
    .span1{
    float:left;
    }
    .span2
    {
    clear:left;
    }

    122

    上两个和下两个效果不同,为什么?

  12. 傲八码说道:

    三兄弟平起平坐虽然看上去好,但是不能适用于后台管理界面的布局结构,需要考虑到整个body宽度伸缩导致右边(“我是一个帅哥…”)非常难看

  13. spellsnow说道:

    楼主的解析实在风趣到位明细,怒赞!!!!!!!!!!!!!!!!!!!!!!!!!

  14. stalwartwill说道:

    请问为什么具有clear:both元素之后的元素也能“抗”浮动特性?

    然后在这篇文章的垂直环绕布局中,在第二个图片clear:right之后,再加上float:right后,第二个图片之后的内容对第一个图片的float:right却没有了抗性,这个还没能理解

  15. 饭太少说道:

    正在做图片和名称 正好可以用上浮动

  16. 古德God说道:

    学习了!

  17. marge说道:

    这样用浮动,可以减少许多不必要标签,学习了

  18. 淡忘~浅思说道:

    不错的文章 对浮动有了进一步的了解

  19. 三戒说道:

    谢谢!刚好有用到~~~

  20. sunaiwen说道:

    「抗性」的角度挺好的,我尝试复述下博主的想法:虽然你是float:left,但我有clear:left,所以你对我来说float没float都没区别,我还是当你是平常的块元素,哥哥还是按正常文档流的规矩排在你下面。

  21. cnsnake11说道:

    想法真是棒。

  22. 潇洒哥说道:

    赞一个,喜欢博主的谦虚及对技术的不断追求。

  23. 馍馍币说道:

    如今而立渐秃头,评论也是基本打酱油

  24. test说道:

    这个”抗性”确实生动形象,但说clear是小白,如何解释父容器高度恢复现象呢?

  25. 孟辛棠说道:

    你把中间那个clear:left改成clear:both;结果也一样。所以 clear:left的作用不在这里

    • hal说道:

      必须赞,看博客就是要有批判精神。碰巧我几天前了解到朴灵痛批阮老师的那件事…

    • spike说道:


      因为之前没有float:right的元素 只有在右侧也需要浮动元素的时候才会有区别
      所以这里的确没有差别

  26. 小小世界说道:

    谢谢分享~ 我之前碰到过对一个元素同时设置 float:left; 和 clear:left; , 在IE7 下会有一些问题,clear 的效果与想象中的有些差距。

    例如:

    在Firefox 上的效果是:第1,2张照片在第一行,第3,4张照片在第二行
    而在IE7上的效果则是:第1,2,4张照片在第一行,第3张照片在第二行。

  27. 子非鱼说道:

    不错的文章~ 新婚快乐!

  28. 窍门天下说道:

    浮动博大精深

  29. SJY说道:

    博主又谦虚了,结尾的打油诗不是出来了么?

  30. 袁梓民说道:

    新婚快乐 哈哈

  31. 叶小钗说道:

    HI,张老师,
    我们在做移动开发过程中遇到了两个顽固的问题:
    ① ios虚拟键盘弹出导致fixed元素错误
    ② webapp 切换时候长短页问题以及卡的问题

    以上我尝试使用IScroll方案解决,在具体应用过程中发现ios中会有:
    光标闪动,滑动时候文本框消失,文字改变input回到视口处,但由于overflow不可见问题

    而,我本身做了一些解决方案,但是今天在无意间使用了一个办法可以解决此问题,这里想请教一下
    我在文本框获得焦点时候给body设置了window的高度,这个时候光标闪动等问题没了
    原因是我滑动时候便是滑动的系统的区域而不是IScroll区域,由此我有一个疑问:
    是不是虚拟键盘出现时(文本框获得焦点时),我们滑动的是外部body区域而不可滑动元素区域
    对应两个demo:
    http://sandbox.runjs.cn/show/60dgkyl5(有BUG版本)
    http://sandbox.runjs.cn/show/5qpjedsv(解决版本)

    因为老师对移动端的经验比较丰富,不知是否碰到过类似问题,若是老师知道原因,有时间的时候可否为我解疑

    • 张 鑫旭说道:

      @叶小钗 我打杂的,移动端的经验不算丰富,对于你的问题,我只能“呵呵”~

    • leer说道:

      增加老滚4的参数,让其内部区域获得焦点
      因为屏蔽监听输入事件可以提高滚动性能
      onBeforeScrollStart: function (e) { var target = e.target; while (target.nodeType != 1) target = target.parentNode; if (target.tagName != ‘SELECT’ && target.tagName != ‘INPUT’ && target.tagName != ‘TEXTAREA’) e.preventDefault(); }

  32. 小万说道:

    招潮蟹, 太有想象力了!!!很棒的文章!

  33. 晓林哥说道:

    博主的文学素养和对技术的至高追求着实让我等惭愧之极。

  34. julytian说道:

    风趣文章,顺便祝贺“新婚快乐”

  35. 非前端说道:

    基本是潜水选手。但看见要结婚了,恭喜恭喜

  36. 要结婚啦.恭喜恭喜,又多了一个脱单的程序员啦.

  37. merices说道:

    不错~ 赞一个

  38. 春和水水子说道:

    顺道来一句…:”恭喜恭喜,新婚快乐!!”嘻嘻^_^

  39. 春和水水子说道:

    感谢你每一次的分享~~

  40. 杨小爷说道:

    以前还真就是按照你说的那种包2个容器浮动的,看来以后又可以精简布局了~谢谢~

  41. Bravo说道:

    学习到啦~

  42. vajoy说道:

    学习啦感谢。不过也开始担心我以后的三十岁会hold不住了呀啧啧