Проблема рендеринга WebKit при использовании переполнения: скрыто;
Я столкнулся с проблемой рендеринга в webkit при использовании overflow: hidden; на дочернем div, а затем увеличивая высоту родительского div с помощью javascript. Я свел мою проблему к следующему примеру кода.
Создайте страницу из этого источника и затем визуализируйте в браузере WebKit (Safari, Chrome). Нажмите на кнопку "Развернуть", и вы увидите, что div, которые переполнены: hidden; установить и теперь должен отображаться на основе расширенной родительской высоты div не отображаются. В браузерах Gecko (Firefox) и Trident (ID) это работает нормально.
Есть идеи или предложения для обхода? По сути, я хочу вручную создать таблицу div, которая содержит текст внутри родительского div, и я не хочу, чтобы текст переносился или выходил за границы div. Мне нужно иметь возможность регулировать высоту родительского div на основе других вещей, происходящих на странице.
Спасибо! Барт
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Language" content="en-us" />
<style type="text/css">
#test_container {
width: 540px;
}
.column_allow_overflow {
float: left;
width: 100px;
height: 16px;
margin-left: 4px;
padding: 3px;
}
.column_no_overflow {
float: left;
width: 100px;
height: 16px;
margin-left: 4px;
padding: 3px;
overflow: hidden;
}
.background {
background-color: #444444;
color: #e5e5e5;
}
.data_row {
height: 22px;
width: 100%;
padding-bottom: 22px;
background-color: #cccccc;
}
#expand_container {
overflow:scroll;
overflow-x: hidden;
-ms-overflow-x: hidden;
height: 100px;
width: 100%;
background-color: #cccccc;
}
</style>
</head>
<body>
<div id="test_container">
<div class="data_row background">
<button type="button" id="expand_button" onclick="expand();">Expand</button>
</div>
<div id="expand_container">
<div class="data_row background">
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
</div>
<div class="data_row background">
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
</div>
<div class="data_row background">
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
</div>
<div class="data_row background">
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
</div>
<div class="data_row background">
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
<div class="column_allow_overflow background">
Overflow allowed
</div>
<div class="column_no_overflow background">
Overflow NOT allowed
</div>
</div>
</div>
</div>
<script>
var expand = function (e) {
var button = document.getElementById('expand_button');
var expand_container = document.getElementById('expand_container');
button.onclick = contract;
expand_container.style.height = '160px';
button.innerHTML = "Contract";
};
var contract = function (e) {
var button = document.getElementById('expand_button');
var expand_container = document.getElementById('expand_container');
button.onclick = expand;
expand_container.style.height = '100px';
button.innerHTML = "Expand";
};
</script>
</body>
</html>
3 ответа
Изменить: Теперь, когда у меня было немного времени, чтобы подумать об этом снова, я понял, что то, что я говорил в первоначальном ответе, верно и все, но это проблема перекомпоновки в двух словах, так как она появляется только тогда, когда вы увеличить высоту. А поскольку это проблема перекомпоновки, решение очень простое, добавьте position:lative:
.data_row {
position: relative;
height: 22px;
width: 100%;
padding-bottom: 22px;
background-color: #cccccc;
}
Проверено, что это работает сейчас просто отлично. Я собираюсь оставить оригинальный ответ в прикрепленном для образовательных целей.
У меня нет для вас хорошего решения, но я думаю, что ваша проблема не только в переполнении: скрытом. Это комбинация float + overflow: скрыто. Если вы удаляете плавающие элементы и, например, размещаете элементы абсолютно на странице, ваш скрипт прекрасно работает в браузерах WebKit. Нет проблем с переполнением. Я не уверен, что это то, что вы хотите сделать, хотя. Проблема в том, что на самом деле переполнение не только контролирует, будет ли показываться ваш контент, если контейнер слишком мал, но в сочетании с плавающими элементами оно также может устанавливать размеры самих контейнеров.
Вот очень простой пример этого:
<div style="width: 500px; overflow: hidden;">
<div style="width: 200px; float: left; height: 100%; background-color: red;"></div>
<div style="width: 200px; float: right; height: 100%; background-color: orange;"></div>
<div style="background-color: green; overflow: hidden;">aaa</div>
<div>
Установка переполнения, как ни странно, работает как очистка с плавающей точкой. Он не очищает поплавок в элементе, он очищается самостоятельно. Это означает, что элемент с примененным переполнением (авто или скрытый) будет расширяться настолько, насколько это необходимо, чтобы охватить дочерние элементы, которые находятся внутри плавающего (вместо свертывания), предполагая, что высота не объявлена.
Я думаю, из-за этого у вас возникли проблемы с вашим дизайном.
Я предлагаю вам использовать display: table-cell, если предполагается, что все элементы имеют одинаковую высоту, макет таблицы, если вы не div-пурист, или абсолютное позиционирование.
PS Извините, вероятно, это должен был быть комментарий, а не ответ, так как я не могу предложить хорошее решение, но это было слишком долго для комментария.
Мне удалось найти немного некрасивый обходной путь, который исправляет его (примечание: с таким же успехом можно перейти к основанию.... Я нашел лучшее решение). Внутри элемента expand_container я добавил еще один div, который содержит другие элементы. В функциях раскрытия и сжатия я удаляю этот элемент из его родителя (expand_container), измеряю размер expand_container, а затем добавляю этот div обратно. Проблема больше не происходит.
<div id="expand_container" >
<div id="inner_container" style="margin:0; padding:0"> <!-- new element! -->
<div class="data_row background">
<div class="column_allow_overflow background">
...
затем...
var expand = function (e) {
var button = document.getElementById('expand_button');
var expand_container = document.getElementById('expand_container');
var inner_container = document.getElementById('inner_container'); // new
expand_container.removeChild(inner_container); // new
button.onclick = contract;
expand_container.style.height = '160px';
expand_container.appendChild(inner_container); // new
button.innerHTML = "Contract";
};
так далее...
Редактировать:
К вашему сведению, если вы не хотите изменять свою структуру dom путем добавления этого внутреннего элемента, вместо этого вы можете восстановить все дочерние элементы файла расширения_контейнера, а затем добавить их обратно после определения размера. Например:
var len = expand_container.childNodes.length, i, a = [];
for (i=len-1; i>=0; i--)
a.push(expand_container.removeChild(
expand_container.childNodes.item(i)));
button.onclick = contract;
expand_container.style.height = '160px';
for (i=len-1; i>=0; i--)
expand_container.appendChild(a[i]);
Возможно медленный, если у вас есть миллион элементов, но на вашем примере это работает как шарм.
Правка 2: хорошо, просто подумал о чем-то, что работает еще лучше.... удалите expand_container и добавьте его обратно в то же место. Опять же, работает нормально (даже если nextSibling имеет значение null):
var next = expand_container.nextSibling;
var parent = expand_container.parentNode;
parent.removeChild(expand_container);
button.onclick = contract;
expand_container.style.height = '160px';
parent.insertBefore (expand_container, next);
Я слишком близок к аварийному завершению, чтобы копировать-вставлять-тестировать ваш код в это ночное время (ну, это ночь, где я нахожусь), но при условии, что ваша проблема в том, что элементы-потомки данного содержащего элемента не перекомпоновываются правильно, когда вы меняете соответствующий стиль, попробуйте также добавить:
expand_container.className = expand_container.className;
сразу после смены стиля. Похоже, что он ничего не должен делать, но в каждом протестированном браузере он заставляет браузер перекомпоновывать контейнер и все его содержимое, что должно исправить ситуацию.
Вы также можете сообщить об этом как об ошибке на http://bugs.webkit.org/ если это не известная ошибка.