Лишние отступы под изображениями в IE6,7
Четверг, 12 июня 2008

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

Теперь HTML-код:
<div class="image_box"> <img src="картинка.jpg" width="200" height="200" alt="Красивая картинка" /> </div>
CSS:
.image_box {
width: 200px;
height: 200px;
border: 3px solid black;
}
Кстати, IE очень последовательный браузер, даже в своих багах, поэтому и в табличной верстке наблюдаются те же проблемы (HTML):
<table id="bug_table"> <tr> <td class="image_box"> <img src="картинка.jpg" width="200" height="200" alt="Красивая картинка" /> </td> </tr> </table>
Табличку привожу просто для примера, поэтому она такая слабенькая.
И к ней CSS:
#bug_table {
border-collpase: collapse;
border: none;
}
.image_box {
width: 200px;
height: 200px;
border: 3px solid black;
}
По идее, в обоих случаях, мы должны были получить просто рамку толщиной в 3 px вокруг изображения и ничего больше. Но в результате, в первом и во втором варианте, наблюдается непонятный отступ под изображениями. В свое время это была проблема 6-ой версии браузера, но, к своему удивлению, я обнаружил ее и в 7-ой (оказалось баги по наследству передаются).
Лекарство от головной боли
Решение странное, но работает. Нужно удалить из HTML-кода все пробелы, отступы и переносы строк, т.е. превратить его вот в это для первого случая:
<div class="image_box"><img src="картинка.jpg" width="200" height="200" alt="Красивая картинка" /></div>
И вот в это для второго:
<table id="bug_table"><tr><td class="image_box"><img src="картинка.jpg" width="200" height="200" alt="Красивая картинка" /></td></tr></table>
После такого исправления лишние отступы исчезнут и мы получим ожидаемый результат.
Страничка с рабочим примером тут. Смотреть, естественно, в обоих Эксплорерах.
Кстати, проблема может проявить себя не только с изображениями. У меня были такие отступы, когда я встраивал в div и таблицу, и неупорядоченный список — под ними также были лишние просветы. Поэтому будьте внимательны.
Нашелся способ получше!
Спасибо Octane, за толковый совет. Теперь ясна природа явления и лучший способ решения проблемы. Читайте комментарии!
Ради интереса, зарегистрировался на blogowar.ru, теперь можете следить и там за моими успехами.
Сканер блогов (ищем умные мысли):
Настя Манно размышляет о «О бесплатности «бесплатных» тем для WP». В БлогДозоре несколько интересных ссылок на SEO-блоги. Ну а для любителей поиграть во Flash на работе — прикольная игра про робота-телепорта на блоге urbanian.ru.
* * *
Понравилась статья?
Тогда помогите мне сделать её доступной для других, или будьте в курсе событий:
- подпишитесь на обновления по RSS
- получайте новые статьи на E-mail

- добавьте в Twitter: Лишние отступы под изображениями в IE6,7
- добавьте статью в закладки:
* * *

Убери эти глупости, это совсем не баг, а вертикальное выравнивание изображения по умолчанию base-line.
Лечится всего лишь одним простым свойством:
img { vertical-align: top; }А какое может быть вертикальное выравнивание, если контейнер и содержимое одинаковой высоты? Откуда тогда отступ? И почему выкрутасы с HTML помогают решить проблему? Однозначно неправильное поведение IE (читай баг).
Выравнивание и вправду помогает, спасибо за еще одно решение проблемы. Оно, насколько я помню, прописано в мейеровском CSS-ресете, но не все им пользуются, поэтому встречаются траблы. Этот способ что-то я упустил из виду.
Просто IE немного подругому обрабатывает пробелы (табуляторы, разрывы строк) внутри контейнера, и в этом случае параметр base-line, установленный по умолчанию для img, рассчитывается не так, как в нормальных браузерах, отсюда и появляются лишние отступы, а т. к. для родительского контейнера не установлено свойство overflow, то значение height задает лишь минимальную высоту контейнера в IE6.
В любом случае верстальщикам нужно знать про эту особенность. Согласен?
Я всегда сбрасывал значения по умолчанию и редко с ней встречался, а недавно на одном давно сверстанном сайте столкнулся и пришлось выкручиваться описанным мной способом.
Отлично, что мы нашли более эффективный способ. Подправлю-ка я слегка пост...
Знать конечно нужно и reset.css надо самому написать ;) очнь полезно будет.
Спасибо за ссылочку! :)
У вас потрясающе красивый блог! А менюшка просто завораживает! С удовольствием добавила к себе в ридер.
2 Настя
Недавно, кстати, тоже стал вас читать. Почему-то не находил ваш блог раньше. Особенно нравятся статьи про стили в веб-дизайне — моя слабость и большой интерес.
Знакомый баг :)
Я про лишние пробелы и переносы строк писал еще год назад здесь...
Спасибо за css-решение :)
2 rotor
А моему бложику всего пара месяцев еще. Но это только начало! :)
Настя
Зато какое начало!
Виктор, что именно?
rotor, Виктор — это спамер. Вряд ли он вам ответит :)
ыыы бестолковый спамер наверна :D ссылки то nofollow
Зато в какой-то степени он своего добился. Сначала привлек мое внимание, а теперь и ваше ))
Женя, Виктор это за**вший всех блоггеров спамер, киляй его!) Хоть в посте и не почерпнул для себя интерересного в виду совершенно иного вида деятельности, хочу улучить момент поздравить твой блог с хорошим стартом и внести лепту в популярность поста в виде еще одного коммента)))
Когда труды свои монетизировать начнешь?
Серега, спасибо! Спамера забанил.
Насчет монетизации — с удовольствием, но пока загрузка очень большая. Хочется реализовать несколько вещей в блоге, с целью улучшить, но времени нет. Думаю к выходным начну активно продвигать проект.
[...] Источник: Лишние отступы под изображениями в IE6,7 [...]
Я для лечения этого бага ставил после изображений тег . Не знаю, как именно баг работает (то есть уже знаю), но помогало. Тем и спасался. В остальных браузерах все нормально. Способ решения выяснил совершенно случайно ;)
Никакого бага тут нет, равно как и неправильного поведения.
Всё корректно и по стандарту:
IMG — это внутристрочный(текстовый) элемент, а значит он имеет свойство vertical-align (загляните хотя бы в dtd-файл, там всё расписано).
По-умолчанию у IE и Safari для IMG это свойство равно baseline
Так как тэг IMG есть заменяемый элемент, то это свойство действует на изображение, которым он заменяется.
Корректнее всё-таки указывать vertical-align:bottom
Значение top тоже «сработает», но вызывает неоднозначность в случае, если высота изображения больше высоты строки(а таких случаев большинство ;) ).
А случаи неоднозначности броузер вправе обрабатывать «как-ему-вздумается» — так прописано в спецификации CSS.
В общем случае, тот шаблон страницы отображается _одинаково_ во всех броузерах, который не содержит неоднозначностей.
Кстати, часть «багов броузеров», описанных в инете, есть попытка автора статьи заставить броузер нарушить правила модели визуального форматирования, вместо того, чтобы привести свой шаблон страницы в соответствие с ней ;)
www.w3.org/TR/CSS21/visuren.html
Wasly
Я понял вашу точку зрения, спасибо.
Только если отбросить CSS в сторону, никто не может объяснить, почему можно избавиться от лишних отступов приведением HTML в нечитаемый вид.
По поводу последнего абзаца согласен. Но тем не менее, знать те грабли, на которые наступают другие кодеры, никогда не лишне :)
IE6 в случае с «bottom» не опускает текст к нижнему краю изображения, в отличие от других браузеров, а действует так же, как и в случае с «top» — текст остается на уровне верхней границы изображения, поэтому лучше использовать значение «top».
2rotor
«никто не может объяснить...»
Попробую обяснить.
Вы внутрь блочного бокса поместили внутристрочный элемент создав неоднозначность для броузера и ждете однозначного поведения от него? ;)
Поместите изображение в строчный бокс — то есть окружите img тэгом p или span и всё встанет на свои места.
2Octane
Странно, у меня значение bottom отрабатывается и под IE6 и под IE7 и под Safari 3 абсолютно одинаково. Может вы допускаете ту же ошибку? Внутристрочный элемент должен всегда находится внутри строчного бокса.
Иначе броузер формирует неименнованный(анонимный) бокс свойства которого вы никак не можете изменить!
www.w3.org/TR/CSS21/visur...mous-block-level
Кстате в Opera 9.51 такая же фигня screenshot
И в Опере и в Лисе появляется «такая же фигня», если явно указать строчный бокс, что вы и сделали.
Но ваш пример некорректный, как я говорил ранее, так как высота изображения больше высоты строки.
Сделайте изображение высотой 10px и посмотрите, что произойдет и как отрабатываются у vertical-align значения top и bottom.
Только что проверил под IE6 и top и bottom отрабатываются корректно как с тэгом p так и с неименованным боксом.
Но при top верх картинки выравнивается по верху строки, а при bottom низ картинки прижимается к низу строки.
В случае, если высота изображения больше высоты строки, то при значении top строка будет прижата к верху обраляющего блока, что не есть гуд ;)
Вдогонку.
2Octane
Не используйте бордюр для p
Чтобы было нагляднее — укажите разны цвета для фонов body и p
Валидатор не выдает ошибки, значит ничего противоестественного не сделано, тег <img /> может находится непосредственно в <p>. При использовании «
vertical-align: bottom;» наблюдается не одинаковое поведение браузеров, так зачем самому себе создавать проблемы?Вы только что сами проверили — броузеры выдают одинаковый результат. Не вижу проблемы.
Валидатор проверяет лишь корректность структуры документа, а такие «мелочи» как к примеру недостающий размер блочного бокса или заподзание контента за границы бокса он еще распозновать не научился.
Валидатор лишь следит, чтобы блочный бокс обрамлял строчный.
А то, чтобы строчный бокс обралял контент, он не отслеживает,так как подразумевается, что броузер вставит неименованный бокс при формировании страницы.
Ух ты! Битвы в комментах!
Жаль что сам сейчас завален работой, так бы и я подключился.
Но всё, что пишете, обязательно попробую и проверю.
В общем-то битвы никакой. Вроде кто-то хотел разобраться в этом вопросе. И это точно не я, ибо знаю правильный ответ :)
Вот скриншот
На котором черное изобращение 100px на 10px благополучно выровнилось по низу строки с помощью vertical-align: bottom
(броузеры IE6, FF2, Opera9.5)
Wasly
Ok. Спасибо за терпение и последовательность в объяснениях :)
Выдалась минутка... Вот скриншот к теме «Почему у IE6 всё по разному». Чтобы закрыть эту тему :)
Объяснение просто.
CR и LF являются символами шрифта, а значит броузер может вычислить высоку строки и baseline. Что он и делает — пример 1. А затем выравнивается черное изображение 100×10 по baseline (как задано у него по умолчанию).
Если убрать эти символы (пример 2), то броузер не знает высоту шрифта, так как img не несет такой информации, и не может построить baseline. Поэтому он строит строку без baseline высотой равной высоте изображения. (этот случай создает неоднозначность — броузер справляется с ним как может, но зато результат устраивает начинающего кодера, а значит «всё правильно» — считает он ;) )
Пример 3 сделан для подтверждения сказанного, к img добавлены 2 пробела(слева и справа от него), как видите, результат тот же что и в примере 1 с CR/LF.
Есть ещё немного другое объяснение, но отличается лишь началом — выводы всё-равно те же :)
Есть один интересный нюанс, который касается IE7 и Mozilla 3.0 и более поздних (насчет более ранних браузеров не проверяла). Так вот, если img поставить в <p>, то в IE7 его положение остается неизменным, а вот в Mozilla появляется отступ сверху(видимо строка, или что-то еще). Не проверяла, но думаю это тоже как-то связано с выравниванием... Так что баги FOREVA))))) . Как исправлю эту мелочь — напишу)) Или может кто подскажет рецепт)). А блог хорош — я нечасто пишу комменты)), а вот сюда даж приятно. Особенно сносную грамотность комментаторов.
Wasly — ты профи))). Очень четкий подход к проблеме.
(inline стиль здесь просто для наглядности, стили выносятся в файл)
Фиксит данный баг в IE 6/7 и в ряде версий Opera
Есть ещё один простой способ который помогает, превратить изображение в блочный элемент img {display:block;}.
Пример тут design-for-you.ru/ie6img.htm
Здравствуйте.
Спасибо за статью.
У меня вопрос немного не по теме...
Я только учусь...
Возникла проблема. Во всех браузерах нормально отображается, но в ИЕ6 при прописывании тега margin-left:20px; текст слева сдвигается вместе с картинкой под ним, что нарушает всю структуру сайта.
br.lora.in.ua
Подскажите, пожалуйста, как можно исправить эту проблему.
Заранее благодарна.
Спасибо.
Ирина, давайте подробнее что и где, и лучше через e-mail.
rotor, извините, немного потерялась.
«Методом проб и ошибок» а также «методом научного тыка» исправила положение картинки в ИЕ6, но он не перестаёт меня «радовать».
Теперь картинку png, которая должна быть с прозрачным фоном, он искажает и выдаёт её на сером фоне. Сейчас читаю Вашу статью и буду пытаться исправить и эту ситуацию. :)
Спасибо огромное Вам за статьи и помощь!
Спасибо огромное!!!!!
Я иза этого бага 2 дня потерял!
Огроменное спасибо!
Спасибо огромное! Я не мог понять в чем дело и потерял 3 дня.
Octane и автору — мужики!!! спасибо!! я уже офигел искать в чем же дело у меня на сайте... вы реально сэкономиои кучу времени!!!!! жаль, что не нашел этот сайт раньше
А как насчет таблицы которая находится внутри div ' а ? ничего не помогает против этого мерзкого отступа... люди! ХЭЛП!
Без примера можно предлагать всё, что угодно.
А это точно не margin / padding? А reset.css используется? Все теги закрыты? ...