Как равномерно и полностью растянуть фиксированное количество элементов горизонтальной навигации по указанному контейнеру

Я хотел бы равномерно растянуть 6 навигационных элементов по контейнеру в 900 пикселей с равномерным количеством пустого пространства между ними. Например...

---| 900px Container |---

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

В настоящее время лучший метод, который я могу найти, это сделать следующее:

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

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

ПРОБЛЕМА с этим в два раза. Прежде всего, это на самом деле не оправдывает, а скорее распределяет теги li равномерно по всему тегу ul... создавая неравномерное пространство между небольшими элементами меню, такими как "HOME" или "ABOUT", и большими, такими как "BASIC SERVICES",

Вторая проблема заключается в том, что компоновка ломается, если размер элемента навигации превышает 150 пикселей, каковым является SPECIALTY SERVICES - даже если для всей навигации более чем достаточно места.

Кто-нибудь может решить это для меня? Я искал в Интернете решения, и все они, похоже, терпят неудачу. CSS / HTML только если возможно...

Спасибо!

ОБНОВЛЕНИЕ (29.07.13): Использование табличных ячеек - лучший современный способ реализации этого макета. Смотрите ответ Феликса ниже. table cell свойство работает на 94% браузеров в настоящее время. Вам придется что-то делать с IE7 и ниже, но в остальном все должно быть в порядке.

ОБНОВЛЕНИЕ (30.07.13): К сожалению, есть ошибка веб-набора, которая влияет на это, если вы комбинируете этот макет с медиа-запросами. На данный момент вам нужно избегать изменения свойства display. Смотрите Webkit Bug.

ОБНОВЛЕНИЕ (25.07.14): Ниже приведено лучшее решение, включающее выравнивание текста: выровнять. Использовать это проще, и вы избежите ошибки Webkit.

12 ответов

Решение

Использование text-align:justify в контейнере, таким образом, он будет работать независимо от того, сколько элементов в вашем списке (вы не должны определять% widths для каждого элемента списка

FIDDLE

<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>

CSS

#nav {
    text-align: justify;
    min-width: 500px;
}
#nav:after {
    content: '';
    display: inline-block;
    width: 100%;
}
#nav li {
    display: inline-block;
}

Этот действительно работает. Также есть то преимущество, что вы можете использовать медиазапросы для простого отключения горизонтального стиля - например, если вы хотите расположить их вертикально в мобильном телефоне.

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/

Если можете, используйте 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;
}

jsfiddle: http://jsfiddle.net/RAaJ8/

Поддержка браузера на самом деле довольно хорошая (с префиксами и другими неприятными вещами): http://caniuse.com/flexbox

Идеальным решением будет:

  1. Автоматически масштабируется до ширины навигационного контейнера
  2. Поддержка динамического количества пунктов меню.

Используя простой ul меню внутри nav Контейнер, мы можем построить решение, которое отвечает вышеуказанным требованиям.

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>

Во-первых, нам нужно заставить ul иметь полную ширину его nav контейнер. Для этого мы будем использовать :after псевдоэлемент с width: 100%,

Это прекрасно достигает нашей цели, но добавляет пробел из псевдоэлемента. Мы можем удалить этот пробел во всех браузерах через IE8, установив line-height из ul до 0 и установите его обратно на 100% на его li дети. Смотрите пример CodePen и решение ниже:

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%;
}

Я перепробовал все вышеперечисленное и нашел их нужными Это самое простое и гибкое решение, которое я смог найти (спасибо за все вышеперечисленное за вдохновение).

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;
}

Очевидно, вы можете отбросить первые / последние закругленные концы детей, но я думаю, что они действительно чистые (как и ваш клиент;)

Ширина контейнера ограничивает горизонтальный список, но вы можете отказаться от этого и просто применить абсолютное значение к UL, если хотите.

Поиграйтесь с ним, если хотите..

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

Это должно сделать это для вас.

<div id="nav-wrap">
    <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>
</div>

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

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

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

}

Это то, что исправит модель флексбокса CSS, потому что она позволит вам указать, что каждый li получит равную долю оставшейся ширины.

Вы пытались установить ширину li, скажем, 16% с запасом 0,5%?

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

редактировать: я бы установил UL на 100% ширины:

nav ul {ширина: 100%; поле: 0 авто; }

Я попробовал так много разных вещей и, наконец, нашел то, что лучше всего для меня было просто добавить в padding-right: 28px;

Я поиграл с отступами, чтобы получить правильное количество для равномерного размещения предметов.

Вместо того, чтобы определять ширину, вы можете просто наложить поле li влево, чтобы интервал был постоянным, и просто убедиться, что поле (поля)+li соответствуют 900px.

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

Надеюсь это поможет.

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

  <div id="container">
    <object>
      <div>
      alpha
      </div>
    </object>
    <object>
      <div>
      beta
      </div>
    </object>
    <object>
      <div>
      charlie
      </div>
    </object>
    <object>
      <div>
      delta
      </div>
    </object>
    <object>
      <div>
      epsilon
      </div>
    </object>
    <object>
      <div>
      foxtrot
      </div>
    </object>
    <span></span>
  </div>
</html>

Я не решаюсь предложить это, так как он злоупотребляет старым HTML. Это не ХОРОШЕЕ решение, но это решение: используйте таблицу.

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>

Это не то, для чего были созданы таблицы, но до тех пор, пока мы не сможем надежно выполнить то же действие лучше, я думаю, что это почти допустимо.

Другие вопросы по тегам