浮动究竟是作什么呢?他们是如何影响相关元素的盒模型的呢?浮动的元素与内联元素有什么不一样呢?制定浮动元素的位置的具体规则是什么?clear属性是如何工做的,而且它的做用是什么?浏览器
即便是经验丰富的开发者也会在浮动上出错,因此理解浮动的行为能帮你摆脱面对CSS的不少困扰。即便你认为你已经了解了关于浮动的全部知识,咱们也会深刻到你可能会学习到新知识的地步。布局
在CSS中一些元素是块级元素,他们会自动启用新的一行。例如,若是你建立2个单独的单词段落元素,它们不会相互流入而会各自出如今单独的一行。另外一种元素是内联元素,它们会与以前的内容保持显示在“一行”。举个例子,有个锚标签,它能够出如今像段落这个元素以内并且不会形成任何额外的空白,也不会另起一行。学习
改变这种布局模型的一种方式是使用浮动,它容许给定的元素挪动到它那一行的一侧,而且其余内容向下流动。一个右浮动的元素将被推进直到它的容器的右侧,而且内容会沿着它的左侧向下流动,一个有浮动的元素会被挪动到左侧,内容会沿着它的右侧向下流动。spa
有一个经典的例子是当你将一张图片放进一段落里,而且想让二者并排出现而不是堆叠。首先,咱们用HTML建立两个元素:翻译
<img src="http://lorempixum.com/200/200/" /> <p>Lorem ipsum...</p>
仅仅这样并不能出现咱们想要的效果。段落元素是一个块级元素,它会独自占一行,因此段落和图片会显示在正常的文档流。
咱们能够经过将图片浮动到右边来改变显示。这种CSS很是基础:code
img { float: right; margin: 20px; }
有了这段代码,咱们的图片会被挪到它这一行的右边,段落文字会在它的左边向下流动。
有趣的是,这张图片在被浮动时,咱们其余的内容将会尽量的尝试围绕它出现。若是改变咱们容器的大小或者将浏览器窗口变窄,文本只是简单的自我重排而不会触碰到图片。图片
可能你对这种行为已经有了很好的理解。然而,为了更充分利用浮动,你须要更深层次的理解这两个元素之间的交互。例如,咱们怎么在段落和图片之间添加额外的空白?你可能认为这样可行ip
p {margin: 20px;}
然而,这不会在图片和段落之间产生甚至一像素额外的空白。相反,咱们为图片应用了这些空白:element
img {margin: 20px;}
你应该问本身一个问题,“为何?”为何增长段落的margin不会在图片和段落之间增长空白?由于咱们没有掌握属于段落的盒模型。开发
若是你曾怀疑你的布局是怎么在基本层面上工做的,试着应用一两个边框来看看将发生什么。若是咱们在这个段落上这样作,结果可能会让你惊讶,
p { border: solid 1px black; }
正如你所看到的,图片实际上在段落的盒子里面!这解开了咱们的边界空白疑惑。咱们给段落添加的任何空白都被应用到了图片的右边,这就是为何在图片和段落之间不会增长空白。
若是咱们想改变这种行为,让段落再也不围绕图片,咱们可让段落浮动到左边,并给他指定宽度(没有表示宽度,段落将会是100%的宽,将不会布置在图片旁边)。
如今咱们知道了浮动是作什么的,以及它是怎么影响所涉及的元素的盒子的。让咱们继续讨论另外一块可能不少开发者都不了解的信息:控制浮动元素位置的规则。
一般在图片集或者特征列表中开发人员会用浮动来控制列表项的位置。咱们建立一个简单的纯图片的列表来看看这是怎么工做的。
<ul> <li><img src="http://placehold.it/100x100&text=1"/></li> <li><img src="http://placehold.it/100x150&text=2"/></li> <li><img src="http://placehold.it/100x100&text=3"/></li> <li><img src="http://placehold.it/100x100&text=4"/></li> <li><img src="http://placehold.it/100x100&text=5"/></li> <li><img src="http://placehold.it/100x150&text=6"/></li> <li><img src="http://placehold.it/100x100&text=7"/></li> </ul>
默认状况下,全部的列表项都显示在一个大的垂直栈里,这意味着它们是块级元素。即便图片是内联元素,它们也被它们的父块级元素列表项控制。为了解决这种问题,咱们要使列表项左浮动。当一行中多个元素被浮动,它们会产生同内联元素的流相似的效果。然而,正如咱们所看到的,有一些关键的区别。
li { float: left; margin: 4px; }
如今,若是咱们全部的图片都是一样的高度,这只是一个很是普通的例子。这个结果看起来就像是一个简单的从左到右按顺序排列的图片集:
然而,咱们的图片并非一样的高度,一些高100px,其余的高150px。这会形成很是古怪的结果。
我第一次看到这种结果的时候感到很困惑。这里的世界到底发生了什么?为何图片4会像那样在右边?难道它不该该本身试着尽量让本身浮动到左边?若是咱们去掉这些列表项的浮动,用display:inline来替代,结果是大相径庭的。
li { display: inline; }
跟最开始相比,这个例子的不一样之处在于图片的默认状态是沿着它们的底部边缘垂直对齐。这会使它们同以前的例子看起来很是不同,可是咱们可使用一行CSS来解决这个问题:
img{ vertical-align: top; }
如今看起来比较像浮动示例了,只会显示有一个可预测顺序的内联列表项。当x轴没有下一项的空间时,它会返回到下一行的左侧。
因此,咱们的浮动图片集为何没有像这样显示呢?为何浮动的列表项被奇怪的巫术控制?
事实证实,CSS规范列出了九条规则来规定浮动的行为。这个清单的问题在于即便是被写出来了,也只有无聊的人才能去理解它。这里是一个从其中一个规则中引用的:
“If the current box is left-floating, and there are any left-floating boxes generated by elements earlier in the source document, then for each such earlier box, either the left outer edge of the current box must be to the right of the right outer edge of the earlier box, or its top must be lower than the bottom of the earlier box. Analogous rules hold for right-floating boxes.”
也许你的阅读理解能力比我要强,可是这个还有其余的规则都让我头晕。全部说什么左外边缘在右外边缘的右边的言论都是很是日常的东西,却被装扮得听起来十分复杂。为了大家的方便,Josh Johnson将浮动表现翻译成英文并总结了九条规则,看起来更简单一点。
咱们能够看作这些大多数都是常识,但他们也要被明确声明出来以便每一个人在每一个浏览器上看到一样的页面。基本上来讲,这种状况的要点就是浮动元素会被指定到具体的边缘(左或者右),没有过多的要求。除非在他以前有另外一个浮动元素,他就会与那个浮动元素相邻。
真正让咱们感到困惑的是最后的规则,它代表了浮动元素尽量的保持高的位置,而且垂直定位规则比水平的左右规则在将元素推到边缘时优先级更高。
在咱们以前的例子中,数字2的图片把行的高度撑开了,以致于在数字3图片以后仍然有一些垂直的空间使得数字4图片挤了进去。即便是考虑到这些规则,这种模式也不容易被预测到。
请记住,当你有一个浮动元素时,后面紧接着的浮动元素至少要占据与以前一样或者更多的垂直高度来打破这一行使得流动下移。
关于咱们在这里提出的规则的最后一点。第2条规则会对那些浮动元素产生有趣的影响。假设,咱们有六张从一到六的数字图片,以下:
<ul> <li><img src="http://placehold.it/100x100&text=1"/></li> <li><img src="http://placehold.it/100x100&text=2"/></li> <li><img src="http://placehold.it/100x100&text=3"/></li> <li><img src="http://placehold.it/100x100&text=4"/></li> <li><img src="http://placehold.it/100x100&text=5"/></li> <li><img src="http://placehold.it/100x100&text=6"/></li> </ul>
若是咱们将这些图片浮动到左边,他们会按顺序出现,从一开始直到六,从左到右,从上到下。可是,若是咱们将这些图片右浮动。
正如你所看到的,第一张图片被放到了最右边的位置。相似的,在换行时,第四张图片也被放置到了右边。这就是为何你不多看到有人将导航元素右浮动。弄出了这样螺旋状的顺序就须要HTML结构作出不受欢迎的改变来解决。
浮动对于完成一些相似于创造内容列这样的布局颇有用。可是,一旦浮动被声明,他们就会对剩下的文档的产生一些或许你喜欢或者不喜欢的影响。例如,咱们想在咱们以前说起的那种左浮动的列表块以后加一个段落。
结果或许并非你所指望的:
这里的结果是使用clear属性,让没有浮动的元素能够出如今他所应用的元素给定的一侧。例如,好比咱们在咱们的小图库列表的第二项添加clear: left.
ul li:nth-child(2) { clear: left; }
这段代码告诉浏览器,第二项的顶部必须位于他以前的任意左浮动项的底部之下(在这个例子中,是第一项)。若是咱们将全部元素都右浮动,咱们就要使用clear: right。
请注意,在此以后,剩下的浮动元素都会保持他们的位置。由于他们仍然被设置的左浮动,清除属性并无取消他们的表现。这意味着咱们的问题不能经过清除列表任意项的浮动来解决。
相反,必须被清除的是段落元素,他是一个没有被浮动的块级元素。这将确保他会出如今浮动元素的下面而不是旁边。
p { clear: both; }
从技术上来说,咱们只须要清除这里的左浮动,可是当一个开发者想要确保清除全部浮动时,一般会看到clear的值被设置为both。这个变化能很是好的解决咱们的问题。
当一个给定的元素只包含浮动元素时会产生奇怪的现象:父元素的高度会坍塌。举例说明,假设咱们想在全部示例中的无序列表给定背景色。若是列表的元素没有被浮动,咱们就只须要应用一下CSS来添加背景。
ul { background: gray; }
正如你所看到的,定义的无序列表的框已经变成了灰色,而且列表中的每一项都堆叠在一块儿。
然而,在第二个例子中,咱们浮动了全部列表项,UL只包含了浮动的元素,致使它的高度坍塌,这会让新手开发者惊讶它的背景色到底发生了啥。
有一些方法能够解决这个问题,最简单容易的方法是为无序列表的父元素明确指定高度。
ul { height: 300px; }
正如你所看到的,这的确能让咱们的背景从新被填满。然而,从长远来看这并非一个可取的办法,若是高度是基于内容自动计算的话。若是咱们要添加三个或者更多的图片到列表库里,高度就会不足。
这里术语clear fix,也叫clearfix,就开始发挥做用啦。清除浮动经过使用clear属性来解决高度坍塌的问题。
开发者在他们的HTML中建立一个跟浮动元素同级的空元素(经常是一个div),而后给空容器添加一个命名为clearfix的class。咱们回到CSS中,给clearfix添加清除浮动的属性。
.clearfix { clear: both; }
马上就解决了高度坍塌的问题:
根据咱们已经学过的能够知道为何这个方法能够解决咱们的问题。高度坍塌的缘由是由于父元素只包含了浮动元素的,如今他有了一个子元素,尽管这个子元素是空的,可是它没有浮动,因此高度会再次跟预期同样自动生成。
这个方法有个问题是,没有人喜欢HTML中额外的丑陋的元素。它根本不是语义的,意味着它不能清晰的传递页面的层次结构。
新的解决方案是利用overflow属性,这个属性控制了超出其包含框边界的内容的功能。若是你将父项目的overflow设置为hidden或者auto,也能解决高度坍塌。
ul { overflow: auto; }
这绝对是解决高度坍塌问题的最简单、最优雅的方案,也应该是你的方案。虽然这么说,那在某种状况,你想将元素的overflow设置为visible,你又应该怎么作呢?
这样的结果可使用Nick Gallagher的微型清除浮动hack,他使用了一下天才般的CSS来解决这个问题。首先,他是使用的:before以及:after来添加一些内容,咱们能够用来为父元素建立一些不浮动的元素。然而,你不想在这里使用真实的内容,因此咱们使它为空而且设置display为table来建立一个匿名框(空的并且不占空间)最后使用咱们的老朋友clear。它建立了一个不可见的块级元素来解决高度坍塌的问题而且没有添加额外的HTML。IE的老版本须要本身修复。
/* For modern browsers */ .cf:before, .cf:after { content:""; display:table; } .cf:after { clear:both; } /* For IE 6/7 (trigger hasLayout) */ .cf { zoom:1; }
文章中,咱们讨论了大量的信息,包括基础和复杂的。咱们从最开始讨论如何浮动,以及他们在基本层级是如何工做的,而后是如何设置元素的浮动来影响元素所涉及的盒子边框,让你找出怎么样工做才能根据你想的那样得到边距。
接着,咱们讨论了浮动元素的基本规则,并得出了一些有趣的结论,就是不一样高度的浮动元素如何定位,以及右浮动的元素怎么以相反的顺序出现。
若是在阅读本篇文章以前,浮动让你感受到很困惑,那么开始阅读吧。它们最开始就迷惑了咱们。但愿你如今以及了解了浮动是怎么工做的,以及知道如何使用它们来实现你想要的布局。若是你以为这些信息有帮助,请在下面留下评论让咱们知道。