5

Update: Why the divs are appearing as they do is more important than how to remove the problem. If I don't know why the divs are appearing the way they do I won't get an understanding of how the divs work.


I have two div's: menuContainer and top, and they are wrapped in another div called topContainer.

I want menuContainer and top to be under one another vertically, not on the X angle (and I thought it was standard for divs to appear under one another) but they appear both on top of each other and "inline".

This is what it looks like in my browser (yes I've f5:ed and the fiddle shows the same thing):

menuContainer is a wrapper for a horizontal CSS menu. I want it to appear as tabs on top of the white area that is top

Why are the divs appearing "inline" (look at where hello is located) and how do I edit it to look like I want it to?

body {
  background-color: #c2b074;
  color: #40371c;
  margin: 0px;
  font-family: Calibri;
}
/* Menu CSS */

#menuContainer {
  margin: 4em auto;
  background-color: #000000;
  width: 600px;
}
#navMenu {
  margin: 0px;
  padding: 0px;
}
#navMenu ul {
  margin: 0px;
  padding: 0px;
  list-style-type: none;
  text-align: center;
  background-color: #d4cbab;
}
#navMenu li {
  display: inline;
}
#navMenu a {
  float: left;
  text-decoration: none;
  color: #40371c;
  width: 6em;
  padding: 0.3em;
  margin: 0 1.2em 0 0;
  background-color: #d4cbab;
  border-radius: 10px 10px 0px 0px;
}
#navMenu a:hover,
#navMenu a#cart:hover,
#navMenu a#contact:hover,
#navMenu a#home:hover {
  background-color: #efefef;
  color: #40371c;
}
#navMenu a#current {
  background-color: #efefef;
}
#navMenu a#contact {
  background-color: #d4cbab;
}
#navMenu a#cart {
  background-color: #6a6145;
  color: #c2b074;
}
#navMenu a#home {
  background-color: #40371c;
}
/* Top content CSS */

#top {
  clear: left;
  width: 650px;
  height: 100px;
  margin: 0 auto;
  background-color: #efefef;
  border-radius: 10px 10px 0px 0px;
}
<div id="topContainer">
  <div id="menuContainer">
    <div id="navMenu">
      <ul>
        <li> <a href="index.html" id="current">Home</a>

        </li>
        <li> <a href="#" id="contact">Contact</a>

        </li>
        <li> <a href="#" id="cart">Cart</a>

        </li>
      </ul>
    </div>
  </div>
  <div id="top">
    Hello
  </div>
</div>

The tutorial the CSS menu is based on is this one.

Unihedron
  • 10,902
  • 13
  • 62
  • 72
Gemtastic
  • 6,253
  • 6
  • 34
  • 53
  • 6
    which ones are you talking about? – jmore009 Jan 02 '15 at 06:34
  • 1
    [Because of this](http://stackoverflow.com/questions/16568272/how-does-css-float-work-why-doesnt-the-height-of-a-container-element-increase/16568504#16568504) – Mr. Alien Jan 02 '15 at 06:37
  • @Mr.Alien But `menuContainer` is not floated, only its content. I tried adding `clear: left` to `top` but it does nothing. – Gemtastic Jan 02 '15 at 06:40
  • I thought the code was pretty self explanatory, I will stop assuming that and fix the original to be more clear. – Gemtastic Jan 02 '15 at 06:42
  • The `top` is below the `menucontainer`. What is the problem? – Abhitalks Jan 02 '15 at 06:44
  • @abhitalks the problem is that top does not appear below menuContainer, it appears next to it. – Gemtastic Jan 02 '15 at 06:46
  • like @abhitalks mentioned, I am seeing the menu on top and then the content from the top div below it. I don't see any issues.. try hitting ctrl+F5 to force load the css (in case if it is cached in the local) – Thangadurai Jan 02 '15 at 06:51
  • What browsers are you people using because it does not appear like that to me. I added a picture of how it appears to me in firefox 34.0.5. – Gemtastic Jan 02 '15 at 06:52
  • @Gemtastic I tested with IE10 – Thangadurai Jan 02 '15 at 06:56
  • You do realize that you've set `margin: 4em auto;` to `#menuContainer` and expecting the below `#top` to be stacked? That's you main issue. – Roko C. Buljan Jan 02 '15 at 06:59
  • @RokoC.Buljan Thank you, now we've identified where the error lies, now, write mean answer with WHY it doesn't stack because of the margin-top and I will consider this question answered :) – Gemtastic Jan 02 '15 at 07:02
  • Sorry, my bad. The pic is taken from my source code which does not contain the word hello. Fixed it with a pic from the fiddle. – Gemtastic Jan 02 '15 at 07:15
  • @Gemtastic play with this demo: http://jsbin.com/kikowi/2/edit with less code reflects your exact issue. – Roko C. Buljan Jan 02 '15 at 07:31
  • @RokoC.Buljan Now you're getting to what I want to know. Would you please take that fiddle and write a more elaborate answer so I can accept it? – Gemtastic Jan 02 '15 at 07:36
  • @Gemtastic created my answer. Hope that this mysterious `margins` issue on collapsed elements will make sense. – Roko C. Buljan Jan 02 '15 at 07:43

4 Answers4

2

How to properly setup horizontal navigation using CSS? here's a demo: jsBin demo

Your #top is Escaping Margins
due the collapsed (but with margins) previous element #menuContainer. Collapsed due the use of inner floated LI elements.

I've created a small demo (with less code) that reflects your issue; and 3 solutions

jsBin demo

<div id="parent">

  <div id="nav">
    <ul>
      <li><a href="#">link 1</a></li>
      <li><a href="#">link 2</a></li>
    </ul>
  </div>

  <div id="top">TOP ELEMENT</div>

</div>

/* Follow the steps. */
#parent{
  background:red; /* red color is visible cause #top has non-floated content */
}
#nav {
  background:gold;
  /* Can you see any GOLD background? 
     NO! cause UL height collapsed cause of floated LI
     So did the #nav height*/
}
#nav ul {
  padding:0;
  margin:0;
  background: #000;
  /* Can you see any BLACK background? NO!
     cause floated LI made the UL collapse */
}
#nav li {
  float:left; /* This line made UL collapse */
}
#nav{ /* (#nav again, I know, it's just to keep-on with steps) */
  /* margin:4em auto; /* Uncomment this line to add the margins */
      /* See the issue now? #nav is height 0 cause everything inside #nav is
      collapsed so #top moved to the nearest available position. */
  /* overflow:auto;   /* Uncomment this line to fix */
}
#top{
  clear:left;
}
/* Solutions:
1) instead of using floated LI make the `display:inline-block;`
2) don't set margin to #nav
3) set overflow:auto to #nav
4) Set height to the collapsed #nav but you'll get again issues if you make your design responsive. */

Worth noting that clear:left; (on the #top element) is not needed in case you use the LI set to inline-block or you use the overflow:auto; trick.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
  • I don't know if it makes any difference, but in my code, it's the `a` element that's floated, not `li`. Clear – Gemtastic Jan 02 '15 at 07:50
  • @Gemtastic same thing bro. Should be clear from above that as soon a children is floated (inside a parent that has no height set) will make it collapse. If that parent is collapsed the outher parent will also collapse and so on and so on. – Roko C. Buljan Jan 02 '15 at 07:55
  • Also, `clear: left;` is in my original snippet. It does nothing. – Gemtastic Jan 02 '15 at 07:55
  • @Gemtastic exactly, so is in my example. And yes, it does nothing cause it's Escaping Margins Issue (element with no height has margins.) – Roko C. Buljan Jan 02 '15 at 07:56
  • @Gemtastic added a third solution to my answer. – Roko C. Buljan Jan 02 '15 at 08:00
  • @Gemtastic so to add to all, again, your issue-by-design that lead you to all those issues was setting a bottom margin of `4em` where you actually don't need any. Everything else in your code was constructed on that issue. – Roko C. Buljan Jan 02 '15 at 08:08
  • Yes, I noticed that by only removing the margin, the problem completely vanished, but! I don't really get an understanding of why it happened in the first place by only doing that. "there I fixed it" doesn't make for good code. – Gemtastic Jan 02 '15 at 08:15
  • I am also a bit surprised that w3cSchools structured such bad examples on horizontal CSS menus... – Gemtastic Jan 02 '15 at 08:15
  • @Gemtastic please ban and blacklist W3Schools from your bookmarks and favorites (**I really mean that**). W3schools is a **terrible** resource, it's not a community driven website, has nothing related to W3C and during the years they've done just harm to the programming community. They also sell fake diplomas :D – Roko C. Buljan Jan 02 '15 at 08:18
  • It's not in my bookmarks, it's just the first thing to pop up on google :/ – Gemtastic Jan 02 '15 at 08:30
  • @Gemtastic this demo I've created is **the proper** way: http://jsbin.com/weric/1/edit?html,css,output – Roko C. Buljan Jan 02 '15 at 08:37
1

you should really just remove the floats. You don't need them. You can accomplish the same thing with display: inline-block:

FIDDLE

CSS

body {
  background-color: #c2b074; 
  color: #40371c;
  margin: 0px;
  font-family: Calibri;
}
/* Menu CSS */

#menuContainer {
  margin: 4em auto 0;
  width: 600px;
}

#navMenu {
  margin: 0px;
  padding: 0px;
}

#navMenu ul {
   margin: 0 0 0 20px;
   padding: 0px;
   list-style-type: none;
   text-align: left;
}

#navMenu li {
  display: inline-block;
}

#navMenu a {
  display:block;
  text-decoration: none;
  color: #40371c;
  width: 6em;
  padding: 0.3em;
  margin: 0 1.2em 0 0;
  background-color: #d4cbab;
  border-radius: 10px 10px 0px 0px;
}

#navMenu a:hover,
#navMenu a#cart:hover,
#navMenu a#contact:hover,
#navMenu a#home:hover {
   background-color: #efefef;
   color: #40371c;
}

#navMenu a#current {
   background-color: #efefef;
}

#navMenu a#contact {
   background-color: #d4cbab;
}

#navMenu a#cart {
   background-color: #6a6145;
   color: #c2b074;
}

#navMenu a#home {
   background-color: #40371c;
}
/* Top content CSS */

#top {
   width: 650px;
   height: 100px;
   margin: 0 auto;
   background-color: #efefef;
   border-radius: 10px 10px 0px 0px;
}

UPDATE

The issue has nothing to do with margin as some others are proclaiming. Change the margin all you want, if you inspect .menuContainer in developer tools you will see it still has a height of 0. It's collapsed because of the floats. Just remove the floats like I have done in my example and it will work perfectly fine. It's not structured correctly anyways, you have the float on the a tag but their parent the li is the one that needs to be floated or inline. So calling inline on the lis and float: left on the a's is unnecessary.

SCREEN SHOTS

This first shot is your code, with only the margins removed, as you can see it has a height of 0:

enter image description here

This is my code, with no floats, the ul is not collapsed and has a height of 27px:

enter image description here

WRAP UP

SO the issue is not the floats but the way you are using them. The floats should have been added to the parent of a (which is li). The li elements are what needs to be inline. But because of the way your CSS was structured around those floats, your styles got messed up after removing them. I had to restructure a hand full of your CSS classes to get the desired result. In the future be sure that the floats are added to the elements that need to be inline, not their children.

jmore009
  • 12,863
  • 1
  • 19
  • 34
  • That doesn't answer why it appears as it does right now. I agree to that it's probably a better solution with `display: inline-block` but why? – Gemtastic Jan 02 '15 at 06:57
  • @Gemtastic it's because of the floats that you are having such issues. There's just no reason to use them. – jmore009 Jan 02 '15 at 06:59
  • @RokoC.Buljan I changed that to `margin: 4em auto 0;` for that exact reason – jmore009 Jan 02 '15 at 07:01
  • @jmore009 Well, we've concluded that the issue is with the margin applied to `menuContainer`. I think I know why but I want someone else to elaborate why. – Gemtastic Jan 02 '15 at 07:04
  • @Gemtastic that's not the issue at all. Set the margin to `0 auto` and you still have the same issue. It just moves up: [http://jsfiddle.net/qdj0zz3d/](http://jsfiddle.net/qdj0zz3d/) – jmore009 Jan 02 '15 at 07:07
  • @jmore009 don't use floats? That's why we have `clear` – Roko C. Buljan Jan 02 '15 at 07:20
  • I don't think you're right (though you are onto something with the floats, but no they're not the problem). When I only shifted the 4em from the margin of `menuContainer` to `topContainer`'s top margin it looks like this: http://i60.tinypic.com/2e3vqqp.jpg – Gemtastic Jan 02 '15 at 07:22
  • 1
    @RokoC.Buljan I have no issues with floats, and im not advocating not to use them, I use them all the time. In this case they're not necessary and they're throwing OPs code off because he/she didnt structure it right anyways – jmore009 Jan 02 '15 at 07:22
  • @Gemtastic im 100% sure you're having issues because of the floats. I updated my post again, you're not using them correctly anyways. The `a` tags have the float and the `li`s are set to `inline`, that makes no sense. Inspect the console...you'll see what im saying, the `ul` (and the `li`s) are collapsed and thats why your divs...which are `block` inherently...are not stacking. I provided you with code that has removed the floats and still has your margin...and it works...so im not sure how you can say thats not the issue... – jmore009 Jan 02 '15 at 07:24
  • Yes, I am having issues because of the floats (I have figured this all out, I just want someone else to explain it in a deeper meaning as to WHY this happens. The menu is based on a tutorial, they had the floats there. Now, if you could write a new answer which explains this whole mess from A to B and why it doesn't affect topContainer, I'd be very happy. – Gemtastic Jan 02 '15 at 07:31
  • And also, why it works perfectly fine when you only remove the top margin from menuContainer. – Gemtastic Jan 02 '15 at 07:33
  • @Gemtastic updated my answer. And it doesn't, maybe it works for you, I couldnt even recreate the issue you posted in your image...so theres just something odd about this and whatever browsers we're all using. But I can assure you the issue had nothing to do with margin. Margin would never cause divs to overlap like that unless it was a negative margin (which you're not using) – jmore009 Jan 02 '15 at 07:39
  • I know the issue has nothing to do with the margin itself, but why would it trigger that behavior in the divs is what I wanted to know. It has pretty much been answered, I just want a clean good answer that explains it all in a proper manner, not "Just write this code and it'll be fine". What exactly will I or anyone reading my question learn out of that? – Gemtastic Jan 02 '15 at 07:41
  • @Gemtastic I dont have an answer because I havent been able to recreate that margin thing, so I'm not sure whats going on with that. But plain and simple this is an issue of floats being used in the wrong place and then not being cleared correctly. – jmore009 Jan 02 '15 at 07:44
1

you need to change the margin its overlap to next div

#menuContainer {
    background-color: #000000;
    margin: 4em auto 0;/*changes*/
    width: 600px;
}
Sathish
  • 2,440
  • 1
  • 11
  • 27
  • Thank you! But why does this happen? Why does the margin affect the `top` div? – Gemtastic Jan 02 '15 at 07:00
  • if you use a margin:4em auto; use height its avoid that problem – Sathish Jan 02 '15 at 07:06
  • If I add height to the `menuContainer` I get the issue of that I must adjust the exact height of the div to the exact height of the menu. As it is now, I assume it just wraps to the menu's size. – Gemtastic Jan 02 '15 at 07:10
1

Now, just for the sake of writing the answer I wanted to read (and hopefully can help other people learn what just happened here)

The quick fix

Removing the margin from menuContainer and adding it to topContainer will "solve" the problem visually and "look" as you want it to, but it's still bad code as the reason for the behavior is still there.


Why does margin trigger the behavior?

The problem (which we'll get to below) is triggered because the margin pushes the menu down, and when the content in top is being pushed upon, it will find a space to appear where there is one.


The problem

The piece of code that causes this mess:

#navMenu a {
    float: left;
}

The issue here is that the element a has gotten all the properties, for no good reason. And what happens here is that it collapses the parent element. A collapse makes the entire element "unseen" and useless.

What float does is that it removes the standard block-property that normally makes up the behavior for the li elements, and it causes the a elements to gather on one line. This is the desired effect, but it also collapses the parent element li, which looks like this:

#navMenu li {
    display: inline; /*This doesn't do anything because of the collapse!*/
}

The collapse carries on upwards to ul where the margins are intentionally collapsed with the attribute margin: 0px;. menuContainer is collapses in all places but it's top. The a elements are floating on top of nothing. So for all purpouses, it too has been collapsed.

This chain-reaction has collapsed the entire menu into topContainer, where top now is laying more or less on top of the a elements, but it's being pushed off by their attributes. The a elements are the only things not collapsed.

Imagine that all that exists to the browser are the loose floating a elements, and they have no margin nor padding to the parent div.

There's an attempt to deal with this issue here:

#top {
    clear: left;
}

However, what clear does is that it checks for floated content to the stated position of it (left in this case) and tells it to "stay clear of it" by moving the border edge down, but a has collapsed li entirely, and all the other parents are collapsed too, so there is no border line but the collapsed menu-container's bottom, which is where the top margin ends. Since topContainer is also collapsed, the margin of menuContainer has moved where it can fit; outside of topContainer.

So; the a elements are floting on nothing, but inside of topContainer. The border made by clear happens where it would have been even without it: at the top of topContainer. This is why you can see the box for top's content start where the a elements start, allowing "hello" to pop up next to them.


The solution

The solution for a better version looks like this:

body {
  background-color: #c2b074;
  color: #40371c;
  margin: 0px;
  font-family: Calibri;
}
/* Menu CSS */

#topContainer {
    margin: 4em auto 0 auto;
}

#menuContainer {
  margin: 0 auto;
  width: 300px;
}
#navMenu {
  margin: 0px;
  padding: 0px;
}
#navMenu ul {
  margin: 0px;
  padding: 0px;
  list-style-type: none;
}
#navMenu li {
  width: 3.5em;
  text-align: center;
  display: inline-block;
  padding: 0.3em;
  margin: 0 0 0 1.5em;
  background-color: #d4cbab;
  border-radius: 10px 10px 0px 0px;
}
#navMenu a {
  text-decoration: none;
  color: #40371c;
  padding: 0;
  margin: 0;
}
#navMenu li:hover{
  background-color: #efefef;
  color: #40371c;
}

/* Top content CSS */

#top {
  width: 350px;
  height: 100px;
  margin: 0 auto;
  background-color: #efefef;
  border-radius: 10px 10px 0px 0px;
}
<div id="topContainer">
  <div id="menuContainer">
    <div id="navMenu">
      <ul>
        <li> 
            <a href="index.html" id="current">Home</a>
        </li>
        <li>
            <a href="#" id="contact">Contact</a>
        </li>
        <li>
            <a href="#" id="cart">Cart</a>
        </li>
      </ul>
    </div>
  </div>
  <div id="top">
    Hello
  </div>
</div>

I removed some unnecessary code. Here you can see a better structure where we are using the li elements as blocks which are to be displayed in line:

#navMenu li {
  display: inline-block;
}

This is the soul place where you need to define that the list elements (or menu buttons) are to be displayed horizontally on the same line.

And just for the sake of it, I left the margin on the menuContainer to show you that that doesn't matter if you put it there or where it should be; in topContainer.

Gemtastic
  • 6,253
  • 6
  • 34
  • 53