Link to home
Start Free TrialLog in
Avatar of Simon Leung
Simon Leung

asked on

HTML and CSS issues

Any idea what the following CSS selector mean ? Why the vertical and horizontal menu bar can't be displayed properly without this CSS ?



.row::after{
      clear:both;
      content: "";
      display: table;
}
sp_home.html
sp_layout.css
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

What you are seeing there is a more modern approach to clearing floats.

In the old days we would do something like this
<div>
   <div style="float: left; width: 50%;">...</div>
   <div style="float: left; width: 50%;">...</div>
   <div style="clear:both"></div>
</div.

Open in new window

That was just inefficient as it involved adding useless markup that was not needed.

The current approach is to use the :after pseudo element and style that to clear the floats.

The :after pseudo element is "implied" on each element - you can add styles to it as if it exists - but it is not an actual element - the browser adds it to the DOM for you.

The display: table - is just a style we use for this - it is a convention. In CSS we can make non table elements behave like a table using the table, table-row and table-cell style options.
In this case we are really just making :after a block element - giving it some content (with the content style) and the clearing the floats.

In the browser this would be represented like this
<div class="row">
   <div style="float: left; width: 50%;">...</div>
   <div style="float: left; width: 50%;">...</div>
   ::after
</div>

Open in new window

Avatar of Simon Leung
Simon Leung

ASKER

Thx. still can't get how it actually work..

Without CSS, banner image will be displayed, followed by vertical menu which will be disable in next line. Do you mean css ".row::after" will provide the whole menu to jump to next line and displayed it after the image ? Thx

  <header class="row">
      <img src="sp_logo.png" alt="Slate & Pencil Tutoring" />
      <nav>
         <ul>
            <li><a href="#">Home</a></li>
            <li><a href="#">Our Tutors</a></li>
            <li><a href="#">Pricing</a></li>
            <li><a href="#">Testimonials</a></li>
            <li><a href="#">Your Account</a></li>
            <li><a href="#">Chat Online</a></li>
         </ul>
      </nav>
   </header>
Do you understand the concpets of inline, block, float and absolute with respect to positioning of elements in a document?

For the most part elements are either block
div, table, section, p ...

Open in new window

While others are inline
i, b, span, a ...

Open in new window

What this means is - when the browser renders the page it will try to put the next element next to the last one (inline) if the element is too big for the space it wraps to the next line.
Block elements by definition take up the full width of the screen -irrespective of how much content they contain so they always have their own row to themselves.

Sometimes we want to put block elements next to each other - for instance in a navigation bar. To do this we use the float style. Float tells the browser to position the element immediately next to the element to the left or right (depending if you are floating an item left or right)

The problem with this is that it tells the browser that it should keep adding elements to the right (in case of a float left) - even when the next element is not floated.

So if you have this to form a horizontal nav bar
<style>
.ul li {
   float: left;
}
</style>
<ul>
  <li>Item 1</li>
  <li>Item 1</li>
  <li>Item 1</li>
</ul>
<span>Some text</span>

Open in new window

What happens here is that Some Text will try to sit next to the last <li> which you don't want.
To fix this we have to clear the floats on the <li> items.

We can do that using a clear: both - this used to be done by adding another element to the HTML with this style on it - but that was clumsy.

Now we simply style the :after pseudo element - which is a virtual element created by the browser to represent the last child item in a parent. It can be styled to do things like clearing floats.

Do you mean css ".row::after" will provide the whole menu to jump to next line and displayed it after the image ? Thx
The row::after style will ensure that the header is on its own row and that now floated items in the header will cause content AFTER the header to appear NEXT to the header instead of UNDERNEATH it.
To test my understand, does it mean "row::after" ensure that all elements within "class=row" appear in a single line, similar to the following :

<div class="row">
   <div style="float: left; width: 50%;">...</div>     --> banner image
   <div style="float: left; width: 50%;">...</div>    -->  horizontal menu
   ::after
</div>

<div class="row">                                    
   <div style="float: left; width: 50%;">...</div>     --> vertical menu
   <div style="float: left; width: 50%;">...</div>
   ::after
</div>

Thx again.
To test my understand, does it mean "row::after" ensure that all elements within "class=row" appear in a single line, similar to the following :
No, ::after does nothing on it's own - it is just there for you to style if you need to - it acts like an element that is there but it is not actually there - however if you style that has an effect on the document.

Other than that it does nothing to your your page.

I have created a working sample here that demonstrates the concepts.
http://www.marcorpsa.com/ee/t3559.html

I recommend you that you use the Inspect Window (F12) to open the console and view the HTML in the Inspector and the corresponding styles.
After adding the ".row::after" in CSS, the header background-color (blue color) can be displayed back. Before adding, what style prevent it from display the header color and show Body color instead ?

Thx again.

.row::after{
      clear:both;
      content: "";
      display: table;
}
Before.png
After.png
Test.zip
In your sample do this
In Firefox
Press F12
In the inspector window find the <header> tag (right after the <body> tag)
In the <header> tag find the ::after pseudo element click on it.
On the right in the Styles window - find the :after style
On the left of the clear:float click the checkbox off and on and off ...

Notice how the menu changes

If you click on the <ul> element in the <header> and click OFF the float: left on the right you will see how the menu will render without floats.

When floats are on the content on the page is going to try and sit next to each other. When you clear the float (on the ::after pseudo element) the float is terminated and document flow continues on the next row.
I mean the background color in the header section.  Why he body color will fill up if there is no "floating". I suppose the area surrounding the horizontal menu should be blue as the menu is located in the header section where the color is blue....

Thx again.
Before.png
After.png
ASKER CERTIFIED SOLUTION
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
A normal container element (that effectively has "display:block")  will not grow in height to accommodate its floated descendants unless something is done to "clear" them, so what you're seeing is its height is less than you expect, and as a result, its background does not extend behind the floated elements until they are cleared.

CSS3 Flex box, with inline-block fallback, is being used instead of floats in a lot of similar cases these days.