Интересные задачи верстки и клиентского программирования

Колонки одинаковой высоты

добавил Шубин Александр 5 Июнь, 2012


Как добиться одинаковой высоты колонок при div верстке? На текущий момент я знаю только три способа. Перечислю их в порядке полезности и сложности, те что выше в списке боллее простые для понимания, а те что ниже наиболее функциональные:

  1. Изменение display
  2. Делать огромные margin и padding плюс overflow:hidden
  3. Вложенные колонки

Есть еще вариант с использованием javascript, но выравнивать колонки javascript’ом не наш метод. Если вы знаете способы которые принципиально отличаются от уже названных то пишите в комменты, я их добавлю с указанием ссылки на автора. Теперь подробнее про перечисленные мной способы.

1. Изменение свойства display

<div id="middle">
	<div id="row">
		<div id="left-column"></div>
		<div id="content"></div>
		<div id="right-column"></div>
	</div>
</div>
#middle{display:table; width:100%;}
	#row{display:table-row;}
		#left-column{display:table-cell; width:20%;}
		#content{display:table-cell; width:60%;}
		#right-column{display:table-cell; width:20%;}

Рабочий пример этого метода :
http://verstaem.com/examples/columns/display/

Это самый простой способ выравнивания колонок из всех.  В то же время он вообще не работает в Internet Explorer ниже и включительно 7 версии. Суть метода:

  • Делаем div в котором будут размещаться три наши колонки.
  • Создаем внутри этого дива еще три дива которые собственно и будут теми самыми колонками.
  • Присваиваем родительскому диву display:table;
  • Присваиваем дочерним дивам display:table-cell;

Все. Довольно просто, не правда ли?

При этом отдельный див для табличного ряда (<div id="row">) можно вообще не использовать. Я привел его для большей наглядности, но в реальной верстке его можно опустить.

2. Использование margin, padding + overflow:hidden

<div id="middle">
	<div id="left-column"></div>
	<div id="content"></div>
	<div id="right-column"></div>
</div>
#middle{width:100%; overflow:hidden; }
	#left-column{
		float:left; 
		margin-bottom:-32000px; 
		padding-bottom:32000px; 
		width:20%;
	}
	#content{
		float:left; 
		margin-bottom:-32000px; 
		padding-bottom:32000px; 
		width:59.8%;
	}
	#right-column{
		float:left; 
		margin-bottom:-32000px; 
		padding-bottom:32000px; 
		width:20%; 
	}

Рабочий пример этого метода можно посмотреть здесь:
http://verstaem.com/examples/columns/margin/

Способ уже немного посложнее, но тоже ничего сверхумного. Радует то, что способ работает во всех браузерах. Суть метода:

  • Делаем див в котором будем размещать все наши колонки
  • Создаем внутри этого дива еще три дива которые собственно и будут теми самыми колонками.
  • Выравниваем колонки по горизонтали с помощью float:left;
  • Присваиваем всем колонкам margin-bottom:-32000px; padding-bottom:32000px;
  • Присваиваем overflow:hidden для родительского дива.

Если непонтяно что мы тут сделали, то объясню подробнее.

Что делает свойство margin-bottom:-32000px?
Оно растягивает колонку вниз на 32000px.

Что делает свойство padding-bottom:32000px?
Оно делает отступ от нижнего края блока до контента в 32000px.

Что делает свойство overflow:hidden у родительского дива?
Оно скрывает ту часть блока в которой нет контента.

Если просуммировать то что я написал выше, то получается, что мы растянули пустое пространство снизу каждой из колонок, и обрезаем его по высоте той колонки в которой больше всего контента. По факту пустое пространство тянется еще очень долго вниз, но пользователь его не видит за счет overflow:hidden.

3. Вложенные колонки

<div id="middle">
	<div id="left-wrap">
		<div id="content-wrap">
			<div id="right-wrap">
				<div id="left"></div>
				<div id="content"></div>
				<div id="right"></div>

				<div class="clear"></div>
			</div>
		</div>
	</div>
</div>
#middle{width:100%;}
	#left-wrap{
		width:20%; 
		position:relative;
	}
		#content-wrap{
			width:300%; 
			margin-right:-300%; 
			position:relative; 
			left:100%;
		} 
			#right-wrap{
				width:33.1%; 
				margin-right:-33.3%; 
				position:relative; 
				left:100%;
			}

				#left{
					float:left; 
					width:100%; 
					margin-right:-100%; 
					position:relative; 
					left:-400%; 
				}
				#content{
					float:left; 
					width:300%; 
					margin-right:-300%; 
					position:relative; 
					left:-300%;
				}
				#right{
					float:left; 
					width:100%; 
				}

Для большей ясности советую изучить пример в котором все это уже работает:
http://verstaem.com/examples/columns/includes/

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

Первый шаг. Плацдарм

Создадим родительский див в котором будем располагать все наши колонки

Второй шаг. Создаем оформительские дивы

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

Третий шаг. Создаем дивы с контентом

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

Четвертый шаг. Определяемся с шириной оформительских колонок

Ширина всей страницы (ширина плацдарма) — 100%. Ширина левой колонки 20%. Выставим для левого оформительского дива ширину 20%. Пока все просто.

Ширина центральной колонки 60% от ширины страницы. Так как центральная колонка вложена в левую, то ее ширина будет рассчитываться относительно левой колонки(родителя). Центральная колонка в три раза шире чем левая, то есть нужно выставить ширину для центральной колонки в 300%.

Ширина правой колонки 20% от ширины страницы. Так как правая колонка вложена в центральную, то ее ширина так же будет рассчитываться относительно родителя и будет в 3 раза меньше чем ширина центральной, то есть нам нужно выставить ширину правой оформительской колонки в 33,3%.

Пятый шаг. Определяемся с шириной контентных колонок

Все три контентных дива вложены в правую оформительскую колонку. Они вложены параллельно. Чтобы было понятнее можно провести аналогию, три матрешки вложены друг в друга и в последней матрешке лежат три кубика. Матрешки это вложенные друг в друга оформительские колонки, а кубики это дивы с контентом.

Ширина правой колонки 20% от ширины страницы. Мы будем рассчитывать все размера контентных дивов относительно этой величины.

Ширина левой контентной колонки — 100% от родителя (20% от страницы)

Ширина центральнойконтентной колонки — 300% от родителя (60% от страницы)

Ширина правой контентной колонки — 100% от родителя (20% от страницы)

Шестой шаг. Двигаем оформительские колонки

Нам нужно сделать так, чтобы каждая из оформительских колонок начиналась там, где заканчивается предыдущая колонка. Сделать это довольно просто. Мы просто присвоим центральной и правой колонкам position:relative и сдвинем их вправо на 100% — left:100%.

Почему именно 100%? Потому что нам надо сдвинуть колонку на всю ширину родительского блока.

Седьмой шаг. Двигаем контентные колонки

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

Для начала выровняем колонки по вертикали с помощью float:left;

Теперь присвоим левому и центральному контентному диву position:relative;, дальше начнем двигать.

Левый контентный див начинается в левом верхнем углу правой колонки. Чтобы он стал отображаться поверх левой оформительской колонки нам надо сдвинуть его на 80% влево от ширины страницы. Так как ширина правой колонки 20% от страницы, то мы будем двигать на четыре ширины правой колонки влево или на 300% от ширины правой колонки — left:-400%;

После того как мы сдвинули левый див с контентом его место в правой колонке занял центральный див. Его мы должны сдвинуть только на 60% относительно ширины страницы или на три ширины правой колонки. Сдвинем центральную колонку на 300% влево.

Теперь левый и центральный контентные дивы находятся на своих местах. В правой оформительской колонке остался только правый контентный див. Его мы никуда двигать не будем. Он сам занял нужное положение, так как ему больше никто не мешает.

Еще немного пояснений

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

Див с классом clear после всех контетных колонок нужен чтобы разорвать поток. После него высота колонок не будет схлапываться.

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




5 комментариев

  • Вы можете добавить еще один способ. Надеюсь на вашу порядочность и вы опишите изложенное на моем сайте своими словами. С Новым Годом! http://vebma.ru/37-div.html Это не реклама, тут мое описание и видео

    • Оставлю ссылку, но не вижу смысла добавлять информацию в пост. На js это выравнивание делается элементарно. В статье я еще в самом начале сказал, что js способы не буду рассматривать. Ничего нового вы не сказали.

  • Второй способ не рекомендуется при использовании в тексте якорей. В результате при нажатии на ссылку вида <a href="#vniz">вниз</a>, наблюдается забавный эффект: блоки уезжают таким образом что блок виден начиная с элемента <span id="#vniz">вот мы и внизу</span>, а весь верхний текст исчезает мистическим образом.

    Так что этот способ очень использовать можно, только если в тексте нет и не будет якорей.

    • Спасибо. Данный баг действительно существует. Был не в курсе.
      Сейчас я думаю первый способ наиболее актуален. Он очень простой и при этом работает везде. Шестой и седьмой IE можно уже игнорировать для большинства сайтов.

  • iluha:

    Отличная статья. Взял себе на заметку. Спасибо!

Добавить комментарий для iluha Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *