Float is an attribute that we love and hate. Love, because through floating, we can easily layout; hate, floating left behind too many issues need to be addressed, especially IE6-7 (the following no special instructions refer to windows platform IE browser ). Many people may have such questions,Where does float come from? Why should we clear the float? What is the principle of clearing float?This article will further analyze the mysteries and make floating more handy.
1. Clear floating or closed floating (Enclosing float or Clearing float )? Many people have used to call it "clear floating". I used to call it this way, but it is not accurate. We should treat code with a rigorous attitude, and help us better understand the three problems at the beginning. 1) clear floating: clear the corresponding word is clear, and the attribute in the corresponding CSS is clear: left | right | both | none; 2) closed floating: more accurately, it means that floating elements are closed to reduce the impact of floating.
Through the above examples, we found that the effect we want to achieve is more specifically closed floating, rather than simply clearing floating, set clear on footer: both clearing floating does not solve the warp height collapse problem. Conclusion: closed floating is more rigorous than clearing floating. Therefore, it is called closed floating.
2. Why clear the float? To answer this question, we must first talk about the positioning mechanism in CSS: Normal stream, floating, and absolute positioning (where "position: fixed" is a subclass of "position: absolute ). 1) normal stream: many people or articles call it a document stream or a common document stream. In fact, there is no such word in the standard Reagan. Document flow is an English document flow, but there is only one word in the standard, calledNormal stream(Normal flow), or a regular flow. But it seems that people are more accustomed to the name of the document stream, because many Chinese translation books come in this way. For example, in CSS Mastery, from the beginning to the end of the original English book, there is only the word normal flow (normal flow), and there has never been a document flow (document flow)
2) floating: a floating box can be moved left and right until its outer edge encounters an edge of the contained box or another floating box. A floating box does not belong to a normal stream in the document. When an element floats, it does not affect the layout of block-level boxes, but only the arrangement of inline boxes (usually text, the normal stream in the document will behave like the floating box does not exist. When the floating box height exceeds the include box, in this case, the contained box does not automatically extend to close the floating element (the "height collapse" phenomenon ). As the name suggests, it is just floating on a normal stream, just like a floating cloud, but only floating around.
It is precisely because of this floating feature that, after the elements in the normal stream are floating, the height of the contained box is 0 (the height collapsed) because there are no other elements in the normal stream ). In the actual layout, this is often not what we want, so we need to close the floating element so that its contained box shows a normal height.
The absolute positioning is not much to say. It is not within the scope of this article and will be broken down next time.
3. How floating is cleared-understanding hasLayout and Block formatting contexts Let's take a look at the methods to clear the floating:
1) add additional labels This is a method that the school teacher told us by adding an empty label at the end of the floating element, such as <div style = "clear: both"> </div>, other tags such as br can also be used.
- <Div class = "warp" id = "float1">
- <H2> 1) add additional labels
- <Div class = "main left">. main {float: left ;}</div>
- <Div class = "side left">. side {float: right ;}</div>
- <Div style = "clear: both;"> </div>
- </Div>
- <Div class = "footer">. footer </div>
Copy codeAdvantages: easy to understand Disadvantages: We can imagine how many meaningless empty labels will be added in this method, which violates the separation of structure and performance. It will be a nightmare in later maintenance, which is intolerable, so after reading this article, I suggest you stop using it.
2) use the br tag and its own html attributes This method is widely used. br has the clear = "all | left | right | none" attribute.
- <Div class = "warp" id = "float2">
- <H2> 2) use the br tag and its own html attributes
- <Div class = "main left">. main {float: left ;}</div>
- <Div class = "side left">. side {float: right ;}</div>
- <Br clear = "all"/>
- </Div>
- <Div class = "footer">. footer </div>
Copy codeAdvantage: The syntax is slightly stronger than that of null tags, and the amount of code is small. Disadvantage: it also violates the separation of structure and performance and is not recommended.
3) parent element overflow: hidden Set the overflow value of the parent element to hidden. In IE6, hasLayout needs to be triggered, for example, zoom: 1;
- <Div class = "warp" id = "float3" style = "overflow: hidden; * zoom: 1;">
- <H2> 3) configure overflow for the parent element
- <Div class = "main left">. main {float: left ;}</div>
- <Div class = "side left">. side {float: right ;}</div>
- </Div>
- <Div class = "footer">. footer </div>
Copy codeAdvantage: there is no structure or semantic problem, and the amount of code is very small Disadvantage: when the content increases, it is easy to cause the content to be hidden without automatic line breaks, and the elements to overflow cannot be displayed. In POPO 04, overflow: hidden will cause the middle key to fail, this is unacceptable as a multi-label browser control. So do not use it anymore.
4) set the overflow: auto attribute for the parent element. Similarly, IE6 needs to trigger hasLayout. The demo is similar to 3. Advantage: there is no structure or semantic problem, and the amount of code is very small Disadvantages: after multiple nesting, firefox may select all content in some cases; when mouseover in IE changes the width, the outermost layer module may have a scroll bar and so on. In earlier firefox versions, focus will be generated for no reason, see zookeeper'sDemo, Do not use
5) the parent element is also set to float Advantage: there is no structure or semantic problem, and the amount of code is very small Disadvantage: the layout of elements adjacent to the parent element is affected and cannot be moved to the body all the time.
6) set the display: table for the parent element. Advantage: The structure semantics is completely correct, and the amount of code is very small. Disadvantage: The box model attributes have been changed, resulting in a series of problems that are not worth the candle and are not recommended.
7) Use: after pseudo element It should be noted that after is a Pseudo Element, not a Pseudo class (in some CSS manuals it is called a "Pseudo object "), many articles such as clearing the floating book are called pseudo classes, but it is an attitude that csser should be more rigorous. Because the IE6-7 does not support: after, use zoom: 1 to trigger hasLayout.
This method is derived from: How To Clear Floats Without Structural Markup
The original code is as follows:
- <Style type = "text/css">. clearfix: after {content :". "; display: block; height: 0; clear: both; visibility: hidden ;}. clearfix {display: inline-block;}/* for IE/Mac */</style> <! -- [If IE]> <style type = "text/css">. clearfix {zoom: 1;/* triggers hasLayout */display: block;/* resets display for IE/Win */} </style> <! [Endif] -->
Copy codeIn view of the extremely low market share of IE/Mac, we ignore it directly. The final code is as follows:
- . Clearfix: after {content: "."; display: block; height: 0; visibility: hidden; clear: both ;}
- . Clearfix {* zoom: 1 ;}
Copy codeAdvantage: The structure and semantics are completely correct, and the amount of code is centered Disadvantage: improper reuse may increase the amount of code
Summary Through comparison, we can easily find that the methods listed above are nothing more than two types: First, add an empty element at the end of the floating element and set the clear: both attribute, the after pseudo element is actually a block-level element with the content generated after the element as a vertex; Second, the floating is closed by setting the parent element overflow or the display: table attribute. Let's discuss the principles described here.
There is a very important concept in CSS2.1, but there are few technical blogs in China, that is, Block formatting contexts (Block-level formatcontext), hereinafter referred to as BFC. In CSS3, This specification was changed, called flow root, and the trigger conditions were further described.
So how to trigger BFC?
- Float values except none
- Value (hidden, auto, scroll) other than visible in overflow)
- Display (table-cell, table-caption, inline-block)
- Position (absolute, fixed)
- Fieldset element
Note that the display: table itself does not create BFC, but it will generate an anonymous box (anonymous boxes), while the display: table-cell in the anonymous box can create a new BFC, in other words, the anonymous box instead of display: table is used to trigger block-level formatting. Therefore, the effect of BFC created through display: table and display: table-cell is different.
The fieldset element does not have any information about this trigger behavior in www.w3.org until it is available in the HTML5 standard. Some browsers, bugs (Webkit, Mozilla), mentioned this trigger, but there is no official statement. In fact, even if fieldset can create block-level formatting contexts in most browsers, developers should not take this for granted. CSS 2.1 does not define which attributes apply to form controls, nor does it define how to use CSS to add styles to them. The user agent may apply CSS attributes to these attributes. It is recommended that developers regard this support as an experimental feature. Higher CSS versions may further regulate this feature.
Features of BFC: 1) block-level formatting context prevents overlay of the outer marginWhen two adjacent block boxes are in the same block-level formatting context, the vertical margin between them is superimposed. In other words, if the two adjacent block boxes do not belong to the same block-level formatting context, their margins will not overlap.
2) block-level formatting context does not overlap floating elementsAccording to regulations, the border of a block-level formatting context cannot overlap the outer margin of its elements. This means that the browser will create an implicit margin for the block-level formatting context to prevent it from overlapping the margins of floating elements. For this reason, when a negative margin is added to a block-level formatting context, it does not work (Webkit and IE6 have a problem at this point-you can refer to this test case ).
3) block-level formatting context can usually contain floatingFor details, see W3C CSS2.1-10.6.7 'auto' heights for block formatting context roots. In general, the element that creates BFC is an independent Box. The child elements in the box do not affect the elements outside the layout, and vice versa, at the same time, BFC is still a common stream in the document.
So far, you may understand why overflow: hidden or auto can be closed and float, because the parent element creates a new BFC. I think it is not rigorous and there is no basis for Zhang Xinxu's article understanding of overflow and zoom "clear floating" to explain the principle of closed floating with a package. In addition, "Firefox and other browsers do not have the concept of haslayout", so modern browsers have BFC. In terms of performance, hasLayout can be equivalent to BFC.
The IE6-7's display engine uses an internal concept called layout, which directly leads to many display bugs in the IE6-7 due to its many defects. When we say an element "get layout", or an element "own layout", we mean its Microsoft proprietary attribute hasLayouthttp: // msdn.microsoft.com/worksh... rties/haslayout. asp is set to true for this purpose. The IE6-7 uses the concept of layout to control the size and positioning of elements, and those with the layout (have layout) are responsible for the size setting and positioning of themselves and their child elements. If the hasLayout value of an element is false, its size and position are controlled by the ancestor element with the most recent layout.
Conditions for triggering hasLayout:
- Position: absolute
- Float: left | right
- Display: inline-block
- Width: any value except "auto"
- Height: any value except "auto" (for example, height: 1% is used when many people clear the float)
- Zoom: any value except "normal" (MSDN) http://msdn.microsoft.com/worksh... properties/zoom. asp
- Writing-mode: tb-rl (MSDN) http://msdn.microsoft.com/worksh... ies/writingmode. asp
In IE7, overflow also becomes a layout trigger:
- Overflow: hidden | scroll | auto (this attribute did not trigger layout in earlier versions of IE. )
- Overflow-x |-y: hidden | scroll | auto (attributes in the CSS3 box model are not widely supported by browsers yet. They did not trigger layout in earlier IE versions)
For more detailed explanations of hasLayout, see the well-knownOn having layoutAn article (English: http://www.satzansatz.de/cssd/onhavinglayout.htm), because the old9 blog by the Wall, Chinese version address: IE8 uses a brand new display engine. It is said that it does not use the hasLayout attribute, so it solves many bad bugs, but IE8 ~ IE11 can still get the hasLayout flag through "document.doc umentElement. currentStyle. hasLayout". I wrote a test Demo (zoom: 1 in IE8 returns false). For more details, seeIE8 haslayout = true
To sum up:In browsers that support BFC (IE8 +, firefox, chrome, and safari), create a new BFC closed floating;In browsers (IE6-7) that do not support BFC, close the float by triggering hasLayout.
IV. Closed floating method-keep improving Seven closed floating methods have been listed above. By analyzing the principles in section 3, we can find more: display: table-cell, display: any value that triggers BFC, such as inline-block, can be closed and floating. Compared from various aspects, the closed floating of the after pseudo elements is undoubtedly a relatively good solution. The method is described in detail below.
- . Clearfix: after {content: "."; display: block; height: 0; visibility: hidden; clear: both ;}
- . Clearfix {* zoom: 1 ;}
Copy code1) display: Blocks display the generated elements at the block level, occupying the remaining space; 2) height: 0 to prevent the height of the original layout from being damaged by the generated content. 3) visibility: hidden makes the generated content invisible and allows you to click and interact with the content that may be covered by the generated content; 4) Use content :". "The generated content is the last element. It can be vertices or other elements in content. For example, oocss contains the classic content:" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ", in some versions, the content may be blank, and it is not recommended to do this if it is cold. firefox will still generate additional gaps until 7.0 content; 5) zoom: 1 triggers IE hasLayout. After analysis, we found that except for clear: both, other code is used to hide the content generated by the content, which is why other versions of closed floating have font-size: 0, line-height: 0.
Optimization Solution 1: The code of the method with the empty tag closed and floating seems to be somewhat redundant. It is found through the query that there is a "zero-width space" in the Unicode character, that is, U + 200B, this character is invisible, so we can omit visibility: hidden.
- . Clearfix: after {content: "\ 200B"; display: block; height: 0; clear: both ;}
- . Clearfix {* zoom: 1 ;}
Copy code Optimization Solution 2: Proposed by Nicolas Gallagher, original article: A new micro clearfix hack, this method does not have any gaps in firefox.
- /* For modern browsers */
- . Cf: before,. cf: after {
- Content :"";
- Display: table;
- }
- . Cf: after {clear: both;}/* For IE 6/7 (trigger hasLayout )*/
- . Cf {zoom: 1 ;}
Copy code Note that: The above method uses the before pseudo element. Many people are confused about this. When should I use before? Why does solution 1 fail? In fact, it is used to deal with the overlap of the margin. Because the internal element float creates BFC, the margin-top of the internal element overwrites the margin-bottom of the previous box. If this is not what you want, you can add before. If it is just closed and floating, after is enough! Not as mentioned in the desert Clear Float article: but when we only use clearfix: after, there will be a vertical margin overlay bug in cross-browser compatibility. This is not a bug, is what BFC should have.
In actual development, solution 1 is improved because Unicode characters are not suitable for pages embedded with CSS GB2312 encoding. Solution 7 can completely solve our needs, solution 2 is awaiting further implementation. Solution 3 and 4 closed the floating through overflow. In fact, a new block-level formatting context has been created, which will lead to a series of changes in its layout and behavior relative to the floating, clearing floating is only a function of a series of changes. Therefore, it is unwise to change the global feature by closing the float. The risk is a series of bugs, such as the focus generated in earlier versions of firefox, and the layer with absolute positioning truncated. Always understand that if you only need to close the float, overflow should not be used, rather than the "use with caution" mentioned in some articles ".
It took three days to write this article. If this article is helpful to you, your message is my greatest support. At the same time, due to limited energy, you are welcome to point out the errors and deficiencies in this article! |