Xiper

Отменяем обтекание текстом картинки

Автор: Александр Головко Дата публикации:

Задача

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

обтекание не нужно слева правильно, справа — нет

Дополнительное условие: ширина ни текста, ни картинки строго не определена. При отсутствии картинки текст занимает всю отведенную ширину.

Решение

Будем считать, что левая колонка может содержать не только картинку, а что-либо еще. Поэтому HTML у нас будет выглядеть так (вообще говоря, класс photo можно было бы присвоить самому img и обойтись без div'а):

<div class="photo">
	<img src="images/pic.jpg" width="100px" height="100px" alt=""/>
</div>
<div class="description">
	Текстовый блок
</div>

Пробуем написать стили. С левой колонкой все ясно:

.photo {
	float: left; /* задаем обтекание */
	margin:10px; /* отступ для красоты */
	display:inline; /* для IE6, чтоб отступ слева не удвоился */
}

Теперь рисунок стал слева, а текст обошел его справа. Но если текста больше, он будет «подныривать» под рисунок (см. картинку выше), а этого-то нам и не нужно.

Первое, что приходит в голову — «зафлоатить» и текст. Но в этом случае, если не прописать ширину текст упадет под рисунок!

пробуем float float:left/right будет требовать ширину — иначе ничего не получиться!

Думаем дальше… Хорошим решением может показаться .description{margin-left: XXXpx}. Действительно, в некоторых ситуациях такой вариант проходит. Например, если размер картинки все-таки задан. Предположим, это резиновый блок новостей. Картинка не может быть шире, скажем 200px, а уже текст тянется и занимает всю оставшуюся ширину.

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

Запретить обтекание можно просто добавив overflow:hidden; для текстовой колонки. Тем самым мы установим для нее новый контекст форматирования (подробнее эта тема скоро будет раскрыта).

Единственный браузер, который среагирует на это неправильно — это конечно IE6. Специально для него колонке устанавливаем layout, например «флоатим» (ширину при этом задавать не понадобится).

Итак, решение поставленной задачи выглядит так:

.photo {
	float: left; /* задаем обтекание */
	margin:10px; /* отступ для красоты */
	display:inline; /* для IE6, чтоб отступ слева не удвоился */
}
.description{
	overflow:hidden;
}
* html .description{	
	float:left;
}

Как всегда, в боевых условиях вместо хаков используем условные комментарии.

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

  • IE 6-8
  • Firefox 3.0-3.6
  • Opera 9.5-10.5
  • Safari 4
  • Chrome 5

Плюс

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

Минус

Overflow:hidden не применимо, если в текстовой колонке есть, например, выпадающие окошки или какие-нибудь другие выступающие элементы.

Альтернативное решение

Update by Тимур, Vladimir

Тот же эффект отмены обтекания получим, если использовать для текстовой колонки display:table-cell; (или table). Для IE6-7 опять же придется устанавливать layout:

.photo {
	float: left; /* задаем обтекание */
	margin:10px; /* отступ для красоты */
	display:inline; /* для IE6, чтоб отступ слева не удвоился */
}
.description{
	display:table-cell;
	zoom:1; /* Осторожно! Строка невалидна  */
}

Но нужно иметь в виду, что если текста будет меньше чем на 1 строку, то следующий блок с текстом может расположиться справа от .description. То есть, у всего нашего текста с картинкой должен быть контейнер.

Материал

  • Correcting Orphans w/ Overflow