Равноудаленные элементы
UPD: Есть новый способ! Читайте пункт 4.
Создание равноудаленных друг от друга элементов, находящихся на одной горизонтали, довольно актуальная задача для вебмастеров: кто-то реализует это с помощью таблиц, другие используют css-трюки и т.п. Но так ли сложна задача на самом деле? Рассмотрим подробнее на примере.

Наша задача будет в том, чтобы расположить 4 элемента по горизонтали так, чтобы расстояние межу ними было равное и пропорционально изменялось в зависимости от размеров окна браузера. В качестве элементов будем использовать изображения, например круги. Вначале рассмотрим несколько способов, которые чаще всего стараются применить верстальщики и проблемы с которыми они сталкиваются.
1. Определим для каждого элемента ширину в % и позиционируем по левому краю:
<img src="images/shape-red.png" class="first-r"> <img src="images/shape-green.png" class="second-r"> <img src="images/shape-yellow.png" class="third-r"> <img src="images/shape-blue.png" class="fourth-r">
CSS код:
img.first-r { left: 0%; position: relative; }
img.second-r { left: 25%; position: relative; }
img.third-r { left: 50%; position: relative; }
img.third-r { left: 75%; position: relative; }
Важно отметить, что свойство relative должно обязательно присутствовать. Это необходимо для того, чтобы крайний слева элемент позиционировался относительно родительского элемента, если тот имеет центрирование и не прилегает к левому краю. Проблема данного решения заключается в том, что левый отступ самого крайнего элемента справа в 75% отсчитывается от ширины окна браузера, но точкой отсчета будет левый край не окна, а родительского элемента. В результате этого, последний элемент уйдет за пределы экрана, а при определенном размере окна, наша строка и вовсе развалиться.
Если изменить значение relative на absolute, то несколько вышеуказанных проблем вам удастся разрешить и даже добиться равного расстояния между элементами. Но основной проблемой останется то, что все элементы будут иметь позиционирование по левому краю, и правила родительских элементов будут игнорироваться.
2. Определим для каждого элемента (кроме первого) отступ слева:
<span class="do-not-wrap"> <img src="images/shape-red.png"> <img src="images/shape-green.png" class="mover"> <img src="images/shape-yellow.png" class="mover"> <img src="images/shape-blue.png" class="mover"> </span>
img.mover {
margin-left: 15%;
}
Тут нам даже не придется высчитывать отступы для каждого элемента – мы просто зададим общий равный отступ для трех элементов, начиная со второго. По идее все должно работать как надо, т.к. отступ будет отсчитывать от ширины окна браузера, так же как и ширина родительского элемента. также, блок do-not-wrap должен предотвратить разъезжание элементов. Но результат нас опять огорчит…
3. Обернем элементы табличной структурой
<table> <tr> <td class="leftalign"> <img src="images/shape-red.png"> </td> <td> <img src="images/shape-green.png"> </td> <td> <img src="images/shape-yellow.png"> </td> <td class="rightalign"> <img src="images/shape-blue.png"> </td> </tr> </table>
И даже этим способом мы не получим идеального результата – элементы будут равноудалены не всегда. Если задать для 2й и 3ей ячейке центрирование содержимого; крайней слева – по левому краю, и последней по правому краю, то в результате все должно работать как нужно, если… не изменять размеры окна браузера.
4. Что будем делать?
Метод, присланый пользователем hmelii (из комментариев):
Для равноудаленного расположения изображений:
CSS
<style type="text/css">
#movers-row{ text-align:justify}
#movers-row span{ display:inline-block; width:100%; }
</style>
HTML:
<div id="movers-row"> <img src="http://css-tricks.com/examples/EquidistantObjects/images/shape-red.png" alt="" /> <img src="http://css-tricks.com/examples/EquidistantObjects/images/shape-green.png" alt="" /> <img src="http://css-tricks.com/examples/EquidistantObjects/images/shape-yellow.png" alt="" /> <img src="http://css-tricks.com/examples/EquidistantObjects/images/shape-blue.png" alt="" /> <span></span> </div>
Способ работает для всех браузеров! Смотрите пример.
Для равноудаленного расположения блоков:
CSS:
.container {
text-align: justify;
text-justify:newspaper;
width:100%
}
.box{
display:-moz-inline-box; // для поддержки FF2
display:inline-block;
vertical-align:top;
text-align:left;
width:200px;
height:200px;
background:red;
}
.box p {padding:10px;}
/*IE6*/
* html .box{ display:inline; }
/*IE7*/*
+ html .box{ display:inline; }
.under{display:-moz-inline-box; display:inline-block; width:100%; }
HTML
div class="container">
<div class="box"><p>текст текст текст текст текст</p></div>
<div class="box"><p>текст текст текст текст текст</p></div>
<div class="box"><p>текст текст текст текст текст</p></div>
<div class="box"><p>текст текст текст текст текст</p></div>
<span class="under"></span>
</div>
Способ работает для всех браузеров! Смотрите пример.
Метод Криса Койера
Предыдущий способ навел на некоторые мысли: попробуем позиционировать первый элемент по левому краю, а остальные по правому. Визуально это должно выглядеть так:

HTML:
<img src="images/shape-red.png"> <div id="movers-row"> <div><img src="images/shape-green.png"></div> <div><img src="images/shape-yellow.png"></div> <div><img src="images/shape-blue.png"></div> </div>
CSS:
#movers-row {
margin: -120px 0 0 120px;
}#movers-row div {
width: 33.3%;
float: left;
}
#movers-row div img {
float: right;
}
Что ж, наших попыток реализации равноудаленных элементов. Очевидно, что именно 4й способ и станет идеальным решением.
Материалы статьи:




Dmoz
У вас два третьих пункта подряд =)
sevonЦитировать
Спасибо! Ваш совет мне очень помог :)
NecronominiconЦитировать
Может вопрос нубский но “mce_src” – что сие есть?
FXIXЦитировать
это глюк TinyMice..
АвторЦитировать
а теперь тоже самое но для элементов разной ширины ;)
frstЦитировать
У меня есть способ, который Chris Coyier и не снился
hmeliiЦитировать
Оо Получилось Вот этот способ о котором я говорил Chris Coyier отдыхает вместе со своими идеями
CSS:
#movers-row{ text-align:justify} #movers-row span{ display:inline-block; width:100%; }HTML:
hmeliiЦитировать
Решение удивительно простое и необычное, span как бы ложиться под картинки, не давая им развалиться в блоке. И работает во всех браузерах!
Думаю вам стоит разместить это к статье Криса ;)
АвторЦитировать
Добавлю ещё что этот способ помимо своей простоты имеет ряд достоинств о которых блочный способ и не мечтал Во первых поддержка картинок любого размера Во вторых неограниченное колличество И в третьих самое важно поддержка вертикального выравнивания
hmeliiЦитировать
Если это не картинки, а блоки или абзацы?
hurumЦитировать
К сожалению кроссбраузерного решения для блоков я пока не нашел Мой метод работает только в firefox safari opera и chrome
hmeliiЦитировать
Привет Это опять я Нашел таки способ и для блочной модели выравнивание во ВСЕХ браузерах (ff2, ff3, opera, safari, chrome и самые любимые ie6, ie7 ) Если интересно могу выложить
hmeliiЦитировать
Выкладывай :) Только код оберни в <pre></pre>, я исправила прошлые баги.
АвторЦитировать
CSS:
* { margin:0; padding:0;}
.container { text-align: justify; text-justify:newspaper; }
.box{ display:-moz-inline-box; display:inline-block; vertical-align:top; text-align:left; width:200px; height:200px; background:red; }
.box div{ width:200px; height:200px;}
/*IE6*/* html .box{ display:inline; }
/*IE7*/* + html .box{ display:inline; }
.under{display:-moz-inline-box; display:inline-block; width:100%; }
html:
<div class="container">
<div class="box"><div>текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
<div class="box"><div>текст текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
<div class="box"><div>текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
<div class="box"><div>текст текст текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
<span class="under"><!– –></span>
</div>
hmeliiЦитировать
Появился код ? Что скажешь ? Как метод ?
hmeliiЦитировать
Что касается фиксированных размеров блоков, то все работает классно, но если для div.box задать 25%, то во всех браузерах, кроме IE6 и IE7 (на удивление) они разваливаются.. Максимум можно задать 24%. И еще, для чего дополнительно для FF прописывать “display:-moz-inline-box; ” ?
АвторЦитировать
А какой смысл для div.box задать width 25% для 4 боксов Зачем тогда нужно выравнивание ?Если конечно имеешь ввиду для меньшего колличества боксов например для трех То все нормально РАБОТАЕТ Ничего не разваливается Что касается display:-moz-inline-box; То это для ff2 Так он не поддерживает display:inline;blockПоэтому если проекту не нужна поддержка устаревшего ff2 Это свойство можно опустить А также вложенные дивы тоже Код станет проще и валидней !
hmeliiЦитировать
Это я просто проверяла что лучше float:left или твой способ для макетов с блоками равной ширины…
А вообще классное решение, спасибо! Я в начало статьи помещу :)
АвторЦитировать
Насчет преимущества float боксов с процентной шириной Это ты зря Причем заметь что боксы распологаются в строку без оберток ! Вот реальный пример css
* { margin:0; padding:0; }
.container { width:25%; word-spacing:-1px;}
.box{ display:-moz-inline-stack; word-spacing:normal; display:inline-block; vertical-align:middle; width:25%; background:red; }
.box div{font-size:12px; }
.in{ width:400%; }
/*IE6*/* html .box{ display:inline; }
/*IE7*/* + html .box{ display:inline; }
.over{ overflow:hidden; position:relative; font-size:0; }
html
<div class="over">
<div class="container">
<div class="in">
<div class="box"><div>текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
<div class="box"><div>текст текст текст текст т</div></div>
<div class="box"><div>текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
<div class="box"><div>текст текст текст текстекст текст текст текст текст текст текст текст текст екст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
<div class="box"><div>текст текст текст текстекст текст текст текст текст текст текст текст текст екст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
<div class="box"><div>текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
<div class="box"><div>текст текст текст текст т</div></div>
<div class="box"><div>текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст текст </div></div>
</div>
</div>
</div>
А сможет ли так float модель ?
hmeliiЦитировать
Ну не скажи, что без обертки.. все таки 2 дополнительных блока, которые, с позиции семантики, “висячие”, т.к. являются обязательным дополнением, но на дизайне как таковые не оборажаются – такого лушче избегать. Хотя с флоатами конечно ситуация не лучше.
..и в IE6 горизонтальная прокрутка появляется (у меня IEtester, а не сам IE6)
АвторЦитировать
Я имел ввиду не эту обертку А ту что обварачивала бы каждые четыре бокса с float Чтобы следующая строка с четырьмя блоками не ломалась в случае если в первой были бы боксы с не равной высотой Щас покажу пример
hmeliiЦитировать
Это я поняла, поэтому и говорю, что и с флоатами не все так идеально.
АвторЦитировать
Вот гляди css:
* { margin:0; padding:0; }
.over{ overflow:hidden; display:block!important; /*IE6*/display:inline-block; }
.box{ float:left; width:25%; clear:right; }
.box p{ border:1px solid red;}
html
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
На первый взгляд все четко но стоит нам в один из боксов добавить чуть текста
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
происходит не приятная ситуация И что нам приходится делать Обварачивать каждую четверку в обертку
<div class="over">
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
</div>
<div class="over">
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
<div class="box"><p>тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект тект</p></div>
</div>
В методе с inline-block Все идет единным потоком ! Насчет тех трех оберток Так это для любимого браузера ie )Другого способа покамест не нашел
hmeliiЦитировать
приветствую! такая вот интересная вещь обнаружена, что если убрать все пробелы в данном коде:
то картинки сдвигаются к друг другу в плотную :(
regЦитировать
что то код не отобразился, видимо что то не так написал.
код имелся в виду который написал Hmelii. т.е. убрать пробел между скобками.
regЦитировать
А зачем ты убрал пробелы? Представь себе если ты уберешь между словами пробелы и определишь для них свойтво text-align:justify Они же не будут отображаться как надо Здесь аналогичный случай Пробелы между необходимы!
hmeliiЦитировать
А как быть со спаном? В IE6 он имеет определенную высоту и если у контейнера один фон, а у самих блоков другой то контейнер растягивается. Существует ли какая-либо возможность заменить span чем то другим?
ЛАСТЫЧЦитировать
Для span дополнительно укажите свойства
font-size:0px;
line-height:0px;
и тогда он не будет иметь высоты.
АвторЦитировать
Пример Hemlli не работает в Konqueror:)
Но, в целом, решение отличное, спасибо.
EnlightenedЦитировать
@Enlightened, к счастью им пользуется ооочень маленький % юзеров :)
Блог для вебмастеровЦитировать
Привет.
метод hmelii
плохо работает под огнелисом2
так как все что внутри блока превращается в инлайн
из этого получается много проблем с размещением элементов внутри
СергейЦитировать
а под первым вообще не работает )))
hmeliiЦитировать
Да я понимаю что это мрак под него править, но нужно :(
СергейЦитировать
Решил частично проблему взял в див все что внутри флат лефт и хак только для огнелиса2
СергейЦитировать
Привет. У меня к тебе есть одна просьба. Прочитав эту статью , я попробывал реализовать эту задачу способом которым я действовал тут, но немного изменил его. Тем самым избавился от лишнего элемента. Если тебе не трудно, не могла бы ты помочь разместить этот способ на хабре.
hmeliiЦитировать
В предыдущий раз у меня возникли проблемы с размещением кода, поэтому дам ссылку на пример . И сразу скажу, что есть один недостаток. В браузерах, основанных на webkit, зачем-то отображается пробел после последнего элемента, поэтому пришлось html код писать в одну строку. Работает в ie6, ie7, ie8, safari, chrome ff3, opera10
hmeliiЦитировать
да и выравнивать можно и по нижней линии и по верхней и по средней, как в примере.
hmeliiЦитировать
hmelii, офигеть решение ).Кстати, можно span заменить на псевдоэлемент :after. Тогда разметка остается чистой и без лишних пустых элементов. ie7 не понимает :after, но ему можно експрешн подсунуть, или подключить знаменитый IE8.js.
даник.htmlЦитировать
Не нужно експрешн. Читайте мой предпоследний коммент. Я там дал ссылку на новую версию этого метода. Где как раз уже нет лишних элементов. И работает во всех браузерах включая и ie
hmeliiЦитировать
А можно выложить код нового метода!? Спасибо!
АлеусейЦитировать
Второй метод hmelii, это, конечно не метод, а сплошные костыли, хоть и эффективные). Думаю, от него лучше сразу отказаться.
AmirЦитировать