Вопрос по html, css – Почему градиент фильтра для псевдоэлемента не работает в IE8?

35

Я хочу создать такие кнопки:
pseudo 3d button

В современных браузерах эффект создается с использованием вставки box-shadow и фильтров.
Для IE8 - выбраны псевдоэлементы.
Для IE7 - я использую специальные теги, обернутые в условные комментарии.

Demo: (http://jsfiddle.net/8M5Tt/68/)

<code>/**
 * 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;
    }</code>
<code><!--
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></code>

Main Question: Почему фильтры не работают с псевдоэлементами в IE8?

Update:

Я предполагаю, что фильтры не работают с контентом, сгенерированным css, несмотря на то, что он не упоминается в этомСтраница MSDN.

Я решил свою проблему в IE8, применив фильтры к условным элементам, как в IE7.

Final demo: (http://jsfiddle.net/matmuchrapna/8M5Tt/73/)

<code>/**
 * 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;
    }</code>
<code><!--
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></code>

Update 2:

Я решил свою проблему, но главный вопрос до сих пор остается без ответа:

“Why don't filters work on pseudo elements in IE8?”

Начали щедрость.

Update 3: я создалпрецедент только для фильтров (а также -ms-filter) на ie8:

enter image description here

Но фильтры по-прежнему не хотят работать с псевдоэлементами.

Update 4: Я думаюСкоттс ответ ближе всего к истине.

Стоит ли идти ко всем этим неприятностям? IE фильтры довольно глючные, как и псевдоэлементы. Я бы либо использовал изображение, либо просто позволил бы IE делать свое дело. Пользователи даже не заметят. elclanrs
Я единственный, кто постоянно видит исчезающие серые точки на пересечениях изображения каждый раз? BalusC
Насколько я знаю, общедоступная база данных об ошибках IE8 больше недоступна, поэтому ваш вопрос о вознаграждении, вероятно, не будет отвечать за "Это ошибка". если кто-то из команды IE не придет и не собирается делиться. BoltClock♦
+1 за ваш хороший стиль допроса. yunzen
В ходе бета-тестирования IE8 Microsoft заявила, что будет поддерживать общедоступную базу данных ошибок, где любой может отправлять сообщения об ошибках на рассмотрение Microsoft. Это было ... довольно эффективно, но некоторые непонятные ошибки все равно пробились. BoltClock♦

Ваш Ответ

5   ответов
6

-ms-filter -синоним дляfilter- состояния:

An object must have layout for the filter to render.

Мое первое предположение было то, что:before содержание не имеетhasLayout установить в true. И хотя это, вероятно, не установлено в true, это, вероятно,not set to false either, Для начала, когда я последовал заhasLayout docs заставить контент получитьhasLayout = true (увидетьjsfiddle) это ничего не решало.

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

object.currentStyle.hasLayout

Если мы посмотрим наW3 документация по содержанию собственности это говорит:

Generated content does not alter the document tree. In particular, it is not fed back to the document language processor (e.g., for reparsing).

Так,a possible conclusion было бы, что сгенерированный контент не являетсяobjectкак таковой он не имеет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

Но, как упоминалось в комментариях @BoltClock:querySelectorAll не может получить доступ к псевдоэлементам.

Еще один намек (правда, опять же - не более, чем намек), чтоfilter не будет работать над псевдоэлементами, можно найти вэто введение MSDN на фильтрах, констатирую (выделение мое):

Filters are applied to HTML controls through the filter property

Хотя я не уверен, что подразумевается под «HTML-элементами управления», я не ожидал, что контент, сгенерированный:before псевдоэлемент, который следует рассматривать как «HTML Control».

Немного оquerySelectorAll() это красная сельдь, какit can never access pseudo-elements, Естественно, поскольку псевдоэлементы не являются частью DOM.
Сможет ли кто-нибудь вызватьhasLayout применяяzoom:1 для псевдоэлементов? Это любопытная находка, но у меня нет доступа к блоку IE с моей домашней машины, чтобы проверить его.
@ O.v. AFAIK, нет надежного способа выяснить, чтоhasLayout свойство для псевдоэлементов, в моем ответе я предполагаю, что это может даже не иметь собственность. В любом случае, если вы откроетеthis updated version of the jsfiddle сzoom:1 filter все еще не работает в IE8.
@BoltClock Ах да, конечно, спасибо! Тогда, вероятно, нет "чистой" информации. способ выяснить, есть ли внутреннийhasLayout свойство сгенерированного контента. Я отредактирую вопрос и поставлю там ссылку, о которой вы упомянули.
Хотя я не согласен с тем, что какие-либо другие ваши пункты имеют какое-либо отношение к этому, я думаю, что вы были на полпути к ответу, когда заявили: «Итак, возможный вывод состоит в том, что сгенерированный контент не являетсяobject. & Quot; Я считаю, что это половина вопроса, основанного на ответе, который я только что опубликовал
0

После просмотра этого графика, подтверждая, чтоIE8 любит только одиночные двоеточия на своих псевдоэлементахчитая этовозможно связанная статья блогаи делает многотестирование в jsFiddle (хотя это немного по сравнению с вашими 73 jsFiddles), я должен был бы заключить, что это ошибка в IE8.

IE9 может делать градиенты на псевдо-элементах (с base64 нонсенсом), но IE8 упорно не нарушена.

@BoltClock Хороший улов на редактировании элемента / селектора. Я просто хотел указать на все необходимые части при работе с псевдоэлементами в IE8. Теоретически, когда рассматриваются все эти части, фильтры должны работать. Тот факт, что они этого не делают, заставляет меня поверить, что это ошибка (не обязательно, потому что у меня склад ума ах!).
IE8, не поддерживающий синтаксис псевдоэлемента CSS3, не имеет большого отношения к фильтрам, которые в первую очередь не работают в псевдоэлементах, за исключением того, что весь IE "глючит". склад ума :)
@ gmeben - Ты упустил смысл. Это не просто IE, который считает их "декоративными" в этом вся их цель. Они чисто дляpresentational использовать, поэтому они являются частью CSS, а не HTML. Первоначальное намерение было просто сделатьtypographical change, Позже, с добавлением:before & Амп;:after, это должно было позволитьgenerated textual content также для презентации. Веб-дизайнер с тех пор извлек выгоду из "бланка" Содержание сделать много аккуратных эффектов.
@ gmeben - да, неправильное использование свойства & apos; и «атрибут»; не является правильным. Я не уверен, что оставляю «псевдоэлемент». называется для. На самом деле это не настоящий элемент. Вы не можете поместить html в него, и при этом он не существует в дереве DOM, поскольку речь идет о самом html, поэтому он не является "реальным" в смысле быть тегом HTML. Когда оно генерируется, оно действительно для визуальных целей, как иллюзия - кажется, что оно есть, но на самом деле его нет (в том же смысле, что и «реальные» элементы).
@ gmeben - Так как & quot; псевдоэлемент & quot; означает «ложный элемент» (буквально), и так как он предназначен только дляcontent вставка (технически было бы логичным противоречием для простого контента, чтобы содержать сам контент; как яблокоcontaining яблоко, а неbeing один), и, поскольку IE определяет свои процедурные поверхности как идущиеbetween контент и его объект (они имеют право определять процедурную поверхность так, как они хотят; это не является частью спецификации HTML / CSS), я не уверен, что смогу выставить обвинение в «плохо спроектированном»; в IE8 для этой конкретной проблемы (теперь другие проблемы ...).
41

почему фильтры не работают с псевдоэлементами в IE8. Следующее является настолько близким к окончательному ответу, насколько я могу собрать. Это исходит из информации оэта страница.

gradient фильтр представляет собой «процедурную поверхность»; (вместе сalphaimageloader). Процедурная поверхность определяется так:

Procedural surfaces are colored surfaces that display between the content of an object and the object's background.

Прочитайте это внимательно. По сути, это еще один «слой» Вы могли бы сказать, что между содержимым объекта и фоном этого объекта. Вы видите ответ на вопрос? Что создано:before а также:after... Да!Content, Конкретно какMSDN заметки:

The ::before and ::after pseudo-elements specify the location of content before and after an element in the document tree. The content attribute, in conjunction with these pseudo-elements, specifies what is inserted.

The generated content interacts with other boxes as if they were real elements inserted just inside their associated element.

Теперь, если этоcontent что генерируется, то этоnot «объект» содержание, ноcontent itself (который имеет некоторое поведение, похожее на объект элемента, который может содержать содержимое).

Таким образом, нет «объекта»containing & Quot; содержание & Quot; (с тех порis содержание), между которымиfilter может размещать процедурную поверхность для контента, сгенерированного псевдоэлементом (то есть «ложным элементом»).gradient должны быть применены кobject, а затем процедурная поверхность помещается между ним и содержимым.

Я заметил, что MSDN взаимозаменяемо использует слова «свойство»; и «атрибут»; описатьcontent, Хорошо.
@ matmuchrapna - Ну, вероятно, нет никакого способа доказать или нет, что мое объяснение действительно является причиной, но когда я читал информацию, она мне показалась самым логичным выводом. Я рад, что вы согласились и удовлетворили ваши поиски ответа.
Я думаю ты прав. Vladimir Starkov
0

filter стиль для этого, вы рассматривали возможность использованияCSS3Pie?

Это скрипт для IE, который добавляет поддержку стандартного CSSbox-shadow и градиенты, так что вы можете написать один и тот же код во всех браузерах, а не иметь все эти специфичные для IE стили.

он не работает на вставке box-shadow, а также не работает без JavaScript Vladimir Starkov
@gmeben я также использую этот генераторcolorzilla.com/gradient-editor/#ff0000+0,00ff15+100;Custom Vladimir Starkov
Лично, если меня интересуют только градиенты, я бы лучше использовалthe Ultimate CSS Gradient Generator (поддерживает IE6-9) и не работает с дополнительными файлами .js и .htc CSS3Pie.
0

но я опубликую это как отдельный ответ.

Вероятная причина, по которой IE8 не работает сfilter где IE7 работает, потому что IE8 изменил синтаксис дляfilter.

filter является специфическим для IE фирменным стилем. Когда Microsoft выпустила IE8, они предприняли большую попытку «соответствовать стандартам». «Соответствие стандартам» способ поддержки нестандартного стиля заключается в присвоении ему префикса поставщика, и именно это и сделала Microsoft.

Поэтому в IE8 вам необходимо сделать следующее:

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

IE7 не поддерживает этот синтаксис, поэтому вам нужны оба.

IE8 на самом деле работает со старым синтаксисомin some cases, Случаи, когда это не работает, как правило, те, где вы используетеprogid: синтаксис. Причина этого заключается в том, что толстая кишка послеprogid вызывает недействительный синтаксис CSS, поэтому MS добавила кавычки вокруг всего тонкого для IE8-ms-filter версия.

Итак, короткий ответ: используйте обе версии в своих таблицах стилей, и у вас все будет хорошо.

я сделал update3 к посту, который доказывает, что фильтры работают в обоих синтаксисах Vladimir Starkov
& gt; & quot; Вероятная причина, по которой IE8 не работает с фильтром, в котором работает IE7, заключается в том, что IE8 изменил синтаксис фильтра. & quot; нет, потому что на этомdemo селектор.ie8 .btn:before используйте правильный синтаксис для ie8, и фильтр не применяется Vladimir Starkov
справедливо. определенно бывают моменты, когда IE8 предпочитает-ms-filter syntqx, но если для вас здесь все в порядке, то это тоже хорошо. Я оставлю ответ на месте для дальнейшего использования.
Я согласен с @matmuchrapna, чтоfilter синтаксис не проблема. Я считаю, что это основано на природе псевдоэлемента иgradient Фильтр, как я изложил в своем ответе.

Похожие вопросы