Ошибка z-index в IE8 для сгенерированного контента с: after - PullRequest
23 голосов
/ 12 января 2012

Это известная ошибка в IE8, посмотрите последнюю ошибку здесь:
http://nicolasgallagher.com/css-typography-experiment/demo/bugs.html

Теперь, немного поиграв с простым примером, я нашел это (протестируйте его с помощью IE8):
http://jsfiddle.net/AjCPM/

<div id="target">
   <div>div</div>
</div>


#target {
    position: relative;
    width: 200px;
    height: 200px;
    z-index: 1;
}
#target>div{
    background: red; width: 200px; height: 200px;  
    position: relative;
    z-index: 0;
}
#target:before {
    top: 0; left: 10%; width: 100%; height: 100%; background: cyan;
    content: "after";
    position: absolute;
    z-index: 10;
}

IE8 отображает голубой прямоугольник (the: after) под красным прямоугольником, даже если он имеет более низкий z-индекс.
А теперь сложная часть:
изменить z-index для #target> div с 0 на -1 и вуаля! это решено!

Итак, я решил свою проблему сейчас, используя множество z-index: -1;
Но я не чувствую себя в безопасности с этим.

Знаете ли вы лучшее решение?

Я использую псевдоэлемент: after, потому что у меня есть список продуктов, и я хочу добавить изображение к элементу, когда он имеет класс «продано», например.
Я могу создать на сервере или с помощью JS новый HTML-элемент для этого, но я думаю, используя: after - это правильное семантическое решение.
Проблема в том, что я немного параноидален по поводу: после псевдоэлемента как вы думаете, лучше его избегать?

Ответы [ 4 ]

3 голосов
/ 29 июня 2012

Не нужно устанавливать z-index es, просто убедитесь, что вы используете :after вместо :before ( demo ):

#target {
    position: relative;
    width: 200px;
    height: 200px;
}
#target>div{
    background: red;
    width: 200px;
    height: 200px;
}
#target:after {
    content: "after";
    position: absolute;
    top: 0;
    left: 10%;
    width: 100%;
    height: 100%;
    background: cyan;
}​

Поскольку сгенерированный контент следует после #target, он будет естественным образом размещен выше.

Кстати, является ли продукт «проданным» или нет семантической информацией, и поэтому правильное семантическое решение будет включать его в HTML, а не добавлять изображение через CSS.

3 голосов
/ 28 июня 2012

Чтобы ответить на ваш последний вопрос в первую очередь, если вам не нужно поддерживать какие-либо браузеры, в которых полностью отсутствует поддержка сгенерированного контента (http://caniuse.com/#feat=css-gencontent)), вам не нужно его избегать. Однако, поскольку выобратите внимание, что это известная ошибка, вы должны быть осторожны .

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

  1. Используйте :after вместо :before и удалите позиционирование у ребенка div: http://jsfiddle.net/AjCPM/24/

    #target {
        position: relative;
        width: 200px;
        height: 200px;
        z-index: 1;
    }
    
    #target>div{
        background: red;
        width: 200px;
        height: 200px;
    }
    
    #target:after {
        content: "after";
        position: absolute;
        top: 0;
        left: 10%;
        width: 100%;
        height: 100%;
        background: cyan;
        z-index: 10;
    }
    
  2. Добавьте потомок к потомку div вместо родителя: http://jsfiddle.net/AjCPM/26/

    #target {
        position: relative;
        width: 200px;
        height: 200px;
        z-index: 1;
    }
    
    #target>div{
        position: relative;
        background: red;
        width: 200px;
        height: 200px;
        z-index: 0;
    }
    
    #target>div:before{
        content: "after";
        position: absolute;
        top: 0;
        left: 10%;
        width: 100%;
        height: 100%;
        background: cyan;
        z-index: 10;
    }
    
  3. Используйте элемент обтекания (обычно потому, что он у вас уже есть)), чтобы применить базовый стиль к: http://jsfiddle.net/AjCPM/29/

     <div id="target">
         <div id="wrap">
             <div>div</div>
         </div>
     </div>
    
    #target {
        position: relative;
        width: 200px;
        height: 200px;
        z-index: 1;
    }
    
    #wrap>div{
        position: relative;
        background: red;
        width: 200px;
        height: 200px;
        z-index: 0;
    }
    
    #wrap>div:before{
        content: "after";
        position: absolute;
        top: 0;
        left: 10%;
        width: 100%;
        height: 100%;
        background: cyan;
        z-index: 10;
    }
    

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

1 голос
/ 28 июня 2012

Краткое примечание о селекторах: before и: after в IE8: чтобы они работали, вам нужно объявить DOCTYPE.См. эту страницу W3Schools .Я предполагаю, что вы уже сделали это.

См. Ответ на этот вопрос , если вы этого еще не сделали (я думаю, что вы, вероятно, сделали).

В основном,Суть в том, что это ошибка.Ваше решение использовать z-index из -1 не является идеальным , но, опять же, НИКАКОЕ обходное решение для ошибки не будет идеальным.Я не думаю, что использование z-индекса -1 должно вызывать беспокойство, если только это не вызывает проблем в вашем макете.Если вы очень обеспокоены, то почему бы вам не нацелиться ТОЛЬКО на IE8 с исправлением.Например, вы можете использовать условный комментарий, например, так:

<!--[if IE 8]>
<style>
#target>div{
  z-index:-1;
}
</style>
<![endif]-->

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

  1. прекратить использование селекторов :before и :after и настроить HTML / CSS на что-то, что является IE8-совместимым.
  2. Использовать условные комментарии или JavaScript для выдачиисправление, специально предназначенное для IE8
  3. Продолжайте взламывать и пытайтесь найти другую работающую HTML / CSS-комбинацию, но есть вероятность, что она не будет более идеальной, чем ваше отрицательное z-index решение.

К сожалению, во многих случаях не существует такой вещи, как "семантически правильный" кросс-браузерный веб-сайт.

Мои два цента - создать таблицу стилей IE8 и использовать условный комментарий, который я отображал выше, чтобызагрузить таблицу стилей.В таблице стилей используйте решение z-index: -1, которое вы придумали.Многие веб-сайты используют таблицы стилей, ориентированные на IE.

0 голосов
/ 27 июня 2012

Я использую другой метод решения этой проблемы:

HTML-код для каждого продукта содержит «аншлаговый» баннер, который можно расположить поверх основного изображения.По умолчанию CSS скрывает этот элемент.Если DIV-пакет «product» содержит класс «soldOut», CSS переопределит объявление по умолчанию и отобразит баннер.

<div class="product soldOut">                                   
    ... product html ...
    <div class="soldOutBanner"></div>    
</div>

CSS:

.soldOutBanner {
     display:none
}

.soldOut .soldOutBanner {
    display:block; 
    width:133px;
    height:130px;
    position:absolute;
    top:0px;
    right:0px;
    z-index:10;
    background-image:url(../SoldOut.png);
}
...