user10218786
user10218786

Reputation:

Issue with displaying inline <li> tags for horizontal nav bar

I am hoping someone can help advise me why the li tags don't display on the same line, with the following mark up. i'm not arguing that my markup is right, just why it doesnt work.

body {
  width: 100%;
  margin: 0 auto;
  padding: 0 auto;
}

ul {
  float: right;
  border: 1px solid black;
  width: 100%;
  padding: 0;
}

ul li {
  display: inline-block;
  width: 20%;
  border: 1px solid black;
  text-align: center;
  list-style-type: none;
}

ul li a {
  display: block;
}
<body>
  <header>
    <ul id="nav">
      <li><a href="home">Home</a></li>
      <li><a href="home">About Us</a></li>
      <li><a href="home">Infomration</a></li>
      <li><a href="home">Additional</a></li>
      <li><a href="home">Contact</a></li>
    </ul>
  </header>
</body>

I'm struggling to wrap my head around, having set the width to the ul as 100%, why then setting the width of the 5 li tags to 20%, it can only fit 4 in a line, pushing the remaining li tag underneath.

I can get the nav bar on one line using the display: table etc, but why doesn't the above work?

Apologies if I've laid my question out wrong.

Thanks.

Upvotes: 1

Views: 60

Answers (4)

kenS
kenS

Reputation: 394

The problem is that there is whitespace between the li tags (in the form of the line breaks in your HTML), and because they are inline-block, that whitespace is rendered as a space character, which takes up horizontal space in your layout.

A solution would be to use flexbox rather than display: inline-block to place the lis next to each other.

Quick demo:

body {
    width: 100%;
    margin: 0 auto;
    padding: 0 auto;
}

ul {
    border: 1px solid black;
    width: 100%;
    box-sizing: border-box;
    padding: 0;
    display: flex;
    flex-flow: row nowrap;
    justify-content: center;
    align-items: center
}

ul li {
    flex: 1 1 20%;
    border: 1px solid black;
    text-align: center;
    list-style-type: none; 
}

ul li a {
    display: block;
}
<body>
  <header>
  <ul id="nav">
      <li><a href="home">Home</a></li>
      <li><a href="home">About Us</a></li>
      <li><a href="home">Infomration</a></li>
      <li><a href="home">Additional</a></li>
      <li><a href="home">Contact</a></li>
  </ul>
  </header>
</body>

More info about how to use flexbox at CSS-Tricks

If you absolutely must use inline-block for some reason, an approach (which I would very much recommend against using, it is bad practice to make your layout working or not dependent on little details of your HTML in this way) would be to remove the whitespace in your HTML, either by putting all of the li elements on the same line or by commenting out the whitespace, ie

<li>...</li><li>...</li><li>...</li>

or

<li>...</li><!--
--><li>...</li><!--
--><li>...</li>

Again, this is bad practice since changes to your HTML as simple as adding those whitespaces would break your layout if you did things this way, but just for completeness I wanted to include this in my answer because it is a way that you can make the inline-block styles work if you really must use them (ie people who can't change their CSS but only their HTML), and it helps illustrate what the problem is.

Upvotes: 0

Slagt
Slagt

Reputation: 611

As Brian mentioned, there are invisible spaces between the li elements. In addition to this, you have to use the box-sizing property:

ul li {
    box-sizing: border-box;
}

With this property and this value, the borders of your element will be included in the width: 20%, not added to it.

Upvotes: 0

gazdagergo
gazdagergo

Reputation: 6691

In addition to @Brians's answer, first of all, I agree, please, use flexbox, but if you keep your code you should calculate with the border. So in css either correct the width:

ul li {
  ...
  width: calc(20% - 2px);  /* 2 x 1px border */
  ...
}

or use another box sizing model which do not consider the border:

ul li {
  ...
  box-sizing: border-box;
  ...
}

Upvotes: 0

bcr
bcr

Reputation: 3811

You really should look into creating horizontal nav bars with flexbox. The issue here is that the browser is rendering "invisible space" between your li elements since they're on different lines of the html document. You can get around that with comments:

<ul id="nav">
    <li><a href="home">Home</a></li><!--
    --><li><a href="home">About Us</a></li><!--
    --><li><a href="home">Infomration</a></li><!--
    --><li><a href="home">Additional</a></li><!--
    --><li><a href="home">Contact</a></li>
</ul>

Upvotes: 1

Related Questions