Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Horizontal list items - fit to 100% with even spacing

I have a simple list and i am trying to get the list items to be evenly spaced horizontally, but still fill 100% of the width of the container regardless of the width of the container.

I do not want each list item to be of equal width, but instead the spacing between each list item to be even:

jsfiddle: http://jsfiddle.net/b6muX/1/

Also the number of list items might be dynamic and not the same as the number in my example.

Can this be done without js?

Here is my markup and css:

<ul>     <li>This is menu item 1</li>     <li>Number 2</li>     <li>Item Number 3</li>     <li>Menu 4</li> </ul> 

and the following css:

ul {     width: 100%;     background: #cacaca;     margin: 0;     padding: 0; } li {     list-style-type: none;     display: inline-block;     padding-right: 10%;     width: auto;     margin-right: 0.5%;     background: #fafafa;     padding-left: 0;     margin-left: 0; } li:last-child {     margin-right: 0;     padding-right: 0; } 
like image 912
Marty Wallace Avatar asked Apr 22 '14 17:04

Marty Wallace


People also ask

How do I horizontally align a list?

If you want to make this navigational unordered list horizontal, you have basically two options: Make the list items inline instead of the default block. .li { display: inline; } This will not force breaks after the list items and they will line up horizontally as far as they are able. Float the list items.

How do I reduce space between lists?

The spacing between list items in an orderedlist or itemizedlist element can be minimized by the document author by adding a spacing="compact" attribute to the list element. In HTML output, the list will get a compact="compact" attribute on the list start tag to reduce spacing in the browser.


1 Answers

The new CSS flexbox specification would be the solution to your problem :)

ul {      display: flex;      align-items: stretch; /* Default */      justify-content: space-between;      width: 100%;      background: #cacaca;      margin: 0;      padding: 0;  }  li {      display: block;      flex: 0 1 auto; /* Default */      list-style-type: none;      background: #fafafa;  }
<ul>      <li>This is menu item 1</li>      <li>Number 2</li>      <li>Item Number 3</li>      <li>Menu 4</li>  </ul>

See also: http://jsfiddle.net/teddyrised/b6muX/3/

If you would allow me to indulge myself in a bit of explanation:

  1. display: flex on the parent tells the parent to adopt the CSS flexbox model
  2. align-items: stretch tells the parent that its children should stretch to the full height of the row. This is the default value of the property.
  3. justify-content: space-between is the magic here — it instructs the parent to distribute remaining space left after laying out the children between them.

On the children:

  1. flex: 0 1 auto on the children tells them that:
    • flex-grow: 0: Do no grow, otherwise they will fill up the parent
    • flex-shrink: 1: Shrink when necessary, to prevent overflowing (you can turn this off by setting to 0.
    • flex-basis: auto: Widths of children element are calculated automatically based on their content. If you want fixed, equal width children element, simply set it to 100%.

You can adjust the padding to the <li> element as of when you see please.


Old CSS method: text-align: justify

The old method, while working perfectly, is a little more cumbersome as it requires you to reset the font-size in the unordered list element to eliminate spacing between child elements. It also requires you to render an pseudo-element to ensure that the content overflows the first row for text justification to kick in (remember that the default behavior of justified text is that a row that is not 100% will not be justified).

ul {      font-size: 0; /* Eliminate spacing between inline block elements */      text-align: justify;      width: 100%;      background: #cacaca;      list-style: none;      margin: 0;      padding: 0;  }  ul:after {      content: 'abc';      display: inline-block;      width: 100%;      height: 0;  }  li {      display: inline-block;      background: #fafafa;      font-size: 1rem; /* Reuse root element's font size */  }  p {      font-size: 1rem;  }
<ul>      <li>This is menu item 1</li>      <li>Number 2</li>      <li>Item Number 3</li>      <li>Menu 4</li>  </ul>

See also: http://jsfiddle.net/teddyrised/b6muX/5/

like image 181
Terry Avatar answered Oct 08 '22 18:10

Terry