使用 :after 生成内容时的 z-index IE8 错误

发布于 2024-12-26 14:27:51 字数 1158 浏览 0 评论 0原文

这是 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 会在红色矩形下方呈现青色矩形(:after),即使它有较低的 z 指数。
现在是棘手的部分:
将 #target>div 的 z-index 从 0 更改为 -1,瞧!解决了!

所以我现在使用大量 z-index: -1;
解决了我的问题 但我对此感到不安全。

你知道更好的解决方案吗?

我使用 :after 伪元素,因为我有一个产品列表,并且我想在该项目具有“已售出”类时向该项目添加图像示例。
我可以在服务器中或使用 JS 创建一个新的 html 元素,但我认为使用 :after 是正确的语义解决方案。
问题是我现在对 :after 伪元素有点偏执,你认为最好避免它吗?

This is a known error in IE8, look at the last bug here:
http://nicolasgallagher.com/css-typography-experiment/demo/bugs.html

Now, playing a bit with a simple example I found this (test it using 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 renders the cyan rectangle (the :after) below the red rectangle, even when it has lower z-index.
And now the tricky part:
change the z-index for #target>div from 0 to -1 and voilá ! it's solved !

So I solved my problem now using a lot of z-index: -1;
But I don't feel safe with this.

Do you know a better solution?

I'm using the :after pseudoelement because I have a list of products, and I want to add an image to the the item when it has the class 'sold' for example.
I can create in the server or with JS a new html element for that, but I think using :after is the correct semantic solution.
The problem is that I'm a bit paranoid about the :after pseudoelement now, do you think is better to avoid it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

星軌x 2025-01-02 14:27:51

首先回答你的最后一个问题,只要你不需要支持任何完全不支持生成内容的浏览器(http://caniuse.com/#feat=css-gencontent) 那么你不需要避免它。但是,由于您注意到这是一个已知的错误,因此您应该小心

在这个具体示例中,我可以想到三种不同的方法来解决该错误。这些对您是否有用取决于您的实际用例。

  1. 使用 :after 而不是 :before 并删除子 div 的定位: http://jsfiddle.net/AjCPM/24/

    <前><代码>#目标{
    位置:相对;
    宽度:200px;
    高度:200px;
    z 索引:1;
    }

    #目标>div{
    背景:红色;
    宽度:200px;
    高度:200px;
    }

    #目标:{之后
    内容:“之后”;
    位置:绝对;
    顶部:0;
    左:10%;
    宽度:100%;
    高度:100%;
    背景:青色;
    z 索引:10;
    }

  2. 将 after 添加到子 div 而不是父级:http://jsfiddle.net/AjCPM/26/

    <前><代码>#目标{
    位置:相对;
    宽度:200px;
    高度:200px;
    z 索引:1;
    }

    #目标>div{
    位置:相对;
    背景:红色;
    宽度:200px;
    高度:200px;
    z 索引:0;
    }

    #target>div:之前{
    内容:“之后”;
    位置:绝对;
    顶部:0;
    左:10%;
    宽度:100%;
    高度:100%;
    背景:青色;
    z 索引:10;
    }

  3. 使用包装元素(通常是因为您已经有一个)将基本样式应用到:http://jsfiddle.net/AjCPM/29/

     
    div
    #目标 { 位置:相对; 宽度:200px; 高度:200px; z 索引:1; } #wrap>div{ 位置:相对; 背景:红色; 宽度:200px; 高度:200px; z 索引:0; } #wrap>div:之前{ 内容:“之后”; 位置:绝对; 顶部:0; 左:10%; 宽度:100%; 高度:100%; 背景:青色; z 索引:10; }

基本上,当面对这样的浏览器之间的解释差异时,您最好的选择是尝试重新安排您的方法以找到跨浏览器的工作方式。

To answer your last question first, as long as you don't need to support any browsers that completely lack support for generated content (http://caniuse.com/#feat=css-gencontent) then you shouldn't need to avoid it. However, since you note that this is a known bug, you should be careful about it.

In this specific example, I can think of three different ways to work around the bug. Whether these are useful to you depends on your actual use case.

  1. Use :after instead of :before and remove positioning from the child 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. Add the after to the child div instead of the parent: 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. Use a wrapping element (usually because you already have one) to apply the base styling to: 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;
    }
    

Basically, when faced with a difference in interpretation between browsers like this, your best bet is to try to rearrange your approach to find something that works cross-browser.

一百个冬季 2025-01-02 14:27:51

无需设置 z-indexes,只需确保使用 :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 添加图像。

No need to set z-indexes, just make sure you use :after instead of :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;
}​

Since the generated content comes after #target, it will naturally be stacked above.

BTW Whether a product is "sold" or not is semantic information, and so the correct semantic solution would be to include it in the HTML, rather than adding the image through CSS.

季末如歌 2025-01-02 14:27:51

关于 IE8 中的 :before 和 :after 选择器的快速注释:要使它们工作,您需要声明 DOCTYPE。请参阅此 W3Schools 页面。我猜你已经这样做了。

如果您还没有,请参阅此问题的答案已经(我想你可能已经有了)。

基本上,底线是这是一个错误。您使用 -1 的 z-index 的解决方案并不理想,但同样,没有解决该错误的方法也不会是理想的。我不认为使用 -1 的 z-index 是值得过度关注的事情,除非它会导致布局出现问题。如果您非常担心,那么为什么不只针对 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 的样式表。

A quick note on the :before and :after selectors in IE8: for them to work you need to declare a DOCTYPE. See this W3Schools page. I am guessing you have already done this though.

See the answer to this question if you haven't already (I think you probably have).

Basically, the bottom line is that it's a bug. Your solution of using a z-index of -1 is not ideal, but then again NO work around for the bug is going to be ideal. I don't think that using a z-index of -1 is something to be overly concerned about, unless it causes issues in your layout. If you are very concerned, then why don't you ONLY target IE8 w/ the fix. For example, you could use a conditional comment like so:

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

Behaviors like the one you are experiencing is one of the reasons many developers despise IE. In many cases, including this one, there is no perfect solution. You could:

  1. stop using the :before and :after selectors & adjust your HTML/CSS to something that is IE8-friendly.
  2. Use conditional comments or JavaScript to issue a fix that specifically targets IE8
  3. Keep hacking and try to find another HTML/CSS combo that works -- but chances are it won't be any more ideal than your negative z-index solution.

Unfortunately, in many cases there is no such thing as a "semantically correct" cross-browser website.

My two cents is to create an IE8 stylesheet and use the conditional comment I displayed above to load the stylesheet. Within the stylesheet, use the z-index: -1 solution you came up with. Many websites use IE-targeted stylesheets.

寂寞清仓 2025-01-02 14:27:51

我使用不同的方法来解决这个问题:

每个产品的 HTML 都包含一个“已售完”横幅,可以放置在主图像上。默认情况下,CSS 隐藏此元素。如果包装“产品”DIV 包含“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);
}

I use a different method to solve this problem:

The HTML for each product contains a "sold out" banner that can be positioned over the main image. By default the CSS hides this element. If the wrapping "product" DIV contains a class of "soldOut" the CSS will override the default declaration and display the banner.

<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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文