Xiper

Правильные анонсы новостей

Автор: Андрей Косяк и Евгений Рыжков Дата публикации:

Задача

Сверстать блок анонсов новостей, например, вот такой:

обычные анонсы новостей

Требование

Если отсутствует фото, текст занимает всю доступную область.

Решение

Кажется, что все предельно просто: выстроил в ряд два плавающих блока и делов. Посмотрим, что из этого выходит:

<dl>
<dt></dt>
<dd>
	<div class="desc">
		<h2><a href="#">Заголовок новости</a></h2>
		<p>текст</p>
	</div>
</dd>
<dt></dt>
<dd>
	<a href="#" class="preview">
		<img src="img.jpg" />
	</a>
	<div class="desc">
		<h2><a href="#">Заголовок новости</a></h2>
		<p>текст</p>
	</div>
</dd>
</dl>
.preview {
	width: 150px;
	height: 100px;
	float: left;
	margin-right: 15px;
}
.desc {
	float: left;
	width: 350px; /* чтоб плавающие блоки выстроились в ряд размер обязателен */
}

Получаем:

кривые анонсы новостей

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

<dl>
<dt></dt>
<dd>
	<div class="desc entireWidth">
		<h2><a href="#">Заголовок новости</a></h2>
		<p>текст</p>
	</div>
</dd>
<dt></dt>
<dd>
	<a href="#" class="preview">
		<img src="img.jpg" />
	</a>
	<div class="desc">
		<h2><a href="#">Заголовок новости</a></h2>
		<p>текст</p>
	</div>
</dd>
</dl>
.preview {
	width: 150px;
	height: 100px;
	float: left;
	margin-right: 15px;
}
.desc {
	float: left;
	width: 350px;
}
.entireWidth {
	width: 100%;
}

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

Этого можно избежать, если вспомнить об одном селекторе: сестринском. Тогда решение получается простым и изящным силами одного лишь CSS:

<dl>
<dt></dt>
<dd>
	<div class="desc">
		<h2><a href="#">Заголовок новости</a></h2>
		<p>текст</p>
	</div>
</dd>
<dt></dt>
<dd>
	<a href="#" class="preview">
		<img src="img.jpg" />
	</a>
	<div class="desc">
		<h2><a href="#">Заголовок новости</a></h2>
		<p>текст</p>
	</div>
</dd>
</dl>
.preview {
	width: 150px;
	height: 100px;
	overflow: hidden;
	float: left;
}
.preview+.desc {
	margin-left: 170px;
}
.descIE { /* спец класс для IE6 */
	margin-left: 170px;
}
* html .desc { /* оптимизированный expression для IE6, который не поддерживает сестринский селектор */
z-index: expression(
runtimeStyle.zIndex = 1,
previousSibling && previousSibling.tagName && "a" == previousSibling.tagName.toLowerCase() ? (className += " descIE") : 0);
}

Демо пример. Проверено в:

Решение 2 — добавляем контекст

update Такого же эффекта можно добиться и не применяя expression, если воспользоваться вторым приемом описанным в «Отменяем обтекание текстом картинки».

<dl>
<dt></dt>
<dd>
	<div class="desc">
		<h2><a href="#">Заголовок новости</a></h2>
		<p>текст</p>
	</div>
</dd>
<dt></dt>
<dd>
	<a href="#" class="preview">
		<img src="img.jpg" />
	</a>
	<div class="desc">
		<h2><a href="#">Заголовок новости</a></h2>
		<p>текст</p>
	</div>
</dd>
</dl>
dt {
	margin-bottom: 5px;
	color: #999;
}
dd {
	margin-bottom: 10px;
	border-bottom: 1px solid #ccc;
	padding-bottom: 5px;
	overflow: hidden;
}
p {
	margin-bottom: 5px;
}
.preview {
	width: 150px;
	height: 100px;
	overflow: hidden;
	float: left;
	margin-right: 10px;
}
h2 {
	font-size: 16px;
	margin-bottom: 3px;
}
.desc {
	overflow: hidden;
	zoom: 1;
}

Демо пример.

По теме