Tips for evenly and fully stretching a set number of horizontal navigation items across a designated container

I want to evenly distribute 6 navigation items across a 900px container, with equal amounts of white space between each item. Here is an example:

---| 900px Container |---

---| HOME    ABOUT    BASIC SERVICES    SPECIALTY SERVICES    OUR STAFF    CONTACT US |---

Currently, the method I am using for this layout is as follows:

nav ul {
  width: 900px; 
  margin: 0 auto;
}

nav li {
  line-height: 87px;
  float: left;
  text-align: center;
  width: 150px;
}

The main ISSUE with this approach is twofold. Firstly, it does not truly justify the items but instead spreads them evenly within the ul tag, creating uneven white-space between smaller menu items like "HOME" or "ABOUT" and larger ones like "BASIC SERVICES".

The second issue arises when a navigation item exceeds 150px in width, which is the case for SPECIALTY SERVICES - even though there is ample space available in the entire nav.

Is there a solution to this problem? I have searched extensively online for solutions, but none seem to provide a satisfying answer. Preferably looking for CSS / HTML only solutions...

Thank you!

UPDATE (7/29/13): The most efficient modern way to achieve this layout is by using table-cell. Refer to felix's response below for implementation. The table cell property is supported by 94% of current browsers. You may need to address compatibility issues with IE7 and older versions, but overall it should work fine.

UPDATE (7/30/13): Unfortunately, there is a known webkit bug that affects this layout when combined with Media Queries. As of now, it's best to avoid changing the 'display' property. Please refer to Webkit Bug for more information.

UPDATE (7/25/14): There is an improved solution provided below involving text-align: justify. This method is simpler and avoids the Webkit bug mentioned earlier.

Answer №1

If you want to evenly distribute items in a modern way, simply apply the following two declarations to the container element:

.container {
  display: flex; /* (1) */
  justify-content: space-between; /* (2) or space-around or space-evenly */ 
} 

The choice of value for justify-content will depend on the type of even distribution required.

https://i.stack.imgur.com/cyl7m.png

Check out MDN for more information.

ul {
  list-style: none;
  padding: 0;
  width: 90vw;
  border: 3px solid gold;
  display: flex;
}
a {
  background: gold;
}
ul {
  justify-content: space-between;
}
ul ~ ul {
  justify-content: space-around;
}
ul ~ ul ~ ul {
  justify-content: space-evenly;
}
<h3>justify-content: space-between; </h3>

<ul id="nav">
  <li><a href="#">HOME</a></li>
  <li><a href="#">ABOUT</a></li>
  <li><a href="#">BASIC SERVICES</a></li>
  <li><a href="#">OUR STAFF</a></li>
  <li><a href="#">CONTACT US</a></li>
</ul>
<div>Even distribution of items with start and end flush </div>
<hr>
<h3>justify-content: space-around;</h3>
<ul id="nav">
  <li><a href="#">HOME</a></li>
  <li><a href="#">ABOUT</a></li>
  <li><a href="#">BASIC SERVICES</a></li>
  <li><a href="#">OUR STAFF</a></li>
  <li><a href="#">CONTACT US</a></li>
</ul>
<div>Even distribution with half-size spacing at ends</div>
<hr>
<h3>justify-content: space-evenly;</h3>
<ul id="nav">
  <li><a href="#">HOME</a></li>
  <li><a href="#">ABOUT</a></li>
  <li><a href="#">BASIC SERVICES</a></li>
  <li><a href="#">OUR STAFF</a></li>
  <li><a href="#">CONTACT US</a></li>
</ul>
<div>Even distribution with equal spacing around each item</div>
<hr>


If using a flex container is not possible, here's an alternative approach:

Apply text-align:justify to the container. This will ensure even distribution regardless of the number of elements in your list (eliminating the need to calculate % widths for each list item).

    #nav {
        text-align: justify;
        min-width: 500px;
    }
    #nav:after {
        content: '';
        display: inline-block;
        width: 100%;
    }
    #nav li {
        display: inline-block;
    }
<ul id="nav">
    <li><a href="#">HOME</a></li>
    <li><a href="#">ABOUT</a></li>
    <li><a href="#">BASIC SERVICES</a></li>
    <li><a href="#">OUR STAFF</a></li>
    <li><a href="#">CONTACT US</a></li>
</ul>

Check out this FIDDLE for a visual representation

Answer №2

This method has proven to be effective and versatile. One great advantage is the ability to utilize media queries to easily switch between horizontal and vertical layouts, especially useful for mobile devices.

HTML

<ul id="nav">
    <li><a href="#">Link</a></li>
    <li><a href="#">Link</a></li>
    <li><a href="#">Link</a></li>
    <li><a href="#">Link</a></li>
    <li><a href="#">Link</a></li>
    <li><a href="#">Link</a></li>
</ul>

CSS

​
#nav {
    display: table;
    height: 87px;
    width: 100%;
}

#nav li {
    display: table-cell;
    height: 87px;
    width: 16.666666667%;  /* (100 / numItems)% */
    line-height: 87px;
    text-align: center;
    background: #ddd;
    border-right: 1px solid #fff;
    white-space: nowrap;
}​

@media (max-width: 767px) {
    #nav li {
        display: block;
        width: 100%;
    }
}

http://jsfiddle.net/timshutes/eCPSh/416/

Answer №3

To create a responsive layout, consider using flexbox:

<ul>
    <li>HOME</li>
    <li>ABOUT US</li>
    <li>SERVICES</li>
    <li>PREVIOUS PROJECTS</li>
    <li>TESTIMONIALS</li>
    <li>NEWS</li>
    <li>RESEARCH &amp; DEV</li>
    <li>CONTACT</li>
</ul>

ul {
  display: flex;
  justify-content:space-between;
  list-style-type: none;
}

View the code on jsfiddle: http://jsfiddle.net/RAaJ8/

Check browser compatibility for flexbox here: http://caniuse.com/flexbox

Answer №4

Here are the key components of an ideal solution:

  1. It should automatically adjust to fit the width of the navigation container
  2. It should be able to support a dynamic number of menu items.

To achieve these requirements, we can create a simple menu using a ul inside a nav container.

HTML

<nav>
  <ul>
    <li>Home</li>
    <li>About</li>
    <li>Basic Services</li>
    <li>Specialty Services</li>
    <li>Our Staff</li>
    <li>Contact Us</li>
  </ul>
</nav>

To ensure that the ul takes up the full width of its parent nav, we can use the :after pseudo-element with width: 100%.

Although this solution works well, it may create unwanted whitespace from the pseudo-element. To eliminate this issue in all browsers including IE8, simply set the line-height of the ul to 0 and then revert it back to 100% on its li child elements. Check out the example CodePen and the CSS solution below:

CSS

nav {
  width: 900px;
}

nav ul {
  text-align: justify;
  line-height: 0;
  margin: 0;
  padding: 0;
}

nav ul:after {
  content: '';
  display: inline-block;
  width: 100%;
}

nav ul li {
  display: inline-block;
  line-height: 100%;
}

Answer №5

After experimenting with various solutions, I concluded that this is the most straightforward and adaptable option I could come up with, drawing inspiration from others.

HTML

<div id="container">
<ul>
    <li>HOME</li>
    <li>ABOUT US</li>
    <li>SERVICES</li>
    <li>PREVIOUS PROJECTS</li>
    <li>TESTIMONIALS</li>
    <li>NEWS</li>
    <li>RESEARCH &amp; DEV</li>
    <li>CONTACT</li>
</ul>
</div>

CSS

div#container{
  width:900px;
  background-color:#eee;
    padding:20px;
}
ul {
    display:table;
    width: 100%;
    margin:0 0;
    -webkit-padding-start:0px; /* reset chrome default */
}
ul li {
    display:table-cell;
    height:30px;
    line-height:30px;
    font-size:12px;    
    padding:20px 10px;
    text-align: center;
    background-color:#999;
    border-right:2px solid #fff;
}
ul li:first-child {
    border-radius:10px 0 0 10px;
}
ul li:last-child {
    border-radius:0 10px 10px 0;
    border-right:0 none;
}

You can choose to remove the rounded ends for first/last child elements, but they add a nice touch (especially for your client's preference).

The container width sets the limit for the horizontal list, but you have the flexibility to assign an absolute value to the UL element instead.

Feel free to tweak it as needed...

http://jsfiddle.net/tobyworth/esehY/1/

Answer №6

Here is a solution that should work for you.

<div id="menu-wrap">
    <ul id="menu">
        <li><a href="#">Home</a></li>
        <li><a href="#">About</a></li>
        <li><a href="#">Services</a></li>
        <li><a href="#">Portfolio</a></li>
        <li><a href="#">Contact</a></li>
    </ul>
</div>

#menu-wrap {
    float: left;
    height: 87px;
    width: 900px;
}

#menu {
    display: inline;
    height: 87px;
    width: 100%;
}

.menu-item {
    float: left;
    height: 87px;
    line-height: 87px;
    text-align: center;
    text-decoration: none;
    width: 150px;
}

Answer №7

Have you experimented with adjusting the li width to 16% and adding a margin of 0.5%?

nav li {
  line-height: 87px;
  float: left;
  text-align: center;
  width: 16%;
  margin-right: 0.5%;
}

Note: Consider setting the UL width to 100%:

nav ul { width: 100%; margin: 0 auto; }

Answer №8

The CSS flexbox model comes in handy for situations like this, allowing you to evenly distribute the remaining width among each li element.

Answer №9

After experimenting with various methods, I discovered that the most effective solution for me was incorporating padding-right: 28px;

I tested different padding settings to achieve a balanced spacing between items.

Answer №10

One way to maintain consistent spacing is by adding a margin-left to your list items instead of defining the width. Ensure that the combined margin(s) and list item widths fit within 900px.

nav li {
  line-height: 87px;
  float: left;
  text-align: center;
  margin-left: 35px;
}

I hope this suggestion proves helpful.

Answer №11

<!DOCTYPE html>
<html lang="en">
<head>
<style>
#layout { width: 100%; border: 1px solid gray; display: block; text-align: justify; }
element, div { display: inline-block; }
div { width: 100%; }
</style>
</head>

  <div id="layout">
    <element>
      <div>
        apple
      </div>
    </element>
    <element>
      <div>
        banana
      </div>
    </element>
    <element>
      <div>
        cherry
      </div>
    </element>
    <element>
      <div>
        date
      </div>
    </element>
    <element>
      <div>
        fig
      </div>
    </element>
    <element>
      <div>
        grapefruit
      </div>
    </element>
    <div></div>
  </div>
</html>

Answer №12

While it may not be the most conventional use of html, one possible solution is to utilize a table for navigation.

CSS:

table.navigation {
    width: 990px;
}
table.navigation td {
    text-align: center;
}

HTML:

<table cellpadding="0" cellspacing="0" border="0" class="navigation">
    <tr>
        <td>HOME</td>
        <td>ABOUT</td>
        <td>BASIC SERVICES</td>
        <td>SPECIALTY SERVICES</td>
        <td>OUR STAFF</td>
        <td>CONTACT US</td>
    </tr>
</table>

Although using tables in this manner is not its intended purpose, until more efficient solutions like flexbox or other methods become widely supported, it may suffice temporarily.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can we sort an array based on the inner HTML values of its children elements in JavaScript?

Can you arrange a JavaScript array based on the innerText values of its HTML elements? I am generating a div element (class="inbox" id="inbox${var}") with a number as its innerText, then adding all these divs to an array (numArr). I wan ...

Having trouble getting the Pokemon modal to show both the type and image?

HTML: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>My First JS App</title> <lin ...

Unable to apply background-color CSS in playwright is not working as expected

I have been encountering an issue with applying the background-color CSS property in a Python template using the playwright package. I initially attempted to apply inline CSS style="background-color:red", then tried using a script tag with JavaScript, an ...

typescript is failing to update CSSRule with the newly assigned background-color value

I am currently working on dynamically changing the CSS style (specifically background-color) for certain text on a webpage. To achieve this, I have been attempting to modify CSSRule by accessing the desired CSSRule based on selectedText. Here is the code s ...

Hide the selection box when hovering over the Div

Looking for a quick solution. I want the option drop down to close when another div element is hovered over. First, open the drop down and hover over the red element on the right side. When hovering over the red element, I would like the drop down to clos ...

Checking the Value of the Second Child Element Using jQuery

I am struggling with a DIV structure that looks like this: <div class="metafield_table"> <div class="metafield"></div> <div class="metafield"></div> <div class="metafield"> ...

PHP: Bootstrap CSS for Carousels

I'm experiencing some difficulties with the Bootstrap CSS Carousel on my website. The left and right arrows seem to be unresponsive, and the slides are not transitioning automatically. I have been unable to identify the root cause of this issue. Belo ...

What is the best method to center a div on the screen?

Is there a way to have a div open in the center of the screen? ...

What could be causing this `even` function to malfunction when utilizing getElementById?

Need assistance with utilizing document.getElementById? Let's take a look at this code snippet: function even() for (i = 0; i < 10; i++) { if (i % 2 == 0) { alert(i); } } document.getElementById("even").innerHTML = i + &apos ...

Adjusting the Scaling Value to Match the Browser's Scaling Value

I'm struggling with a problem in HTML where the initial-scale function is not working as expected. When I zoom in on certain pages, it saves the zoom level. However, when I navigate to another page and then return to the original one, the zoom level r ...

Utilizing CSS to place an image on top of the upcoming <div> container

My goal is to create a layout similar to the one displayed in the linked image. https://i.stack.imgur.com/7DSE9.jpg Currently, I am using Bootstrap 3 and my HTML markup looks like this: <body class="gray-bg"> <section class="white-bg"> <d ...

Issues with the functionality of the submit button (html, js, php)

Seeking assistance with a submit button functionality issue - I have a simple submit button that allows visitors to enter their email address. Upon clicking the button, it should add their email to a CSV file and display a pop-up thank you message. The pr ...

Tips for successfully passing an image using props in Vuejs without experiencing the issue of disappearing content when there is no image present

Is there a way to make a component that can function with or without an image? Currently, when the component doesn't have an image, other contents and styles disappear. How can I resolve this issue? App.Vue: <template> <div id="app&qu ...

Ensuring proper alignment and dimensions of tables

It's interesting to note that one of my tables is a different size than the other. My initial question is: why is this the case? I have set the width of the <th> in the top table to 100/300/100/100/100 (=700), and in the bottom table 500/100/10 ...

Navigating with Anchors, Styling and jQuery

Firstly: Apologies in advance for any language errors as English is not my native tongue. :) The Scenario Here's the deal: I'm attempting to create a single button that, when clicked by the user, automatically scrolls down to the next DIV. Each ...

Adding data to the SharePoint RichText Control using the WinForms WebBrowser Control

I am struggling to modify the content of an SP Rich Text field using the WinForms web browser control. While changing the values of other controls is straightforward, I have encountered difficulties with Rich Text fields. I found some suggestions on this b ...

How can I trim a value using one-way data binding in Angular?

Is there a way to trim values in Angular using one-way data binding? Can this be done directly in the component.html file rather than in typescript? I tried the following but it didn't work: <P>{{country.trim()}}</P> Thanks ...

Is there a way to modify the scroll ion-content's color scheme?

Is there a way to change the scroll color in Ionic to green, specifically for ion-content? Any suggestions on how I can achieve this? Below is my HTML code: <ion-header> <ion-toolbar> <ion-buttons slot="start"> ...

Ways to incorporate a dynamic HTML form that allows for input elements to be added both horizontally and vertically while maintaining connected lines

Looking to design a form that showcases HTML elements in both vertical and horizontal positions, with lines connecting them as seen in this example: https://i.sstatic.net/jB12f.png. Can anyone offer guidance on how to achieve this? Thanks! ...

"Optimizing App Pool Performance with IIS Precache Event Monitoring

Our asp.net LOB web application is quite large. The issue we are facing is the delay of up to 10 seconds when the app pool is started or recycled, making the first page load slow. This results in users seeing a white page with a loading spinner until IIS ...