Pytanie w sprawie html, internet-explorer-8, css, pseudo-element – Dlaczego gradient filtru pseudoelementu nie działa w IE8?

35

Chcę utworzyć takie przyciski:

W nowoczesnych przeglądarkach efekt jest tworzony za pomocą wstawek box-shadow i filtrów.
Dla IE8 - wybrane są pseudoelementy.
Dla IE7 - używam specjalnych tagów owiniętych w komentarze warunkowe.

Próbny: (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>

Główne pytanie: Dlaczego filtry nie działają na pseudoelementach w IE8?

Aktualizacja:

Domyślam się, że filtry nie działają na treści generowanej przez css, mimo że nie jest o tym wspomnianeStrona MSDN.

Rozwiązałem swój problem w IE8, stosując filtry do elementów warunkowych, tak jak w przypadku IE7.

Końcowe 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>

Aktualizacja 2:

Rozwiązałem swój problem, ale główne pytanie wciąż pozostaje bez odpowiedzi:

„Dlaczego filtry nie działają na pseudoelementach w IE8?”

Rozpoczął nagrodę.

Aktualizacja 3: ja stworzyłemtestcase tylko dla filtrów (a także -ms-filter) na ie8:

Ale filtry nadal nie chcą pracować na pseudoelementach.

Aktualizacja 4: MyślęScotts odpowiada jest najbliższy prawdzie.

+1 za dobry styl zadawania pytań. yunzen
@BoltClock o tym, co mówisz w publicznej bazie błędów ie8? Vladimir Starkov
O ile wiem, publiczna baza danych błędów IE8 nie jest już dostępna, więc twoje pytanie o nagrodę prawdopodobnie nie będzie odpowiadać przed „To błąd”, chyba że ktoś z zespołu IE przyjdzie i zamierza się nim dzielić. BoltClock
Podczas beta IE8 Microsoft powiedział, że będą utrzymywać publiczną bazę danych o błędach, w której każdy może zgłaszać błędy Microsoft. To było ... całkiem skuteczne, ale niektóre niejasne błędy przetrwały mimo wszystko. BoltClock

Twoja odpowiedź

5   odpowiedzi
0

Po przejrzeniu tego wykresu, potwierdzając toIE8 lubi pojedyncze dwukropki na swoich pseudoelementach, czytając toewentualnie powiązany artykuł na blogui robi dużotestowanie w jsFiddle (chociaż, niewiele w porównaniu z twoimi 73 jsFiddles), musiałbym stwierdzić, że jest to błąd w IE8.

IE9 może wykonywać gradienty na pseudoelementach (z nonsensem base64), ale IE8 jest uparcie łamany.

@ScottS - Rozumiem ich cel. Nadal uważam za dziwne, że IE8 będzie renderowaćkolory tła na treści, a jednak gradienty są całkowicie wykluczone, ponieważ zdecydowali, że nie zasługują na powierzchnię proceduralną opartą na archaicznej definicji. gmeben
IE8, który nie obsługuje składni pseudoelementów CSS3, nie ma wiele wspólnego z filtrami, które w pierwszej kolejności nie działają w pseudoelementach, poza tym cały sposób myślenia „IE to buggy” :) BoltClock
@ScottS Dobra robota. Twoja odpowiedź była dobrze wyjaśniona. Z pewnością jednak i nie po to, aby pokonać martwego konia, ale ponieważ IE8 nie uważa pseudoelementów za obiekty w swoim DOM, dodatkowo wzmacnia pogląd, że IE8 był źle zaprojektowany. gmeben
@ gmeben - tak, niewłaściwe użycie „własności” i „atrybutu” nie jest właściwe. Nie jestem pewien, czy porzucono „pseudoelement”. W rzeczywistości nie jest to prawdziwy element. Nie można w nim umieszczać html, ani nie istnieje w drzewie DOM, jeśli chodzi o sam HTML, więc nie jest on „prawdziwy” w sensie bycia znacznikiem html. Kiedy jest generowany, to naprawdę dla celów wizualnych, jak iluzja - wydaje się, że tam jest, ale tak naprawdę nie istnieje (w tym samym sensie, co elementy „prawdziwe”). ScottS
0

filter styl na to, czy rozważałeś użycieCSS3Pie?

Jest to skrypt dla IE, który dodaje obsługę standardowego CSSbox-shadow i gradienty, więc możesz pisać ten sam kod we wszystkich przeglądarkach, zamiast mieć wszystkie te style specyficzne dla IE.

@gmeben używam także tego generatoracolorzilla.com/gradient-editor/#ff0000+0,00ff15+100; Custom Vladimir Starkov
Osobiście, jeśli martwię się tylko o gradienty, wolałbym użyćUltimate CSS Gradient Generator (obsługuje IE6-9) i nie zajmuje się dodatkowymi plikami .js i .htc CSS3Pie. gmeben
nie działa w przypadku wstawiania box-shadow, a także nie działa bez javascript Vladimir Starkov
41

„Dlaczego filtry nie działają na pseudoelementach w IE8?” Poniższe informacje są tak bliskie ostatecznej odpowiedzi, jak tylko potrafię. Pochodzi z informacji na tematta strona.

Thegradient filtr jest „powierzchnią proceduralną” (wraz zalphaimageloader). Powierzchnia proceduralna jest zdefiniowana w ten sposób:

Powierzchnie proceduralne są kolorowymi powierzchniami, które wyświetlają się między zawartością obiektu a tłem obiektu.

Przeczytaj to uważnie. Jest to zasadniczo inna „warstwa”, którą można powiedzieć między treścią obiektu a tłem tego obiektu. Czy widzisz odpowiedź na pytanie? Co jest tworzone przez:before i:after... Tak!Zawartość. W szczególności jakNotatki MSDN:

Pseudoelementy :: before i :: after określają położenie treści przed i po elemencie w drzewie dokumentu. Atrybut content w połączeniu z tymi pseudoelementami określa, co jest wstawiane.

Wygenerowana treść wchodzi w interakcję z innymi polami, tak jakby były one rzeczywistymi elementami wstawionymi bezpośrednio do powiązanego elementu.

Teraz, jeśli takzawartość to jest generowane, to jestnie „obiekt” zawierający treść, alesama treść (co zdarza się, że ma pewne zachowanie podobne do obiektu elementu, który może zawierać treść).

Tak więc nie ma „obiektu”zawierający „treść” (ponieważ tojest treść) między którymifilter może umieścić powierzchnię proceduralną dla treści generowanej przez pseudoelement (tj. „fałszywy element”). ZAgradient należy zastosować doobiekt, a następnie powierzchnia proceduralna jest umieszczana między nim a treścią.

@ matmuchrapna - Cóż, prawdopodobnie nie ma sposobu, aby udowodnić, czy nie, moje wyjaśnienie jest naprawdę powodem, ale gdy przeczytałem informacje, z pewnością wydawało mi się to najbardziej logicznym wnioskiem. Cieszę się, że zgadzasz się i spełniłeś swoje poszukiwanie odpowiedzi. ScottS
Zauważyłem, że MSDN używają zamiennie słów „właściwość” i „atrybut”content. W porządku. gmeben
Myślę, że masz rację. Vladimir Starkov
6

-ms-filter -synonim dlafilter- stwierdza:

Obiekt musi mieć układ renderowania filtru.

Domyślam się, że:before zawartość nie mahasLayout ustaw na true. I chociaż prawdopodobnie nie jest ustawiony na true, to prawdopodobnie jestnie ustawiono również na false. Na początek, kiedy poszedłem zadocLayout docs aby wymusić na treścihasLayout = true (widziećjsfiddle) nic nie rozwiązało.

Powiedziałbym więc, że nie jest to prawda ani fałsz. Zamiast tego to prawdopodobnieniezdefiniowany. W tym samym dokumencie zauważyłem źródło tej właściwości:

obiekt.currentStyle.hasLayout

Jeśli spojrzymy naDokumentacja W3 dotycząca właściwości content to mówi:

Wygenerowana treść nie zmienia drzewa dokumentu. W szczególności nie jest on przesyłany z powrotem do procesora języka dokumentu (np. W celu reparacji).

Więc,możliwy wniosek byłoby, że wygenerowana treść nie jestobiekt, jako taki nie macurrentStyle własność, a więc także nie mahasLayout Ustawićtrue. To byłby powód, dla którego filtry nie działają na wygenerowanej treści, a zatem odpowiadają na pytanie.

Na pierwszy rzut oka pomyślałem, że znalazłem podpowiedź w konsoli powyższego skrzypce:

<code>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
</code>

Ale jak wspomniano w komentarzach @BoltClock:querySelectorAll nie może uzyskać dostępu do pseudoelementów.

Kolejna podpowiedź (chociaż - nic więcej niż podpowiedź), żefilter nie będzie działać na pseudoelementach można znaleźć wto wprowadzenie msdn na filtrach, stwierdzając (podkreślenie moje):

Filtry są stosowane doFormanty HTML przez właściwość filtra

Chociaż nie jestem pewien, co należy rozumieć przez „formanty HTML”, nie oczekiwałbym zawartości generowanej przez:before pseudoelement uważany za „kontrolę HTML”.

@BoltClock Ahh tak, oczywiście, thx! Wtedy prawdopodobnie nie ma „czystego” sposobu na sprawdzenie, czy istnieje wewnętrznyhasLayout własność wygenerowanej treści. Wyedytuję pytanie i umieścisz tam wspomniany link. Jeroen
Czy uda się uruchomićhasLayout poprzez zastosowaniezoom:1 dla pseudoelementów? To ciekawe odkrycie, ale nie mam dostępu do skrzynki IE z mojego komputera domowego, aby ją przetestować. o.v.
@ o.v. AFAIK nie ma niezawodnego sposobu, aby dowiedzieć się, cohasLayout właściwość dla pseudoelementów, w mojej odpowiedzi spekuluję, że może nawet nie mieć tej własności. Tak czy inaczej, jeśli otworzyszta zaktualizowana wersja jsfiddle zzoom:1 filter nadal nie działa w IE8. Jeroen
@Jeroen Twoja odpowiedź jest niesamowita. Może masz rację. Tak poza tym,wyszukiwanie formantów HTML w msdn nie przyniosło więcej powiązanych materiałówkontrolki HTMLdlatego nie mogę mówić o wyjątku poza opisemHtml controls. Dlatego wolę ufać w tym punkciestrona, opisując elementy, które nie mogą mieć filtrów:embed, applet, select, option, tr, tHead, tBody itFoot. Vladimir Starkov
0

ale opublikuję to jako osobną odpowiedź.

Prawdopodobny powód, dla którego IE8 nie działafilter gdzie IE7 działa, ponieważ IE8 zmienił składnię dlafilter.

filter to specyficzny dla IE styl zastrzeżony. Kiedy Microsoft wydał IE8, poczynił duży wysiłek, aby być „zgodnymi ze standardami”. „Zgodny ze standardami” sposób obsługi niestandardowego stylu polega na nadaniu mu prefiksu dostawcy, i to właśnie zrobił Microsoft.

Dlatego w IE8 musisz wykonać następujące czynności:

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

IE7 nie obsługuje tej składni, więc potrzebujesz ich obu.

IE8 faktycznie działa ze starą składniąw niektórych przypadkach. Przypadki, w których nie działa, zwykle są tymi, w których używaszprogid: składnia. Powodem tego jest dwukropek poprogid powoduje, że jest to niepoprawna składnia CSS, dlatego MS dodawał cytaty wokół całego cienkiego dla IE8-ms-filter wersja.

Krótka odpowiedź brzmi: użyj obu wersji w arkuszach stylów, a wszystko będzie dobrze.

Zgadzam się z @matmuchrapna, żefilter składnia nie jest problemem. Wierzę, że opiera się na naturze pseudoelementu igradient filtruj, jak opisałem w mojej odpowiedzi. ScottS
Słusznie. zdecydowanie są czasy, kiedy IE8 preferuje-ms-filter syntqx, ale jeśli jest w porządku, to również dobrze. Pozostawię odpowiedź na miejscu, ale na przyszłość. Spudley
zrobiłem update3 do postu, który dowodzi, że filtry działają w obu składniach Vladimir Starkov
> "Prawdopodobnym powodem, dla którego IE8 nie działa z filtrem, w którym działa IE7, jest to, że IE8 zmienił składnię filtru." nie, ponieważ na tympróbny selektor.ie8 .btn:before użyj poprawnej składni dla ie8 i nie zastosuj filtra Vladimir Starkov

Powiązane pytania