Why don't my frames surround the floats inside them without this CSS fix? (And how does the fix work?)

I teach CSS and HTML, and I came across something that seems like a mistake - it challenges the way I understand HTML and CSS. I already found a fix for this error, but I was hoping someone would be able to tell me why the fix works, and if there is any advice on how to get a lighter CSS mismatch descriptor. Below I will talk in detail about the problem and its solution.

Problem: I have several elements that I want to nest in a couple of boxes on the page. I modified CSS to draw attention to specific problem areas: red and green boxes should be sandwiched between the black and yellow lines.

Red and green fields are set to float to the right and left of the page. Their container does not expand to surround them, and the black and yellow lines touch each other. After applying magic CSS before my custom CSS, two lines surround the red / green rectangles as expected

Here are my files: template.html

<html> <head> <!-- uncomment the line below to enable the fix --> <!--<link rel="stylesheet" href="css/resettemp.css" type="text/css" > --> <link rel="stylesheet" href="css/template.css" type="text/css" > </head> <body> <section class="content"> <header id="contact"> <div id="name">Name</div> <div id="address"> <div>Home Address</div> </div> <div id="contact-details"> <div><strong>Phone Number:</strong>5555 </div> </div> </header> This text should be under everything else. </section> </body> </html> 

template.css:

 header#contact { display: block; font-size: 1em; border-bottom: 5px #ff0 dashed; } header#contact #name { display:block; text-align: right; font-size: 2em; border-bottom: 3px #000 solid; } header#contact #address { float:left; background: #f00; } header#contact #contact-details { float:right; background: #0f0; } 

And the fix below is placed in "resettemp.css":

 /* our Global CSS file */article:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }aside:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }div:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }footer:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }form:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }header:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }nav:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }section:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }ul:after { clear:both; content:"."; display:block; height:0; visibility:hidden; }/* our ie CSS file */article { zoom:1; }aside { zoom:1; }div { zoom:1; }footer { zoom:1; }form { zoom:1; }header { zoom:1; }nav { zoom:1; }section { zoom:1; }ul { zoom:1; } 

Sources: http://www.sycha.com/css-clearfix-floated-element-automatically-fill-parent-container

and then CSS above: http://www.marcwatts.com.au/blog/best-clearfix-ever/

How can I understand how this CSS fix works? How can I teach myself the basic CSS syntax in addition to understanding these features? I seem to be probably using float to achieve formatting goals incorrectly. What is a more acceptable way to get two boxes of text on opposite sides of a container under another block element like this?

Browser: google chrome 10.0.648.205

+6
source share
3 answers

"Problem"

Here is a diagram, fom w3c , showing what happens when a float overlaps the boundaries of elements in a normal stream.

A floating image obscures borders of block boxes it overlaps.

This behavior of floating elements causes the height of the parent element to do what most developers consider unintuitive.

But, given that it is documented in w3c, this is intentional: this is not a mistake.

The solution you found

So here is an interesting rule in your CSS:

 /* our Global CSS file */ header:after { clear:both; content:"."; display:block; height:0; visibility:hidden; } 

This rule targets the <header> element, but also uses :after pseudo-element . As a result, it looks like an imaginary element after the <header> that you are targeting this CSS rule:

 <!DOCTYPE html> <html> <head> <!-- uncomment the line below to enable the fix --> <!--<link rel="stylesheet" href="css/resettemp.css" type="text/css" > --> <link rel="stylesheet" href="css/template.css" type="text/css" > <title>Teaching myself CSS, HTML. I want help understanding this bug.</title> </head> <body> <section class="content"> <header id="contact"> <div id="name">Name</div> <div id="address"> <div>Home Address</div> </div> <div id="contact-details"> <div><strong>Phone Number:</strong>5555 </div> </div> </header><!-- imaginary header:after element --> This text should be under everything else. </section> </body> </html> 

This imaginary header:after "element" that is added after the <header> has the clear:both CSS property:

 /* our Global CSS file */ header:after { clear:both; /* This property clears floating elements! */ content:"."; display:block; height:0; visibility:hidden; } 

So what does clear do? According to w3c ...

This property indicates which sides of the element (s) of the element cannot be adjacent to an earlier floating field.

Less reliable, but sometimes clearer, w3schools describes clear as ...

The clear property indicates which sides of the element, where other floating elements are not allowed.

Since the header:after element has the CSS property clear:both , any floating elements on the left or right side, such as red and green fields, will appear at the bottom (after).


Now, this resettemp.css file seems to target almost every element that you can imagine with the same trick - a kind of carpet bomb approach to solving the float - overflow problem. The best idea is to learn CSS: P


You can also use header { overflow:hidden; } header { overflow:hidden; } - depending on your needs.

+7
source

A good tool for debugging html / css is FireBug with Firefox. You can dynamically edit html and css to get real-time results.

When you float an element, it no longer extends the parent element, so the height of the header is reduced to the height of your # name block, which is not floating. The same as in the lower text, it is pushed because floating elements “float” from above.

Clean both (which clean the floats)

 <body> <section class="content"> <header id="contact"> <div id="name">Name</div> <div id="address"> <div>Home Address</div> </div> <div id="contact-details"> <div><strong>Phone Number:</strong>5555 </div> </div> <div style="clear:both;"></div> </header> This text should be under everything else. </section> </body> 
+2
source

To explain your “mistake”:

Red and green fields are set to float to the right and left of the page. Their container does not expand to surround them, and the black and yellow lines touch each other.

This is not a mistake, this is how floats work. Floating elements do not occupy vertical space in their ancestral elements. This is due to the fact that the floating one was originally designed so that the text flowed around the image - if you have a floating image inside the text paragraph and its height above the text in this paragraph, you usually want the next paragraph to also go around the image.

To explain how your “fix” works, for your HTML this is the bit that does it:

 header:after { clear: both; content: "."; display: block; height: 0; visibility: hidden; } 

It works like this:

  • The :after class pseudo-class effectively adds an anonymous HTML element after the element specified by the rest of the selector (which calls the source element well) and allows you to style it. It is a little pointless without ...

  • ... content property. This gives the anonymous element some content that allows it to influence the page layout.

  • display: block and clear: both force this anonymous element to clear any floats that are in front of it (i.e. the floats in the original element). An anonymous element appears after the content field of the original element, but before the fill, border, and field fields, so cleaning pushes the original elements out of the floats.

  • height: 0; and visibility: hidden; then make the anonymous element invisible, but do not prevent it from affecting page layout.

Your “fix” repeats this CSS for div:after , article:after and aside:after . I'm not sure why it doesn’t just use all three selectors together in one CSS rule, i.e.

 header:after, article:after, aside:after, div:after { /* Fix CSS here */ } 

Or really apply CSS to the class instead of elements so that you can choose when to apply it, for example.

 clear-floats:after { /* Fix CSS here */ } 
+2
source

Source: https://habr.com/ru/post/886345/


All Articles