Проблема рендеринга WebKit при использовании переполнения: скрыто; - PullRequest
2 голосов
/ 11 ноября 2010

Я столкнулся с проблемой рендеринга в webkit при использовании overflow: hidden; на дочернем div и затем увеличении высоты родительского div с использованием javascript.Я свел мою проблему к следующему образцу кода.

Создайте страницу из этого источника и затем визуализируйте в браузере WebKit (Safari, Chrome).Нажмите на кнопку «Развернуть», и вы увидите, что div, которые имеют overflow: hidden; set и теперь должны отображаться на основе расширенной родительской высоты 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 ]

1 голос
/ 21 ноября 2010

Редактировать: Теперь, когда у меня было немного времени, чтобы подумать об этом снова, я понял, что слова, которые я говорил в первоначальном ответе, верны и все, но это проблема перекомпоновки в двух словах, так как она показывает только когда вы увеличиваете высоту. И поскольку это проблема перекомпоновки, решение очень простое, добавьте 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-пурист, или абсолютное позиционирование.

P.S. Извините, вероятно, это должен был быть комментарий, а не ответ, так как я не могу предложить хорошее решение, но это было слишком долго для комментария.

0 голосов
/ 21 ноября 2010

Я слишком близок к аварийному завершению, чтобы копировать-вставлять-тестировать ваш код в это ночное время (ну, это ночь, где я нахожусь), но при условии, что ваша проблема в том, что дочерние элементы данного содержащего элемента нене правильно переформатировать при изменении соответствующего стиля, попробуйте также добавить:

expand_container.className = expand_container.className;

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

Вы также можете сообщить об этом какошибка на http://bugs.webkit.org/, если она не известная ошибка .

0 голосов
/ 21 ноября 2010

Мне удалось найти немного некрасивый обходной путь, который исправляет его (примечание: с таким же успехом можно перейти к нижней части .... Я нашел лучшее решение) .Внутри элемента 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, добавив этот внутренний элемент, вместо этого вы можете восстановить все дочерние элементы файла expand_container, а затем добавить их обратно после определения размера.Например:

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);
...