为什么伪元素上的滤镜渐变在IE8中不起作用?

Vla*_*kov 35 html css internet-explorer-8 pseudo-element

我想创建这样的按钮:
伪3d按钮

在现代浏览器中,使用插入框阴影和滤镜创建效果.
对于IE8 - 选择伪元素.
对于IE7 - 我使用包含在条件注释中的特殊标签.

演示:(http://jsfiddle.net/8M5Tt/68/)

/**
 * Button w/o images
 */
html {
    font-size: 62.5%;
    }
body {
    font: normal 1em/1em Arial, Tahoma, Verdana, sans-serif;
    }
 
/* layout */
.btn {
    display: inline-block;
    height: 28px;
    border-width: 1px;
    border-style: solid;
    width: 170px;
    box-sizing: content-box;
    overflow: hidden;
    position: relative;
    z-index: 1;
    }
.btn {
    margin: 15px;
    }
.btn.btn_small {
    width: 130px;
    }

/* ie7 */
.lt-ie8 .btn .before,
.lt-ie8 .btn .after {
    position: absolute;
    right: -1px;
    left: -1px;
    display: block;
    height: 3px;
    }
.lt-ie8 .btn .before {
    top: -1px;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#80ffffff', endColorstr='#00ffffff',GradientType=0 );
    }
.lt-ie8 .btn .after {
    bottom: -1px;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#80000000',GradientType=0 );
    }
/* /ie7 */

/* ie8 */
.ie8 .btn:before,
.ie8 .btn:after {
    content: ' ';
    z-index: 1;    
    position: absolute;
    right: -1px;
    left: -1px;
    display: block;
    height: 3px;
    }
.ie8 .btn:before {
    top: -1px;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#80ffffff', endColorstr='#00ffffff',GradientType=0 );
    }
.ie8 .btn:after {
    bottom: -1px;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#80000000',GradientType=0 );
    }
/* /ie8 */

/* typo */
.btn {
    /* 28 / 14 = 2.57142857 */
    font: bold 14px/2 Arial, Helvetica, Tahoma, sans-serif;
    text-transform: uppercase;
    }
.btn:active {
    line-height: 2.4em;
    }

/* color */
.btn {
    background-color: #00cccc;
    color: #fff;
    border-color: #00a8a8;
    border-radius: 3px;
    cursor: pointer;
    box-shadow:
         1px  1px 4px rgba(255, 255, 255, 0.5) inset,            
        -1px -1px 4px rgba(000, 000, 000, 0.5) inset;
    }
.btn:hover {
    background-color: #00ebeb;
    }
.btn:active {
    box-shadow:
        -1px -1px 4px rgba(255, 255, 255, 0.5) inset,            
         1px  1px 4px rgba(000, 000, 000, 0.5) inset;
    }

/* green */
.btn_green {
    background-color: #009900;
    border-color: #009600;
    }
.btn_green:hover {
    background-color: #00c200;
    }

/* red */
.btn_red {
    background-color: #e00000;
    border-color: #c13d00;
    }
.btn_red:hover {
    background-color: #f00000;
    }
Run Code Online (Sandbox Code Playgroud)
<!--
paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/
-->
<!--[if lt IE 7]> 
    <div class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en">
<![endif]-->
<!--[if IE 7]>
    <div class="no-js lt-ie9 lt-ie8 ie7" lang="en">
<![endif]-->
<!--[if IE 8]>
    <div class="no-js lt-ie9 ie8" lang="en">
<![endif]-->
<!--[if gt IE 8]><!-->
    <div class="no-js no-ie" lang="en">
<!--<![endif]-->

<button class="btn btn_green btn_small ">
    Send
    <!--[if IE 7]> <span class="before"> </span><span class="after"> </span> <![endif]-->
</button>

<button class="btn">
    Buy
    <!--[if IE 7]> <span class="before"> </span><span class="after"> </span> <![endif]-->
</button>

<button class="btn btn_green">
    Activate
    <!--[if IE 7]> <span class="before"> </span><span class="after"> </span> <![endif]-->
</button>

<button class="btn btn_red">
    Delete
    <!--[if IE 7]> <span class="before"> </span><span class="after"> </span> <![endif]-->
</button>

</div>
Run Code Online (Sandbox Code Playgroud)

主要问题:为什么过滤器不能处理IE8中的伪元素?


更新:

我猜这些过滤器不适用于css生成的内容,尽管在这个MSDN页面上没有提到它.

我通过对像IE7这样的条件元素应用过滤器来解决IE8中的问题.

最终演示:(http://jsfiddle.net/matmuchrapna/8M5Tt/73/)

/**
 * Button w/o images
 */
html {
    font-size: 62.5%;
    }
body {
    font: normal 1em/1em Arial, Tahoma, Verdana, sans-serif;
    }
 
/* layout */
.btn {
    display: inline-block;
    height: 28px;
    border-width: 1px;
    border-style: solid;
    width: 170px;
    box-sizing: content-box;
    overflow: hidden;
    position: relative;
    z-index: 1;
    }
.btn {
    margin: 15px;
    }
.btn.btn_small {
    width: 130px;
    }

/* ie78 */
.lt-ie9 .btn .before,
.lt-ie9 .btn .after {
    position: absolute;
    right: -1px;
    left: -1px;
    display: block;
    height: 3px;
    }
.lt-ie9 .btn .before {
    top: -1px;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#80ffffff', endColorstr='#00ffffff',GradientType=0 );
    }
.lt-ie9 .btn .after {
    bottom: -1px;
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#00ffffff', endColorstr='#80000000',GradientType=0 );
    }
/* /ie78 */

/* typo */
.btn {
    /* 28 / 14 = 2.57142857 */
    font: bold 14px/2 Arial, Helvetica, Tahoma, sans-serif;
    text-transform: uppercase;
    }
.btn:active {
    line-height: 2.4em;
    }

/* color */
.btn {
    background-color: #00cccc;
    color: #fff;
    border-color: #00a8a8;
    border-radius: 3px;
    cursor: pointer;
    box-shadow:
         1px  1px 4px rgba(255, 255, 255, 0.5) inset,            
        -1px -1px 4px rgba(000, 000, 000, 0.5) inset;
    }
.btn:hover {
    background-color: #00ebeb;
    }
.btn:active {
    box-shadow:
        -1px -1px 4px rgba(255, 255, 255, 0.5) inset,            
         1px  1px 4px rgba(000, 000, 000, 0.5) inset;
    }

/* green */
.btn_green {
    background-color: #009900;
    border-color: #009600;
    }
.btn_green:hover {
    background-color: #00c200;
    }

/* red */
.btn_red {
    background-color: #e00000;
    border-color: #c13d00;
    }
.btn_red:hover {
    background-color: #f00000;
    }
Run Code Online (Sandbox Code Playgroud)
<!--
paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/
-->
<!--[if lt IE 7]> 
    <div class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en">
<![endif]-->
<!--[if IE 7]>
    <div class="no-js lt-ie9 lt-ie8 ie7" lang="en">
<![endif]-->
<!--[if IE 8]>
    <div class="no-js lt-ie9 ie8" lang="en">
<![endif]-->
<!--[if gt IE 8]><!-->
    <div class="no-js no-ie" lang="en">
<!--<![endif]-->

<button class="btn btn_green btn_small ">
    Send
    <!--[if lte IE 8]> <span class="before"> </span><span class="after"> </span> <![endif]-->
</button>

<button class="btn">
    Buy
    <!--[if lte IE 8]> <span class="before"> </span><span class="after"> </span> <![endif]-->
</button>

<button class="btn btn_green">
    Activate
    <!--[if lte IE 8]> <span class="before"> </span><span class="after"> </span> <![endif]-->
</button>

<button class="btn btn_red">
    Delete
    <!--[if lte IE 8]> <span class="before"> </span><span class="after"> </span> <![endif]-->
</button>

</div>
Run Code Online (Sandbox Code Playgroud)


更新2:

我解决了我的问题,但主要问题仍然没有答案:

"为什么过滤器不能处理IE8中的伪元素?"

开始赏金.

更新3: 我为ie8上的过滤器(以及-ms-filter)创建了测试用例:

在此输入图像描述

但是过滤器仍然不想处理伪元素.

更新4: 我认为Scotts的回答最接近真相.

Sco*_*ttS 41

问题是"为什么过滤器不能处理IE8中的伪元素?" 以下几乎是我能够集中讨论的最终答案.它来自此页面上的信息.

gradient滤波器是一个"程序性表面"(连同alphaimageloader).程序表面定义如下:

程序表面是在对象内容和对象背景之间显示的彩色表面.

仔细阅读.它本质上是对象内容和对象背景之间的另一个"层".你看到问题的答案了吗?什么是创建:before:after...是啊!内容.特别是作为MSDN注意到:

:: before和:: after伪元素指定文档树中元素之前和之后的内容位置.content属性与这些伪元素一起指定插入的内容.

生成的内容与其他框交互,就好像它们是在其关联元素内插入的真实元素一样.

现在,如果它是生成的内容,那么它不是包含内容的"对象",而是内容本身(其恰好具有与可能包含内容的元素对象类似的行为).

因此,不存在包含 "内容"(因为它内容)的"对象",在该"对象" 之间filter可以为由伪元素(即"假元素")生成的内容放置程序表面.gradient必须将A 应用于对象,然后将程序表面放置在它与内容之间.


Jer*_*oen 6

关于-ms-filter-a的同义词的文档filter:states:

对象必须具有要呈现的过滤器的布局.

我的第一个猜测是:before内容没有hasLayout设置为true.虽然它可能没有设置为true,但它可能也不会设置为false.首先,当我按照hasLayout文档强制获取内容时hasLayout = true(参见jsfiddle),它没有解决任何问题.

所以我说这不是真的也不是假的.相反,它可能是未定义的.我在相同的文档中注意到它描述了这个属性的来源:

object .currentStyle.hasLayout

如果我们看一下内容属性W3文档,它会说:

生成的内容不会更改文档树.特别是,它不会反馈给文档语言处理器(例如,用于重新分析).

因此,可能的结论是生成的内容不是对象,因此它没有currentStyle属性,因此也没有hasLayout设置true.这就是过滤器不能对生成的内容起作用的原因,从而回答了这个问题.


乍一看,我以为我在上述小提琴的控制台中找到了一个提示:

document.querySelectorAll('div')[0].currentStyle.hasLayout; 
// true

document.querySelectorAll('div:before')[0].currentStyle.hasLayout
// Unable to get value of the property 'currentStyle': 
// object is null or undefined
Run Code Online (Sandbox Code Playgroud)

但正如@BoltClock的评论中所提到的:querySelectorAll无法访问伪元素.


filtermsdn关于过滤器的介绍中可以找到另一个不会对伪元素起作用的提示(虽然 - 只是一个提示) - 但是强调我的:

过滤器通过filter属性应用于HTML控件

虽然我不确定"HTML控件"是什么意思,但我不希望:before伪元素生成的内容被视为"HTML控件".