Firefox: Как переполнение работает с фиксированным z-индексом и положением? - PullRequest
2 голосов
/ 17 ноября 2010

Меня смущает, как CSS для z-index, скрытого переполнения и фиксированного положения работают вместе в Firefox 3.6. Рассмотрим этот пример:

Первый DIV.fix_z0 - это позиция, фиксированная с z-index 0 и переполнение скрыто. Внутри это DIV.abs_z1 с абсолютной позицией с z-индексом 1. Внутри это DIV.fix_z2 с фиксированной позицией и z-индексом 2. Я ожидал бы, что все .fix_z2 будут видимы, даже если они находятся вне области просмотра .fix_z0 поскольку он является фиксированным и имеет более высокий z-индекс, чем базовый DIV.

В IE 8 это работает, как и ожидалось, но в FF 3.6, DIV.fix_z2 ограничено границами .fix_z0. Оба элемента фиксированы, но один вложен в другой. Спецификации W3C указывают, что фиксированные элементы должны быть удалены из потока документов, но что происходит, когда они вложены? Кроме того, поскольку содержащий элемент .abs_z1 имеет более высокий z-индекс, это должно установить новый контекст z-index, и все в .abs_z1 должно быть выше .fix_z0 (делая z-index для .fix_z2 неуместным, но я включил это, чтобы видеть, имело ли это значение.)

Осложняющим фактором является z-индекс. Если мы возьмем альтернативный пример, внутри .fix_z0 a DIV.abs_znone с абсолютной позицией и без z-индекса. Внутри этого мы помещаем DIV.fix_z1 с фиксированной позицией и z-индексом 1. Теперь DIV.fix_z1 не обрезается на .fix_z0. Мне кажется, что либо оба должны быть обрезаны, либо оба не должны быть обрезаны. Это ошибка или я неправильно понимаю правила CSS? Ниже приведен код для воспроизведения.

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Z-Index Woes</title>
<style type="text/css">
    body {
        background-color: black;
    }

    div.fix_z0 {
        position: fixed;
        left: 100px;
        top: 100px;
        bottom: 100px;
        right: 100px;
        background-color: #606060;
        overflow: hidden;
        z-index: 0;
    }

    div.abs_z1 {
        position: absolute;
        left: 50px;
        top: 50px;
        width: 200px;
        height: 200px;
        background-color: #550000;
        z-index: 1;
    }

    div.fix_z2 {
        position: fixed;
        left: 50px;
        top: 50px;
        width: 150px;
        height: 150px;
        background-color: #888800;
        z-index: 2;
    }

    div.abs_znone {
        position: absolute;
        right: 50px;
        bottom: 50px;
        width: 200px;
        height: 200px;
        background-color: #005500;
    }


    div.fix_z1 {
        position: fixed;
        right: 50px;
        bottom: 50px;
        width: 150px;
        height: 150px;
        background-color: #888800;
        z-index: 1;
    }

    p {
        position: absolute;
        font-size: 12pt;
        color: #EFEFEF;
        margin: 0;
        padding: 0;
    }

    p.center {
        text-align: center;
        width: 100%;
    }

    p.right {
        right: 0;
    }

    p.bottom {
        bottom: 0;
    }

</style>
</head>
<body>
    <div class="fix_z0">
        <p class="center">pos: fixed, z:0, overflow: hidden</p>
        <div class="abs_z1">
            <p class="right">pos: abs, z:1</p>
            <div class="fix_z2">
                <p class="right bottom">pos: fix, z:2</p>
            </div>
        </div>
        <div class="abs_znone">
            <p>pos: abs, z: none</p>
            <div class="fix_z1">
                <p>pos: fix, z:1</p>
            </div>
        </div>
    </div>
</body>
</html>

ОБНОВЛЕНИЕ 11/18/10 : Оба ответа пока что указывают на то, что .fix_z2 и .fix_z1 должны быть обрезаны на .fix_z0. Это сделало бы IE8 100% неправильным и FF 50% неправильным в примере кода.

Я бы сказал, что оба DIV не должны быть обрезаны, так как они исправлены. W3C устанавливает фиксированное позиционирование как подмножество абсолютного и абсолютно позиционированного элемента:

устанавливает новый содержащий блок для дочерних элементов нормального потока и абсолютно (, но не фиксированных ) потомков. [W3C]

Следовательно, мне кажется, что ни .fix_z0, ни .abs_z1, ни .abs_znone не должны устанавливать новый содержащий блок, на который обрезается фиксированное содержимое.

Стандартные значения W3C Z-Index:

целое число: Это целое число - уровень стека сгенерированного блока в текущем контексте стека. Блок также устанавливает локальный контекст стека, в котором его уровень стека равен «0».

auto: Уровень стека сгенерированного бокса в текущем контексте стекирования такой же, как у родительского бокса. Поле не устанавливает новый локальный контекст стека.

http://www.w3.org/TR/CSS21/visuren.html#z-index

Я не понимаю, почему z-index влияет на FF, но он имеет следующий эффект: поскольку .abs_znone не имеет z-index, он имеет тот же контекст стека, что и его родительский .fix_z0, и .fix_z1 будет иметь z-индекс по отношению к любым детям .fix_z0. В результате DIV.fix_z1 НЕ обрезается на .fix_z0. И наоборот, .abs_z1 устанавливает новый контекст стека, поскольку он имеет z-индекс, а .fix_z2 будет иметь z-индекс по отношению к любым дочерним элементам .abs_z1, но по какой-то причине это приводит к обрезанию .fix_z2 .fix_z0

Итог: я все еще ищу ответы на некоторые вопросы. IE или FF придерживаются стандартов здесь? Что вызывает отсечение на одном DIV в FF, а не на другом? Мое текущее мнение заключается в том, что IE корректен (для разнообразия) и что поведение FF содержит ошибки.

Ответы [ 2 ]

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

Вариант этого вопроса был задан здесь , и один из ответчиков дал эту ссылку для решения, но это было для IE7. Я попробовал предложение типа документа, но оно не дало никаких немедленных результатов.

(Кстати, в вашем примере кода, если вы дадите .abs_znone z-индекс, который связывает его с его родителем, и он ведет себя должным образом. Подсказка, возможно?)

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

Кажется, что дисплей FF правильный. Если у вас есть переполнение: скрыто для элемента, все дочерние элементы будут отображаться, только если они находятся в границах родительских объектов.

...