Отменяем обтекание текстом картинки
Дата публикации: 05.11.2010
Задача
Сверстать блок, состоящий из картинки и текста, причем текст не должен обтекать картинку.
слева правильно, справа — нет
Дополнительное условие: ширина ни текста, ни картинки строго не определена. При отсутствии картинки текст занимает всю отведенную ширину.
Решение
Будем считать, что левая колонка может содержать не только картинку, а что-либо еще. Поэтому 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: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 7.11.2010 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. То есть, у всего нашего текста с картинкой должен быть контейнер.