Практика вёрстки зоны контента

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

Две колонки. Фикс, резина

	<div class="section">
		<div class="inner">

			<h1>Заголовок страницы</h1>

			<div class="cols-1">

				<aside class="leftcol">
					<p>Задача организации<!-- много текста --> модели развития.</p>
				</aside>

				<main class="rghtcol">
					<p>Повседневная <!-- много текста --> потребностям.</p>

					<p>Задача <!-- много текста --> развития.</p>

					<p>Не следует, <!-- много текста --> условий.</p>
				</main>

			</div>

		</div>
	</div>

Соответствующие стили:

/* Content */
.cols-1 { /* 2 колонки, фикс. и резина */
	width:100%;
	overflow:hidden;
}
.cols-1:after {
	content:"";
	display:block;
	clear:both;
}
	.cols-1 .leftcol {
		float:left;
		width:220px;
	}
	.cols-1 .rghtcol {
		margin:0 0 0 260px;
	}

Три колонки. Фикс, резина, фикс

HTML:

	<div class="section">

		<div class="inner">

			<div class="cols-2">

				<div class="container">
					<main class="content">
						<p>Повседневная практика <!-- много текста --> потребностям.</p>
						<p>Задача организации, <!-- много текста --> развития.</p>
						<p>Не следует, <!-- много текста --> условий.</p>
					</main>
				</div>

				<aside class="leftcol">
					<p>Повседневная <!-- много текста --> потребностям.</p>
				</aside>

				<aside class="rghtcol">
					<p>Не следует, <!-- много текста --> условий.</p>
				</aside>

			</div>

		</div>

	</div>

CSS:

.cols-2 { /* 3 колонки, фикс., резина, фикс. */
	width:100%;
	position: relative;
}
.cols-2:after {
	content:"";
	display:block;
	clear:both;
}

	.cols-2 .container {
		width:100%;
		float:left;
		overflow:hidden;
	}

		.cols-2 .content {
			padding:0 240px 0 240px;
		}

	.cols-2 .leftcol {
		float:left;
		width:200px;
		margin-left:-100%;
		position:relative;
	}

	.cols-2 .rghtcol {
		float:left;
		width:200px;
		margin-left:-200px;
		position:relative;
	}

Как видим, используется, фактически, хак. Однако, данные метод позволяет реализовать адаптив в широком диапазоне за счёт средней колонки.

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

Для этого из вёрстки уберём правую колонку.

	<div class="section">

		<div class="inner">

			<div class="cols-3">

				<div class="container">
					<main class="content">
						<p>Повседневная практика <!-- много текста --> потребностям.</p>
						<p>Задача организации, <!-- много текста --> развития.</p>
						<p>Не следует, <!-- много текста --> условий.</p>
					</main>
				</div>

				<aside class="leftcol">
					<p>Не следует, <!-- много текста --> условий.</p>
				</aside>

			</div>

		</div>

	</div>

В CSS убираем соответствующий padding.

.cols-3 { /* 2 колонки, фикс., резина */
	width:100%;
	position: relative;
}
.cols-3:after {
	content:"";
	display:block;
	clear:both;
}

	.cols-3 .container {
		width:100%;
		float:left;
		overflow:hidden;
	}

		.cols-3 .content {
			padding:0 0 0 240px;
		}

	.cols-3 .leftcol {
		float:left;
		width:200px;
		margin-left:-100%;
		position:relative;
	}

Визуально адаптивное поведение совпадает с первым случаем, поэтому анимацию не прикладываю.

Flex

Свойство display имеет значение flex, кроссбраузерность довольно низкая, IE11 поддерживает данный стандарт частично. Однако, в отличие от float, за этим типом позиционирования будущее.

HTML-код:

	<div class="section">

		<div class="inner">

			<div class="cols-4">

				<main class="content">
					<p>Повседневная практика <!-- много текста --> потребностям.</p>
					<p>Задача организации, <!-- много текста --> развития.</p>
					<p>Не следует, <!-- много текста --> условий.</p>
				</main>

				<aside class="leftcol">
					<p>Не следует, <!-- много текста --> условий.</p>
				</aside>

			</div>

		</div>

	</div>

CSS-код:

.cols-4 { /* 2 колонки, фикс., резина */
	width:100%;
	position: relative;
	display:flex;
	display:-webkit-flex;
}
.cols-4:after {
	content:"";
	display:block;
	clear:both;
}

	.cols-4 .content {
		order:2; /* Меняем порядок колонок. Свойство order сработает, только если родитель имеет display:flex */
		background:yellow;
	}

	.cols-4 .leftcol {
		flex-basis:200px; /* Вместо width используется понятие базовой ширины */
		flex-grow:0;
		flex-shrink:0;
		order:1;
		background:lightblue;
		margin:0 20px 0 0;
	}

Сразу видно принципиальное отличие от float-вёрстки: колонки сами вытягиваются по высоте, для этого не нужно использовать дополнительные ухищрения. Свойства flex-grow и flex-shrink являются коэффициентами растягивания и усечения. Как они работают, посмотрим ниже.

	<div class="section">

		<div class="inner">
			<div class="flex-shrink-outer">
				<div class="no-shrink-block">
					<p>Задача организации <!-- Много текста --> прогрессивного развития.</p>
				</div>
				<div class="shrink-block-1">
				
				</div>
				<div class="shrink-block-2">
				
				</div>
				<div class="shrink-block-3">
				
				</div>
			</div>
		</div>

	</div>

/* Flex Shrink */
.flex-shrink-outer {
	display:flex;
	justify-content:space-between;
}
	.flex-shrink-outer .no-shrink-block {
		width:200px;
		background:pink;
		flex-shrink:0;
	}
	.flex-shrink-outer .shrink-block-1 {
		flex-basis:400px; /* Если использовать width вместо flex-basis, эффект будет тем же */
		background:cyan;
		flex-shrink:3;
	}
	.flex-shrink-outer .shrink-block-2 {
		flex-basis:400px;
		background:royalblue;
		flex-shrink:2;
	}
	.flex-shrink-outer .shrink-block-3 {
		flex-basis:400px;
		background:maroon;
		flex-shrink:1;
	}

flex-shrink применяется, когда элементы не помещаются во flex-контейнер. У колонки .no-shrink-block свойство flex-shrink равно нулю, так что при сжатии колонка будет сохранять свой размер. А вот у других колонок суммарная ширина больше, чем ширина блока-контейнера. Поэтому браузеру придётся умещать дочерние блоки в блок-контейнер в соответствии с пропорциями, заданными в свойстве flex-shrink. Единственное качественное отличие от ширины в процентах, это возможность задать одну или несколько колонок с неизменной шириной, а остальное пространство распределить пропорционально.

Теперь рассмотрим поведение блоков с flex-grow.

	<div class="section">

		<div class="inner">
			<div class="flex-grow-outer">
				<div class="no-grow-block">
					<p>Задача организации <!-- Много текста --> прогрессивного развития.</p>
				</div>
				<div class="grow-block-1">
				
				</div>
				<div class="grow-block-2">
				
				</div>
				<div class="grow-block-3">
				
				</div>
			</div>
		</div>

	</div>

/* Flex Grow */
.flex-grow-outer {
	display:flex;
	justify-content:space-between;
}
	.flex-grow-outer .no-grow-block {
		width:200px;
		background:pink;
		flex-grow:0;
	}
	.flex-grow-outer .grow-block-1 {
		flex-basis:100px;
		background:#ff33cc;
		flex-grow:3;
	}
	.flex-grow-outer .grow-block-2 {
		flex-basis:100px;
		background:#0066ff;
		flex-grow:2;
	}
	.flex-grow-outer .grow-block-3 {
		flex-basis:100px;
		background:#ff3300;
		flex-grow:1;
	}