Каскадные Таблицы Стилей

индекс
324,89

Позиционирование элементов по разным сторонам блока

Здравствуйте, дорогие читатели. Сегодня я расскажу вам о малоизвестном способе разнести два элемента по разным сторонам блока, в котором они находятся. Например вот так

До некоторого времени я, как и многие из вас, пользовался двумя способами:
  1. Первый способ основан на свойстве float. Левому блоку задаётся float: left, правому float: right
  2. Второй способ заключается в абсолютном позиционировании правого блока, с параметрами right: 0 либо left: 100%, margin-left: -(ширина блока)

Главный недостаток обоих способов заключается в том, что, если блоки нужно выравнять по нижней границе или по средней линии относительно друг друга, то приходится методом подбора смещать блоки по вертикали, задавая им либо top: anyValue, либо margin-top: anyValue. А у первого способа плюс ко всему есть ещё один, не то чтобы недостаток, но неприятная мелочь. Это необходимость очищать поток с помощью clearFix'a, overflow или дополнительного дива.
Итак способ номер 3. Для начала код:

Собственно HTML


Copy Source | Copy HTML
  1. <div class="wrap">
  2.     <div class="left"><a href="#">Левый блок</a></div><div class="right"><a href="#">Правый блок</a></div>
  3. </div>

Собственно CSS


Copy Source | Copy HTML
  1. .wrap {
  2.     width: 500px;
  3.     background: #555;
  4.     height: 500px;
  5. }
  6. .left, .right {
  7.     display: inline-block;
  8.     //display: inline;
  9.     //zoom: 1;
  10.     width: 100%;
  11.     margin-right: -100%;
  12.     vertical-align: bottom;
  13. }
  14. .right {
  15.     text-align: right;
  16. }
  17. .left a, .right a { display: inline-block; position: relative; }
  18. .left a { width: 200px; height: 100px; background: green; }
  19. .right a { width: 100px; height: 200px; background: pink; }

Пояснения


Суть способа заключается в том, чтобы наложить блоки друг на друга посредством margin-right: -100% и содержимое правого блока выровнять по правому краю с помощью text-align: right.
Оба блока (right и left) желательно записывать в одну строку, иначе из-за символа переноса строки правый блок будет чуть-чуть вылезать за границы блока-родителя.
Ссылкам обязательно нужно ставить position: relative, иначе из-за наложения блоков некоторые могут быть некликабельные.

Плюсы способа


Главный плюс в том, что теперь для наших блоков начинает работать vertical-align. И мы легко можем выровнять их и по верхней границе и по нижней и по центру.

Минусы способа


А главный минус заключается в том, что, применяя этот способ, мы должны быть твёрдо уверены, что содержимое блоков не увеличится до такой степени, что они начнут перекрывать друг друга (к слову говоря, способ с флоутами лишён этого недостатка, так как при увеличении содержимого блоков, они будут вставать друг под друга).

Ссылка на готовый пример

P.S.


Я не встречал такого способа в интернете, посему просьба: если кто-то найдёт аналогичную статью опубликованную раньше, сообщите мне пожалуйста.

Upd.


В комментариях моё внимание внимание обратили на способ, использующий text-align: justify. Этот способ тоже хорош, но у него есть два недостатка. Во-первых он требует введения дополнительного элемента, эмулирующего последнюю строку текстового блока, а во-вторых, он не будет работать в IE6-IE7 для блочных элементов.
+56
25 августа 2010, 20:54
139

комментарии (81)

+1
sharr #
Спасибо! пригодится :)
0
starfake #
на margin-right: -100% основывается способ Чикуенка по верстке растягивающихся сайтов. Хотя все наверное уже читали.
И по данному примеру хочется спросить: выравнивание должно работать относительно содержащего контейнера или относительно контейнера right. В ФФ в Мак оси работает относительно right.
0
smashercosmo #
Данная статья к вёрстке растягивающихся сайтов не имеет никакого отношения. Контейнеры right и left выравниваются друг относительно друга. В зависимости от того какое значение свойства vertical-align вы зададите каждому из них.
–4
Butylski #
Who is Mr. Чикуёнок? :)
+1
FeelGood #
0
kashey #
О! Какой человек оказывается рядом со мной с iPad сидел на последнем Я.Субботнике( по верстке какраз ).
+3
homm #
Who is Mr. Google?
0
tenshi #
раз уж у нас размеры фиксированны, то что мешает заюзать bottom:0?
0
smashercosmo #
Честно говоря не совсем понял, о чём вы? Кому прописать bottom: 0? И про какие размеры вы говорите?
0
tenshi #
.ritght { position: absolute; right: 0; bottom: 0; width: 200px; height: 100px }
0
smashercosmo #
И что получится? В данном примере блок right тогда окажется в нижнем правом углу (если конечно блоку wrap ещё задать position: relative). А чего-то, честно говоря, всё равно не понимаю в чём суть.))
0
tenshi #
bottom: 300px и будет как у тебя в примере
+2
smashercosmo #
Так в том-то и дело, что при position: absolute каждый раз придется подгонять значения top, bottom. А при моём способе всё будет происходить автоматически. Блоки не обязательно должны быть фиксированными по высоте. Высота спокойно может зависить от объёма контента. Плюс я сейчас постоянно сталкиваюсь с тем, что в конторе, в которой я работаю, дизайнеры любят по ходу вносить кучу исправлений: изменить размер шрифта, изменить высоту блока, решить, что они хотя блоки выровнять не по нижней линии, а по центру и т. д. И данный способ позволяет это всё делать быстро и безболезненно. Т.е. он гораздо более гибкий чем float или position: absolute.
0
tenshi #
в том-то и дело, что пример не показательный
–1
frujo #
Да-да! Тоже подумалось. Родительскому элементу присвоить position:relative, а двум другим position:absolute, а потом позиционировать всласть свойствами left, top или bottom, right.
+1
Quiz #
Перебрал в уме все свои прошлые проекты и ни в одном из них не возникало такой необходимости.
Если не секрет, где Вы это использовали?
0
nobr #
Посмотрите, как оформлены комментарии на хабре: слева аватар, ник и дата, справа — оценка. Всё это в одной строке по разным краям.
+3
Steward #
Пример с хабром жутко неудачный к теме данного опуса… потому что на хабре сделано по нормальному, т.е. с использованием списков и флотами left-right для отдельных элементов…

честно я несколько раз прочитал заметку… пример посмотрел… исходник… и так и не понял в чём прикол или хоть какое-то ноу-хау!
0
nobr #
Просто я хотел показать, где это можно использовать: строка постоянной высоты, блоки никогда не достигнут ширины больше половины строки.

Хотя мне тоже больше нравится float.
0
smashercosmo #
прикол в том, что используя float вы можете выровнять блоки только по верхней линии. Чтобы выровнять их по нижней границе или по центру, вам придется каждый раз подгонять значения margin-top или top. А если высота блоков будет зависить от контента, то вообще ничего не получиться.
+2
homm #
блоки никогда не достигнут ширины больше половины строки
Далеко ходить не пришлось:
image
НЛО прилетело и опубликовало эту надпись здесь
0
frujo #
Тут сверстано совершенно не так. Используются элементы списка обтекающие друг друга слева.
+5
Panya #
Я просто оставлю это здесь: jsfiddle.net/h9YMP/
0
smashercosmo #
ваш способ не будет работать в IE6-7 для блочных элементов
0
Panya #
Обновил jsfiddle.net/h9YMP/69/ теперь работает.

Ключевые моменты:

1. ins вместо div т.к. ins по-умолчанию может быть и блочным (содержать другие блочные) и строчным (это надо чтоб в IE < 8 работал нативный display:inline-block;)
2. Убрать переводы строк внутри ins (нужно только для IE6).
0
smashercosmo #
хм… не знал такого про ins и del. спасибо за новые знания.
P.S. Но в данном случае вас бы загнобили любители семантики :)
0
Panya #
А мне на них плевать, задача решена? Решена. С наименьшими усилиями? Да. Кроссбраузерно? Да. Даже валидно? Да. Семантичо? А имеет ли это какое-то значение в данном случае?
+6
alemiks #
Я бы ещё P.P.S. приписал: «Названия классов left и right даны для наглядности, не называйте классы left, right, verh, niz, green, krasno-korichneviy и т.п. в реальных проектах!!!»
–1
Anonym #
И с чем же связана такая избирательность?
+4
ArtyV #
В названии класса необходимо отражать не внешний вид элемента, а его назначение
0
tenshi #
а если ег назначение — внешний вид? ;-)
0
ArtyV #
Всегда есть что-то, что можно придумать. Например жёлтые декорационные «листочки» я называл стикер, а не йелоу шит : D
0
tenshi #
смысла не прибавилось. что если бы у тебя были разбросаны декорационные листочки разных цветов. как бы ты их назвал? стикер_основной, стикер_дополнительный, стикер_ещё_один? х)
0
ArtyV #
А какое у них назначение? Или просто так разных цветов без всякого принципа? Тогда впринципе сойдёт просто нумерация, думаю
0
tenshi #
декорация. и когда тебе скажут подвинь жёлтый листочек в сторону ты полезешь в фаербаг смотреть номер класса вместо того, чтобы просто отредактировать правило для еллоу_шит?
0
tenshi #
декорация. и когда тебе скажут подвинь жёлтый листочек в сторону ты полезешь в фаербаг смотреть номер класса вместо того, чтобы просто отредактировать правило для еллоу_шит?
0
ArtyV #
Зато мне не придётся лезть в html, когда попросят сделать из елоу_шит блю_шит
0
tenshi #
а какая разница куда лезть?
и там и там поменять — одну строчку
0
ArtyV #
Ну мы же лезем типа отображение менять, значит лезем в css : D
0
tenshi #
html — это тоже вообще-то отображение данных.
0
ArtyV #
Безусловно, но типа принято считать — что это как бы не отображение : D в общем то понятны плюсы и минусы обоих подходов, дальше вроде незачем обсуждать
0
smashercosmo #
Я на самом деле тоже не согласен. К примеру у меня есть тридцать таблиц. У них весь контент выровнен по левому краю, а в последнем столбце каждой таблицы по правому. Последний столбец в каждой таблице называется по-разному. В одной — «статус», в другой — «расход», в третей «Кол-во просмотров» и т. д. Так я лучше присвою последнему столбцу класс last. Чем буду для каждого последнего столбца создавать новый класс, отражающий его контент.
0
ArtyV #
В данном случае конечно же класс last лучший вариант. Правильным вариантом конечно же был бы псевдокласс, но вы верно подметили на счёт IE. Плюс в IE8 нет ни last-child, ни экспрешенов : D
Но такие исключения ведь появляются только из-за неполноценности браузеров, так что они вне правил
0
smashercosmo #
Только не надо говорить: td:last-child, а для IE экспрешен. На таком количестве элементов IE сдохнет.
0
ArtyV #
Обычная инлайн-блочная вёрстка. На tjkdesign.com про это было написано года 2-3 назад наверное, если не раньше.
0
ArtyV #
Ну и да, увлекаться инлайн-блоками не стоит (в плане глобальной разметки), т.к. это довольно нестабильная модель отображения.
0
smashercosmo #
В том-то и дело, что макеты на инлайн-блоках никто делать не предлагает. В данной статье решается совершенно конкретная задача. Также как и здесь, например.
0
tibalt #
еще вариант — display: inline-block + text-align: justify (придется юзать лишний вспомогательный элемент)

впрочем, про этот способ выравнивания по краям не раз писали на хабре.
0
smashercosmo #
Не могли бы вы мне дать ссылку на какой-нибудь из этих топиков? Реализация, которую я нашёл в интернете, некорректно работает в хроме. Вот ссылка.
0
GruZZ #
Вот выше есть комментарий со ссылкой. Кстати, я всегда пользовался подобным способом, и глюков в Хроме не замечал. Можете рассказать о глюке поподробнее?
+1
ArtyV #
В ie6 и ie7 не работает
0
tibalt #
лично реализовывал этот способ в футере

под хромом тоже все ок

ссылки сходу не дам, помню сам не сразу нашел статьи на эту тему, тяжело подбирались ключевые слова) просто посмотри, как у меня сделано и скопипасть.
0
smashercosmo #
Я понял, почему глючило в хроме. В той реализации, которую я нашёл, человек использовал свойство content, для эмуляции последней строки. Ну чтобы дополнительный div не вставлять. И это везде отлично прокатывает, кроме хрома. Хром почему-то не воспринимает эту строку как последнюю в блоке текста.

А так да, этот способ чудо как хорош. Минус только в дополнительном диве. Но очень большой плюс в том, что блоки при перекрытии будут прыгать друг под друга.
0
smashercosmo #
Кстати, как заметили выше, этот способ не будет работать в IE6, IE7. Точнее он будет работать, но только для инлайновых элементов, а для блочных — увы.
0
ArtyV #
Конечно это на самом деле может работать, но всё немного сложнее
0
smashercosmo #
и каким образом, учитывая, что в IE6-7 единственный способ эмулировать inline-block — это поставить блочному элементу display: inline, zoom:1, но для таких элементов justify работать не будет?
0
ArtyV #
Вы наверное замечали, что инлайн элемент с hasLayout не совсем инлайн-блочный, он слишком блочный — это может навести на некоторые мысли ; ) если не догадаетесь, то дождитесь моего поста об этом, на этой неделе опубликую
0
smashercosmo #
вы намекаете на то, что для IE нужно выставлять просто inline? Ну хотя ладно не буду гадать, дождусь поста.)
0
ArtyV #
Как обещал (почти как обещал, получилось написать только сейчас): habrahabr.ru/blogs/css/81611/
0
Rooc #
спасибо, очень интересно. то есть второй элемент налезает на первый изза отрицательного маргина первого, а зачем тогда правому маргин отрицательный?
0
smashercosmo #
Вообще да, вы правы, второму не нужен. Просто так css красивее смотрится: практически одинаковый стиль для обоих дивов :)
0
Rooc #
да, конечно, просто для ясности понимания спросил )
0
smashercosmo #
А налезает конечно из-за марджина
0
Elt #
Оба блока (right и left) желательно записывать в одну строку, иначе из-за символа переноса строки правый блок будет чуть-чуть вылезать за границы блока-родителя.

Достаточно прописать для родителя блоков word-spacing: -1ex; или эквивалентное значение -.3em, и описаной проблемы не будет.
0
smashercosmo #
К сожалению способ не универсален. Например при значении font-family: verdana или monospace, парамметр word-spacing придется менять. Уверен, что есть и другие ситуации, где этот способ даст сбой. Например на других платформах.
0
Elt #
Назначить стиль для родителя — одна строка, переназначить его для детей — ещё одна. За то не придется городить код в одну строку. По поводу других платформ — это уже нужно проверять.
0
smashercosmo #
Ещё раз: значение в -.3em актуально только для определенных шрифтов. Если вы сделаете проект, а потом кто-то решит поменять шрифт, то они будут долго искать, почему у них всё вдруг сместилось.
0
Elt #
1. Что значит для определенных? Пример.
1. word-spacing: -1ex;
2. Строить макет на em, тогда ничего не будет смещаться.
0
smashercosmo #
Пример писал выше: verdana или monospace
0
smashercosmo #
Пример писал выше: verdana или monospace
0
Hmelii #
Предлагаю более универсальный способ выравнивания элементов. К сожалению моей кармы, не хватает, чтобы написать полноценный пост с описанием, поэтому просто дам ссылку на пример. Кому интересно сам разберется, как и что работает.
0
smashercosmo #
Вы уже не первый, кто предлагает этот способ. Но чтобы этот способ заработал в IE6-7 для блочных элементов, нужно дико извращаться с элементом ins: http://habrahabr.ru/blogs/css/102651/#comment_3204337
0
Hmelii #
Откройте страницу в ie6 в ie7. Там все прекрасно работает с блочными элементами. И никакой дикости нет. Всё проще паренной репы.
0
smashercosmo #
А, нет, сорри, был не прав. Офигенно на самом деле. text-justify: center))) вот никогда бы не додумался. Благодаря ему всё работает. Круто. Спасибо.
0
smashercosmo #
тьфу, text-justify: newspaper))
0
smashercosmo #
Кстати, можете объяснить почему ваша реализация этого способа работает в хроме, а вот эта, которая вроде как аналогична, не работает?
0
smashercosmo #
Скажите пожалуйста, зачем классу ib-ju выставлен font-size: 0?.. Из-за этого свойства этот способ не работает в опере для более чем двух элементов.
0
Hmelii #
И сразу же опережу следующие быстрые ответы. Этот способ не содержит ни дополнительных элементов. Работает в ie6, ie7, ie8, ff3, opera10, safari, chrome. Поддерживает выравнивание по вертикале. Можно использовать и для более 2 блоков. Смотрите внимательно код.
0
Hmelii #
Вы, скорее всего, формируете код в каком-то редакторе, который при выравнивании кода зачем-то, вставляет символы пробелов, которые влияют на отображение элементов в webkit браузерах. Убрав их всё стабилизируется в webkit браузерах. Попробуйте их убрать или написать последний спан неразрывно с закрывающимся дивом на конце.
0
ojiga #
хм… интересно. узнал новый способ. я обычно делаю вариацию на тему:

направо:

wrap {
position: relative;
}
.right {
position: absolute;
right: 0;
}

или чаще float: right

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.