web-dev-qa-db-ja.com

IE8で疑似要素のフィルターグラデーションが機能しないのはなぜですか?

次のようなボタンを作成したいと思います。
pseudo 3d button

最新のブラウザでは、効果はインセットボックスシャドウとフィルターを使用して作成されます。
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;
    }
<!--
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>

主な質問:IE8の疑似要素でフィルターが機能しないのはなぜですか?


更新:

この MSDNページ で言及されていないにもかかわらず、フィルターはcssで生成されたコンテンツでは機能しないと思います。

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;
    }
<!--
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>

更新2:

私は自分の問題を解決しましたが、主な質問はまだ答えられていません:

「IE8の疑似要素でフィルターが機能しないのはなぜですか?」

賞金を開始しました。

更新3:IE8のフィルター(および-ms-filter)に対してのみ テストケース を作成しました:

enter image description here

しかし、フィルターはまだ疑似要素で機能することを望んでいません。

更新4:私は スコッツの答え が真実に最も近いと思います。

35

-ms-filter -a filter-の同義語に関するドキュメントは次のように述べています。

フィルタをレンダリングするには、オブジェクトにレイアウトが必要です。

私の最初の推測では、:beforeコンテンツのhasLayoutがtrueに設定されていません。そして、おそらくtrueに設定されていませんが、おそらくfalseにも設定されていません。手始めに、 hasLayout docs に従ってコンテンツにhasLayout = trueを強制的に取得させたところ( jsfiddle を参照)、何も解決されませんでした。

だから私はそれが真実でも偽でもないと言うでしょう。代わりに、おそらくundefinedです。私は同じドキュメントで、このプロパティのソースについて述べていることに気づきました:

object。currentStyle.hasLayout

contentプロパティに関するW3ドキュメント を見ると、次のようになっています。

生成されたコンテンツはドキュメントツリーを変更しません。特に、それはドキュメント言語プロセッサにフィードバックされません(例えば、再解析のために)。

したがって、考えられる結論は、生成されたコンテンツがオブジェクトではないということです。 currentStyleプロパティがないため、hasLayouttrueに設定されていません。これが、生成されたコンテンツに対してフィルターが機能しない理由であり、したがって質問に答えます。


一見したところ、上記のフィドルのコンソールでヒントを見つけたと思いました。

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

しかし、@ BoltClockによるコメントで述べられているように: querySelectorAllは疑似要素にアクセスできません


filterが疑似要素で機能しないという別のヒント(ただし、これもヒントにすぎません)は、 このmsdnのフィルターの紹介 にあり、(私の強調)と述べています。 :

フィルタは、フィルタプロパティを介してHTMLコントロールに適用されます

「HTMLコントロール」の意味はわかりませんが、:before疑似要素によって生成されたコンテンツが「HTMLコントロール」と見なされるとは思いません。

6
Jeroen

これにIEのfilterスタイルを使用するのではなく、 CSS3Pie を使用することを検討しましたか?

これはIEのスクリプトであり、標準のCSS box-shadowとグラデーションのサポートが追加されているため、IE固有のスタイルをすべて使用しなくても、すべてのブラウザーで同じコードを記述できます。 。

0
Spudley

私はすでに私の好みの解決策(CSS3Pieを使用)を提供しましたが、これを別の回答として投稿します。

IE8がfilterで機能しない理由として考えられるのは、IE8がfilterの構文を変更したためです。

filterは、IE固有の独自のスタイルです。 MicrosoftがIE8をリリースしたとき、彼らは「標準に準拠」しようとすることを大いに強調しました。非標準スタイルをサポートする「標準準拠」の方法は、ベンダープレフィックスを付けることであり、これはMicrosoftが行ったことです。

したがって、IE8では、次のことを行う必要があります。

-ms-filter: "progid:DXImageTransform.Microsoft.gradient( startColorstr='#80ffffff', endColorstr='#00ffffff',GradientType=0 )";

IE7はこの構文をサポートしていないため、両方が必要です。

IE8は、実際には古い構文で動作します場合によっては。動作しない場合は、progid:構文を使用する場合が多いです。この理由は、progidの後のコロンが原因で、無効なCSS構文になるためです。そのため、MSはIE8 -ms-filterバージョンのシン全体に引用符を追加しました。

つまり、簡単に言えば、スタイルシートで両方のバージョンを使用すれば、問題はありません。

0
Spudley

うわー、これは難しいものです。

このグラフを確認した後 、確認 IE8は疑似要素の単一のコロンのみが好き 、これを読む おそらく関連するブログ記事 、そしてたくさんのことをするof jsFiddleでのテスト (ただし、73 ?? jsFiddlesと比較すると少しですが)、これはIE8のバグであると結論付ける必要があります。

IE9は疑似要素(base64ナンセンス)でグラデーションを実行できますが、IE8は頑固に壊れています。

0
gmeben