CSSFloat原理详解(中英文对照)_CSS教程
教程Tag:暂无Tag,欢迎添加,赚取U币!
本文介绍CSS Float的基本原理和行为特征,并介绍各种浏器Float特性的Bugs。
if you are like most people, the whole issue of Floats is rather intimidating. The theory is difficult to grasp, and on top of that, the bugs are rumored to be numerous and nasty. Well fear not, because we will walk through the concepts, some of the bugs, and the practical uses of floats, in nice easy stages. Be assured that you will suffer no ill effects. Rather, a vast new world of positioning will open up before you. Onward!
基本的浮动原理
Any element may be floated. Paragraphs, div's, lists, tables, and images can all be floated, and in fact even inline elements like "span" and "strong" can float just fine.
任何元素 element 都可以被浮动。段落、div、list、tables,以及图像都可以被浮动,事实上即使是像 span 和 strong 这样的行内置元素也可以很好地进行浮动。
Any element that is declared to be a "float" is automatically made a "block level element," meaning it can have both a declared "width" and "height." In fact, floats are currently required to have a declared width, but this is not what modern browser makers think, and the W3C has come to agree. The consensus now is that a float with no assigned "width" should "shrink-wrap" to the width of the float content. So a float with an image inside will be as wide as the image, and a float with text will be as wide as the longest text line in the float.
任何申明为 float 的元素自动被设置为一个"块级元素", 这表示它可以具有申明的"width"和"height"属性。事实上,floats当前被要求具有一个申明的宽度,但这不是现代浏览器制造者的思路,W3C以及开始同意这样的作法。现在大多数人的意见是没有指定宽度的float应当伸缩包装到浮动内容的宽度。因此,内部带有图片的一个float将和图片一样宽,带有文本的一个浮动将与该浮动内的最长文本行一样宽。
The CSS2.1 rules for floats now say: "If 'width' is computed as 'auto', the used value is the 'shrink-to-fit' width". All modern browsers already do this, except for IE5/Mac. That browser will be buggy unless the float has some kind of specified width. These days most savvy coders will let browsers shrink-wrap their widthless floats and use a hiding hack to "feed" IE5/Mac a width for the float. It might not be as pretty, but that is a very minority browser now and Mac users have several quality alternatives too. Microsoft has ceased to support IE5/Mac, so perhaps it's too much to ask that a highly useful feature like float shrink-wrapping be avoided, just so that IE5/Mac users won't see misshapen floats.
CSS2.1的浮动规则中这样讲: "假如 width 是以 auto 方式计算得到,使用的值是 shrink-tofit 伸缩到适合的宽度。" 所有现代的浏览器已经这样做,除了IE5/Mac。除非浮动具有某种指定的宽度,否则该浏览器会变得错误百出。现在大多数聪明的编码人员会让浏览器伸缩其没有宽度属性的floats, 并使用一个隐藏的专门给IE5/Mac的宽度知识。这可能不算很巧妙,但是它是现在不能满足该规范的极少数的浏览器,同时Mac用户有几种更好的选择。MS停止了对IE5/Mac的支持,因此寻求像伸缩包装式浮动这样有用特性被避免的代价太高了,这样只有IE5/Mac用户不会看到错误的浮动。
浮动是如何进行的
Floats are "removed from the flow," but unlike absolutely positioned elements (layers), floats do get displayed directly after the last block element that precedes them (just like block boxes do). If the float is inside a "line box," the float's upper edge is placed level with the top of the line box. But other than that, floats are similar to absolute elements, in that ordinary block boxes totally ignore both floats and AP elements. Those static block boxes just keep "flowing" one after another as though the float were not there.
浮动"从流程中被移除出来", 但是与绝对位置的元素(层次)不同,浮动是在他们前面的最后一个块元素之后直接被显示出来(就像块盒一样)。假如该浮动是在一个“行块”中,该浮动的上边界被放置在行块顶部的水平上。当除此以外,浮动与绝对元素相似,原先的块盒会完全忽略浮动和AP元素。那些静态的块盒知识保持一个接一个地”跟随“,就似乎没有浮动不在那里一样。
The following is minimal code for the example graphic:
示例代码 [www.mb5u.com]
<div style="float:left; width:40%;"><p>Float text</p></div>
<p>
Paragraph text outside the float
</p>
<p>
Paragraph text outside the float
</p>
Shows how line boxes are shortened in the presence of a float. You can get inline elements like text and images to go along the side of a float and continue below it, just like using the good old (but deprecated) "align=left" on an image. Floats, however, are much more versatile than that.
上例展示了行盒在一个浮动中是如何被削短的。你可以让行内元素(像文本、图像)在一个浮动的边上放置并且在它的下面继续,就似乎使用很好的老式(不过已过时)图像的属性"align=left"。浮动,比这要灵活的多。
It is a common misconception that block elements following a float are made to run down the side of the float, but that is not correct. Actually, it is only the "line boxes" within those block elements that behave so. (Please see the first screen shot image.)
认为跟在一个浮动后面的块元素会被设置为放置在浮动的下方是通常的一个误解。事实上,只有在哪些块元素内部的”行盒“才会这样。
Remember that I mentioned that floats are removed from the document flow? The specs require that line boxes that would pass behind a float be shortened enough to keep the line box out in the open. That means text and inline images cannot ever be covered by a float, unless one or both are in separately positioned containers. That is, if a float were nested in an absolutely positioned element, and that AP element were made to overlap a paragraph, the line boxes in the paragraph would not be shortened by the float, due to their different contexts. Rather, that text would indeed be covered by the float.
还记得我提到的浮动被从文档处理流程中移除出来的话吗?标准要求在一个浮动后面的行盒被进行足够的削短以保持行盒在外部开放区。这表示文本和行内的图像永远不会被浮动覆盖,除非他们其中之一或两个在独立的、指定位置的容器中。这就是说,假如一个浮动被嵌套在一个绝对位置的元素中,并且AP元素被设置为覆盖一个段落,在段落中的行盒不会被浮动削短,这是因为他们不同的上下文环境造成的。而且,文本的确会被该浮动覆盖。
A common problem people have with floats is keeping text outside the float from touching the sides of the float. Putting left padding or margin on the paragraph following the float won't work, because those properties are applied over on the left side of the paragraph, behind the float! The proper way is to place margins on the float itself, thus convincing the line boxes that the float is "bigger" than it appears, and shortening them accordingly. Most floats typically get such margins just on the side nearest the text and the bottom. The float in the screenshot above has a small right margin.
对于浮动的一个常见错误是:将文本保留在该浮动的边界之外。对浮动后面跟着的段落放置padding或设置边界是不会生效的,因为这些属性被应用在跟随在浮动后面的段落的左边。正确的方式是对浮动本身设置margins,这样可以让行盒正确显示,浮动要比它呈现的要更大,并且对他们进行相应的削短。大多数浮动通常只是从按照最靠近文本的边和底部获得这样的边界信息。上面浮动的截图有一个小的右边界。
Meanwhile, the block boxes following the float just get covered by the float (even though their content may have been moved aside). If the float is made very tall, it can drape over a large stack of block boxes, as shown in the second screen shot image.
同时跟在float后面的块盒只是被该浮动覆盖(即使他们的内容已经被移动到边上)。假如该浮动被设置的非常高,它可以挡住大量堆叠的块盒上,就像第二个截图看到的那样:
示例代码 [www.mb5u.com]
<div style="float:left; width:30%;">
<p>Left float text</p></div>
<div> <!-- first block box -->
<div style="float:right; width:150px;">
<p>Right float text</p>
</div>
<p>Text following the right nested float</p>
</div>
<p>Paragraph</p> <!-- second block box -->
<p>Paragraph</p> <!-- third block box -->
<p>Left float text</p></div>
<div> <!-- first block box -->
<div style="float:right; width:150px;">
<p>Right float text</p>
</div>
<p>Text following the right nested float</p>
</div>
<p>Paragraph</p> <!-- second block box -->
<p>Paragraph</p> <!-- third block box -->
Shows how floats can cover multiple block boxes.
展示了浮动是如何覆盖多个块盒的。
As seen above, another behavior of floats is their "direction". When a float is defined, it is always given a directional value of either "left" or "right," for example: div {float: left;} . These values simply move the float to the indicated side of the containing box.
如上所示,浮动的另一个行为是他们的”方向”。当一个浮动被定义的时候,总是被给予一个方向值。(“left”或“right”),例如:div{ float:left;}. 这些值简单地将浮动移到到容器盒的指定边界。
Occasionally, float newbies will try to use float values such as {float: up;} or {float: bottom;} , but these values are not valid, and there are no plans to include them in the float specification. One can always hope...
偶然,float的新手会试图使用浮动值,例如{float:up;} or {float:botton;}, 但是这些值是无效的,在浮动的标准中并没有计划要添加这些值。人们总是可以期待...
浮动从何处开始
If a float comes between two block boxes, it has its upper edge placed against the lower edge of the preceding block box, and then it is moved over to the left (or right), until it strikes the side of the outer container element, often the <body> element.
假如一个浮动在两个块盒之间,它会将其上边界放置在前置块盒的下边界上,并且将其移动到左(或右边),直到达到外界容器元素的边界,通常是<body>元素。
If the float is nested inside the second block box, and that container box has no borders or padding, it appears just the same as when the float is between the block boxes. However, if those block boxes are held apart by margins, the float's top edge starts at the point where the margin of one box meets the other box. In the following screen shot image, the block boxes have top margins, but the left float's left margin has been removed to show its default (non-margined) behavior.
假如浮动被嵌套在第二个块盒中,并且该容器盒没有边框盒填充,浮动呈现样式,与浮动被放置在块盒之间是一样的。但是,假如这些块盒通过边距分离,该浮动的顶部边界从一个盒与另一个盒边界的交叉点上开始。在以下截图中,块盒右顶部边界,但是左侧的浮动的左边距已经被移动以显示缺省的动作。:
示例代码 [www.mb5u.com]
<p>Paragraph</p> <!-- first block box (complete) -->
<div style="float:left; width:30%;">
<p>Left float text</p></div>
<div> <!-- second block box -->
<div style="float:right; width:150px;">
<p>Right float text</p>
</div>
<p>Text following the right nested float</p>
</div>
<div style="float:left; width:30%;">
<p>Left float text</p></div>
<div> <!-- second block box -->
<div style="float:right; width:150px;">
<p>Right float text</p>
</div>
<p>Text following the right nested float</p>
</div>
Shows the different places that floats may be placed.
展示了浮动可能被放置在不同的位置。
水平浮动堆叠
If a left float is placed in the upper left corner of its container, and a similar float directly follows it, that float is placed at the upper right of the container, and then moved to the left, stopping against the right side of the first float.
假如居左的浮动被放置在其容器的左上脚,并且其后跟随一个同向的浮动,该浮动会被放置在容器右上脚,然后移动到左侧,边界延伸到第一个浮动的右侧时停止。
That last behavior lets us create a whole row of floats, each being placed to the right of the one before (or to the left of the one before if {float: right;} is used). Also, when there is not enough room for all the floats to fit in one row, the extra floats "wrap" down to another line, almost like inline elements do. This is very handy for making an array of clickable image "thumbnails," because the array will adjust to whatever screen size happens to be used, simply rewrapping as necessary.
最后的一种行为让我们创建整行的floats,每个都被放置在前一个的右侧(或者左侧,假如使用{float:right;}). 同样,当一行中没有足够的空间时,多出来的floats绕到下一行,非常像行内元素那样。这对于制作可点击的图像“简略图”非常方便,因为矩阵会自动调整到屏幕的尺寸,只是简单地在需要时进行回绕。
Below is a line of colored left floats. The upper left float comes first in the source, and the lower right is last. They all have small margins just to look pretty. Try narrowing the window of your browser, and watch as the float line gets "wrapped" down to accommodate the window size.
以下是一行彩色的左向浮动。左上方的浮动在源代码中先出现,右下方的最后。他们都有一个小的边距以便看起来更好一些。试一下将浏览器的尺寸变小一些,观察浮动行被回绕以使用窗口尺寸。
Float 1 Float 2 Float 3 Float 4 Float 5 Float 6 Float 7 Float 8 Float 9 Float 10 Float 11 Float 12 Float 13 Float 14 Float 15
The floats above will wrap to fit any screen size. Notice how the text in this following (invisible) paragraph also adjusts to any changes in the float arrangement. The paragraph actually starts right where the first float does, but since only the text in the paragraph is visible, that fact is not obvious. The paragraphs in the screen shots have borders and backgrounds in order to show the actual situation.
上述浮动会回绕以使用任何屏幕的尺寸。注重其下段落(不可见)的文本同样也调整以使用浮动排列的变化。该段落实际上从第一个浮动开始的地方开始,但是只有在段落文本可见的情况下,该事实才不明显。截图中的段落具有边框盒背景以便显示实际的位置。
If the float is given a "right" value instead of "left," the behaviors are exactly the same, but the float moves right rather than left, and subsequent floats are added to the left end of the row, not the right. In either case, wrapping is similar, unless float bugs cause differences.
假如浮动被设置为“右侧”而不是“左侧”,其行为完全相同,知识浮动从右开始,而不是从左开始,后续的浮动被添加到左侧行尾而不是右侧。两种情况,回绕都是一样的,除非float的Bugs导致差异。
Think of it this way. A float in a container is first moved up to the topmost space it can fit into (on the side away from its "direction"), then is moved in the designated float direction until it bumps into the side of the container, or another float. Each succeeding float does the same thing, until one of the floats can't find a space wide enough on the level of the others. Instead it is forced to stop against the bottom of the other floats, and then slide to the side just like before.
用这样的方式思考,一个容器中的浮动首先被移到它能够到达的最上方的空间(在其定位的方向),然后按设置的浮动反向移动直到到达容器的边界,或者碰到另一个浮动。每个连续的浮动都是同样处理,直到其中一个浮动在另一个浮动的level中无法发现足够宽的空间。这样,它会被强制停止到另一个浮动的底部,然后向之前那样进行滑行。
Float 1 Float 2 Float 3 Float 4 Float 5 Float 6 Float 7 Float 8 Float 9 Float 10 Float 11 Float 12 Float 13 Float 14 Float 15 Float 16 Float 17 Float 18 Float 19 Float 20
Caution! Watch out for floats that are not all the same height. When a float being placed in the second row comes up against the first row (over to the right), and it tries to slide sideways (to the left), it gets "stuck" on the first taller float it encounters. With a large number of irregular floats this can get really ugly. The above batch of floats contains a couple of "joker" floats that are slightly taller than the others.
警告!注重上面的浮动的高度不是一样的。当一个浮动被放置到第二行紧接第一行时,它视图滑行到边界,当碰到第一高的浮动时会被停住。当有大量不规则浮动时,这会造成很丑陋的情况。上面的浮动中包含一些比其他高一些的浮动。
Test this behavior by narrowing your browser to different screen widths (browser abuse).
缩小你的浏览器以不同的屏幕宽度来测试。
Whenever this technique is used to make a large thumbnail array, care must be taken to insure all the floats are the same height, or the page might easily resemble a train wreck.
在追着一个大型的简略图矩阵时,必须注重确保所有的浮动具有同样的高度,或者页面可以轻易地被出轨的浮动重新组装。
All the live demos in this article have been hacked to account for the faulty IE5.x/win box model. This was necessary due to the borders and padding applied to the boxes in those demos.
本文中的所有例子都使用了非凡的处理以适应IE5.x/win盒模式的缺点。由于边框和填充造成了必须非凡处理。
反向浮动
示例代码 [www.mb5u.com]
There's no reason why two successive floats can't have different directions. If a container starts its content with two floats, one left and the other right, and there is room for both to fit side by side, then they will indeed display that way. Any extra space will form a gap between the floats.
But what if there is not enough room for both? Then the float that comes last will be forced below the first float, although the floats will still remain on opposite sides of the container. Again, narrow the browser to see opposing float wrapping, or the lack of it in the case of percentage sized floats.
First, the left float precedes the right float:
This float has width: 250px; and is floated to the left. It precedes the following right float.
This float has width: 250px; and is floated to the right. It follows the preceding left float.
Then the reverse:
This float has width: 250px; and is floated to the right. It precedes the following left float.
This float has width: 250px; and is floated to the left. It follows the preceding right float.
Now percentage sized widths:
This float has width: 44%; and is floated to the left.
This float has width: 44%; and is floated to the right.
This simple arrangement mostly works well, but some browsers don't handle more complex (multiple) oppositions very well yet. Anything of the sort must be rigorously tested in all target browsers.
There is one major flaw in the above demo, in that Internet Explorer 5.x/win fails to make a following left float wrap below a preceding right float, under any circumstances, unless the floats are contained in a width defined block element. The above demo has such an element enclosing it. It's just one of many IE float bugs that are "fixed" by putting a dimension on the float container.
Clearing Floats
But what if there is not enough room for both? Then the float that comes last will be forced below the first float, although the floats will still remain on opposite sides of the container. Again, narrow the browser to see opposing float wrapping, or the lack of it in the case of percentage sized floats.
First, the left float precedes the right float:
This float has width: 250px; and is floated to the left. It precedes the following right float.
This float has width: 250px; and is floated to the right. It follows the preceding left float.
Then the reverse:
This float has width: 250px; and is floated to the right. It precedes the following left float.
This float has width: 250px; and is floated to the left. It follows the preceding right float.
Now percentage sized widths:
This float has width: 44%; and is floated to the left.
This float has width: 44%; and is floated to the right.
This simple arrangement mostly works well, but some browsers don't handle more complex (multiple) oppositions very well yet. Anything of the sort must be rigorously tested in all target browsers.
There is one major flaw in the above demo, in that Internet Explorer 5.x/win fails to make a following left float wrap below a preceding right float, under any circumstances, unless the floats are contained in a width defined block element. The above demo has such an element enclosing it. It's just one of many IE float bugs that are "fixed" by putting a dimension on the float container.
Clearing Floats
Here we come to the trickiest and most misunderstood part of floating.
以下开始讲述关于浮动的最晦涩、最难以理解的部分。
Think back to what was said about static boxes following floats. Those boxes just ignore the float, and display up against the previous static boxes. But let's say you give that following box the clear property, {clear: both;} . What this does is extend the margin on the top of the cleared box, pushing it down until it "clears" the bottom of the float. In other words, the top margin on the cleared box (no matter what it may have been set to), is increased by the browser, to whatever length is necessary to keep the cleared box below the float.
回顾一下跟随浮动后面的静态盒。这些盒只是忽略浮动,并且在前一个静态盒的后面排列显示。假设你给以下盒一个清除属性,{clear:both;}。这是将被清除盒的顶部边距扩展,将其向下推直到清理浮动的底部。换句话说,该被清理的盒的顶部边距(无论它之前被设置成什么值),都会被浏览器增加到需要保证被清理盒位于浮动下回的长度。
So in effect, such a cleared box cannot be at the same horizontal level as a preceding float. It must appear just below that level. The image shows how this might look.
这样的效果是,一个被清理的盒无法与前置浮动保持在同一个水平位置上。它必须出现在其下方。以下图例展示了效果。
Shows how a box may clear below a float.
展示一个盒如何清理下方的一个浮动。
Remember, floats are not actually contained within a block box, even though they may be nested there in the source code. Sure, the float's screen starting point is determined by its nested location, but after that it just drapes over the containing box, as do absolute elements. Only line boxes containing inline elements (like text) will care where the float is displayed.
记住,浮动实际上并不是真正地被包含在一个块盒中,即使在源代码中是怎样嵌套的。请注重确认,浮动的屏幕开始点是由它所嵌套的位置决定的,之后它只是在容器盒上展开,就像绝对元素一项。只有包含行内元素的行盒(例如文本),才需要关注浮动在哪里被显示。
The standard method of making an outer container appear to "enclose" a nested float is to place a complete "cleared" element last in the container.
制作一个看起来封装一个嵌套浮动的外容器的标准方法是在容器的最后放置一个完整“被清理”的元素:
示例代码 [www.mb5u.com]
<div> <!-- float container -->
<div style="float:left; width:30%;"><p>Some content</p></div>
<p>Text not inside the float</p>
<div style="clear:both;"></div>
</div>
<div style="float:left; width:30%;"><p>Some content</p></div>
<p>Text not inside the float</p>
<div style="clear:both;"></div>
</div>
Since that div is not floated, the container must recognize it and enclose it, and because of that top margin (added by the browser because of the "clear" property), the div "pulls" the bottom edge of the container down below the bottom edge of the float.
由于div没有被浮动,容器必须识别它并封装它,并且由于顶部边距(由于“clear”属性由浏览器添加),该div将容器的底部边界拉到浮动框的底部。
Sure, that is a weird way to do it, but that's what the specs say. However, there is talk at the W3C about adding a rule that would make a container "auto- enclose" a float. It sure would be simpler.
的确,这是一个古怪的方法,但是标准就是这样说的。不过,W3C中有一个讨论关于添加一个容器自动封装一个浮动的规则。这样就于更加简单。
In fact, both Explorer and Opera 7 already do "auto-enclose" nested floats, in violation of the specs. Opera 6 did not do this, so it seems Opera is following Microsoft's non-standard lead.
事实上,IE盒Opera7已经自动封装嵌套的浮动,与标准不一样。Opera6不是这样,因此看来Opera在跟随MS的非标准道路。
It is also possible to use {clear: left;} or {clear: right;} . This allows an element to clear a left float but not a right, or the opposite. You will have to get pretty fancy to need this kind of control, however.
还可以使用 {clear:left;} 或 {clear:right;}. 这可以让一个元素清除左侧浮动当不影响右侧浮动,或者相反。要使用这种控制你需要有相当的想像力。
In general, clearing works well, but can sometimes induce minor and not so minor bugs, which are almost entirely confined to Internet Explorer.
通常来说,清除可以很好地完成,但是有时会引起不大不小的错误,这完全是由IE造成的。
相关CSS教程:
- 相关链接:
- 教程说明:
CSS教程-CSSFloat原理详解(中英文对照)。