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.wf0088.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.wf0088.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.wf0088.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.wf0088.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.wf0088.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原理詳解(中英文對照)。