2

:target {
  border: 2px solid #D4D4D4;
  background-color: #e5eecc;
}
.navigation li {
  list-style-type: none;
  float: left;
  padding: 1em;
}
<ul class="navigation">
  <li> <a href="#help"> Help </a> 
  </li>
  <li> <a href="#about"> About us </a> 
  </li>
</ul>

<p>lorem ipsum</p>

<br/>

<p id="help"><b> Help yourself man </b>
</p>
<p id="about"><b> We're free software lovers </b>
</p>

If we inspect the above snippet (using dev tool) ul and p elements both are display:block under user agent stylesheet. Nothing is applied in element.style and none of them have float:left

Yes, the float is applied to li not ul and removing float:left from .navigation li class will fix the problem.

p and ul both are block elements then why they're behaving as inline elements? Not adding a new line break.

I'm not looking for a fix, I need to understand the concept behind this.

Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219
  • 1
    float to the li is causing the Home and About us to be displayed inline – Sherin Mathew Jan 05 '16 at 07:06
  • 1
    The real reason here is that you are *not* clearing the floats. Easiest would be to add an `overflow:hidden` to the parent i.e. the `ul` in this case. More info here - https://css-tricks.com/the-how-and-why-of-clearing-floats/ – Abhitalks Jan 05 '16 at 07:20
  • @Abhitalks 2 different block elements (as showing in [dev](https://developer.chrome.com/devtools%5C) tool) shall not be in single line. So, how're `ul` and `p` shown in single line. What is the concept here? – Zameer Ansari Jan 05 '16 at 07:24
  • @student: From the snippet you posted in the question above, the `ul` and the `p` are not in single line. The problem which I see is that the `ul` appears after the first `p`. And that is because of the non-clearing floats. For more details about how floats affect this problem, read this - https://css-tricks.com/all-about-floats/ – Abhitalks Jan 05 '16 at 07:26

4 Answers4

5

Solution

Add clear: left to the p tag. This will cause it to drop below the left floated elements before it.

Use Nicolas Gallagher's micro clearfix on the ul tag:

.cf:before,
.cf:after {
  content: " "; /* 1 */
  display: table; /* 2 */
}

.cf:after {
  clear: both;
}

/**
 * For IE 6/7 only
 * Include this rule to trigger hasLayout and contain floats.
 */
.cf {
  *zoom: 1;
}

This will cause the ul tag to expand to the size of the li elements it contains.

Explanation

The floated elements don't take up space in the document flow, so the element they are wrapped in, ul in this case, won't grow to take up space, so it is 0 px high.

The p tag comes right after the ul, which takes up no space, so it appears right at the top.

The li tags float to the left, which means they slide over to the left and push everything to their right that can be pushed over to the left. In this case, the p tag.

  • What is the point of the clearfix here? The `p { clear:left; }` alone is sufficient to get the first p element to be positioned below the floated li elements. – Alohci Jan 05 '16 at 07:46
  • @Alohci I also feel that [clearfix](http://stackoverflow.com/a/25343280/2404470) is better than just [`clear:left`](https://jsfiddle.net/xameeramir/ztx0z7qc/). – Zameer Ansari Jan 05 '16 at 08:00
  • @student - clearfix is not "better" than just `clear:left` but it serves a different purpose. The purpose of a clearfix is to extend the bottom of the container element box to be at least the bottom of the last floated element it contains. This is helpful when you want to put either a background or a border on the container element. But in your example, you're doing neither. – Alohci Jan 05 '16 at 08:29
  • @Alohci I'm interested in the concept. Can you explain [it](http://stackoverflow.com/q/34605941/2404470)? – Zameer Ansari Jan 05 '16 at 08:31
  • @student - sadly no. The problem is that your understanding of "inline" is wrong. An inline box is a box that is laid out inside a line box, which is different from the concept of boxes being laid out next to one another horizontally. Floated elements are not laid out in line boxes and are therefore not "inline". You need a solid grounding in the box model and *normal flow* first, Then you can learn how floated elements are taken out of that flow and how line boxes, but not non-cleared block boxes, avoid the floated elements. – Alohci Jan 05 '16 at 08:39
  • @Alohci the reason I included the clearfix is that the original question asked "`p` and `ul` both are **block** elements then why they're behaving as **inline** elements?" The clearfix will make the `ul` _appear_ more block-like. Maybe not necessary, but could help in the future. – tristanslater Jan 06 '16 at 19:06
1

Yup

Remove Float:left from .navigation li class

Hi student,

li not behaving like an inline element, it's Block element Itself. if a Block element with Float:left always align back to back.

http://www.impressivewebs.com/difference-block-inline-css/

From this Clearly you can understand what exactly a inline and Block element

Dinesh Kanivu
  • 2,551
  • 1
  • 23
  • 55
1

The problem is that all of the elements inside the ul are floated, so the ul behaves as if it has no content.

One solution, if you want the lis to remain on a single line, would be to use display: inline instead of float: left on them.

:target {
  border: 2px solid #D4D4D4;
  background-color: #e5eecc;
}

.navigation li {
  list-style-type: none;
  display: inline;
  padding: 1em;
}
<ul class="navigation">
  <li> <a href="#help"> Help </a>
  </li>
  <li> <a href="#about"> About us </a>
  </li>
</ul>
<p>lorem ipsum</p>
<br/>
<p id="help"><b> Help yourself man </b></p>
<p id="about"><b> We're free software lovers </b></p>
Abhishek Pandey
  • 13,302
  • 8
  • 38
  • 68
Jeremy Rans
  • 211
  • 1
  • 5
1

You can also add a clear:left style after the Floated li that will solve the problem.

Kaku Sarmah
  • 171
  • 7