Проблема с oveflow: hidden

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

Проблема

Opera иногда не понимает overflow: hidden.

Теория

Такой баг можно получить, если внутри блока-родителя есть дочерний блок с размерами, превосходящими размеры родителя. Особенно ярко выражена проблема, если у родителя нет четко заданных размеров (блок резиновый).

<div class="parent">
	[...]
	<div class="child"></div>
</div>
.parent {
	width: 200px;
        height: 200px;
	overflow: hidden;
	position: relative;
}
.child {
	position: absolute;
	top: 0;
	left: 0;
	width: 10px;
	height: 200000px;
	background: url(paht-to/back.png);
}

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

Эта проблема у Opera с долгой историей, начиная еще с древних версий вроде 8.0. А может и еще с более ранних. Не знаю, я их не застал.

О причинах такого поведения можно только гадать.

Решение

По возможности следует избегать приемов с большими размерами. Иногда можно обойтись height/width: 100%. Если же без этого никак, спасает overflow: hidden у контейнера для нашего блока parent.

<div class="parentWrap">
<div class="parent">
	[...]
	<div class="chilid"></div>
</div>
</div>
.parent {
	width: 200px;
	overflow: hidden;
	position: relative;
}
.child {
	position: absolute;
	top: 0;
	left: 0;
	width: 10px;
	height: 200000px;
	background: url(paht-to/back.png);
}
.parentWrap {
	overflow: hidden;
}

Заметка

Чтоб не плодить лишних DOM элементов, достаточно любому из родителей блока с багом добавить overflow: hidden, а не добавлять специальный контейнер.

Решение 2

update by Иван Колесников: еще один способ — не задавать родителю четких размеров. Например, в нашем примере не указывать высоту для блока с классом parent.

Еще один вариант — для блока с большими размерами не использовать position: absolute. Такой вариант не для всех случаев подходит, но работает лучше остальных.