Ustaw krycie obrazu tła bez wpływu na elementy potomne

214

Czy można ustawić krycie obrazu tła bez wpływu na krycie elementów potomnych?

Przykład

Wszystkie linki w stopce wymagają niestandardowego punktora (obrazu tła), a krycie niestandardowego punktu powinno wynosić 50%.

HTML

<div id="footer">
    <ul>
        <li><a href="#">Link 1</a></li>
        <li><a href="#">Link 2</a></li>
        <li><a href="#">Link 3</a></li>
        <li><a href="#">Link 4</a></li>
        <li><a href="#">Link 5</a></li>
    </ul>
</div>  

CSS

#footer ul li {
    background: url(/images/arrow.png) no-repeat 0 50%;
}  

Co próbowałem

Próbowałem ustawić krycie elementów listy na 50%, ale potem krycie tekstu linku również wynosi 50% - i wydaje się, że nie ma sposobu na zresetowanie krycia elementów potomnych:

#footer ul li {
    background: url(/images/arrow.png) no-repeat 0 50%;
    /* will also set the opacity of the link text */        
    opacity: 0.5;
}

Próbowałem także użyć rgba, ale nie ma to żadnego wpływu na obraz tła:

#footer ul li {
    /* rgba doesn't apply to the background image */
    background: rgba(255, 255, 255, 0.5) url(/images/arrow.png) no-repeat 0 50%;
}
jmohr
źródło

Odpowiedzi:

119

Możesz używać CSS linear-gradient()z rgba().

div {
  width: 300px;
  height: 200px;
  background: linear-gradient(rgba(255,255,255,.5), rgba(255,255,255,.5)), url("https://i.imgur.com/xnh5x47.jpg");
}
span {
  background: black;
  color: white;
}
<div><span>Hello world.</span></div>

Naklejki
źródło
To najlepsze rozwiązanie!
Dzenis H.
93

Przenieś obraz do edytora obrazów, zmniejsz krycie, zapisz go jako plik .png i użyj go zamiast tego.

2ToneKenobi
źródło
8
Hmm ... właśnie przegłosowałem, ale spójrz na tę zaakceptowaną odpowiedź: stackoverflow.com/a/6502295/131809 przegłosowałem 10 razy i prawie identycznie.
Alex
9
To dobra opcja, nie mam pojęcia, dlaczego tak wiele głosów negatywnych. Gdybym mógł to dwukrotnie głosować, zrobiłbym to. Element potomny częściowo nieprzezroczystego elementu macierzystego będzie częściowo nieprzezroczysty i powinien nim być. Wszystkie „obejścia” to błędy, które ostatecznie powinny zostać naprawione.
RobW
6
@mystrdat Już pobierasz obraz, nie jest to dodatkowa prośba.
Brad
2
@mystrdat Ale on już pobiera obraz strzałki. Nie dostarczyłeś rozwiązania innego niż obraz, więc o to mi chodziło. Już pobiera obraz strzałki, może równie dobrze przyjść w razie potrzeby, co nie byłoby dodatkową prośbą. Nie rozumiem, skąd pochodzisz.
Brad
1
@brad Przepraszam, okazuje się, że źle przeczytałem pytanie, gdy sprawdziłem ponownie.
mystrdat
42

Będzie to działać z każdą przeglądarką

div {
 -khtml-opacity:.50; 
 -moz-opacity:.50; 
 -ms-filter:"alpha(opacity=50)";
  filter:alpha(opacity=50);
  filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);
  opacity:.50; 
}

Jeśli nie chcesz, aby przezroczystość wpływała na cały kontener i jego dzieci, sprawdź to obejście. Musisz mieć dziecko o absolutnej pozycji z rodzicem o względnej pozycji.

Sprawdź wersję demo na http://www.impressivewebs.com/css-opacity-that-doesnt-affect-child-elements/

Hussein
źródło
Myślę, że musisz zmienić „cudzysłowy w powyższym kodzie na„, aby działał po wklejeniu go w prosty sposób.
nsantorello
6
czy ta odpowiedź jest nadal najlepszym rozwiązaniem problemu: „jak sprawić, aby element potomny nie dziedziczył wartości nieprzezroczystości CSS elementu macierzystego”? Potrzebuję dziecka, aby naprawdę było dzieckiem ... i w obiegu dokumentów ... a także nie chcę w tym celu włączać javascript / flash; wolę czysty CSS.
govinda
Mam 50% nieprzezroczystych elementów macierzystych <li> zawierających obrazy podrzędne, które chcę w 100% nieprzezroczyste. Ustawienie <li> na position:relative;i img na position:absolute;NIE pozwala mi przesłonić odziedziczonego krycia na img, i nie mogę użyć bezwzględnego pozycjonowania dla samych <li> (to bałagan ;-). W Javascript próbowałem imgs[i].style.opacity = '1';, ale to również nie działa, aby zastąpić odziedziczone nieprzezroczystość. Jeśli dobrze rozumiem, nie mogę również używać rgba, ponieważ muszę wpływać na same zdjęcia, a nie tylko na kolor tła. Czy ktoś ma dla mnie zalecenie?
govinda
26
Cała ta odpowiedź nie ma sensu. Podany kod, poza tym, że jest dokładnie tym, czego pytający nie chce robić, ponieważ nie działa , nie pasuje do opisu ani linku. Bardzo trudno mi zrozumieć, dlaczego tak wielu ludzi to oceniło.
BoltClock
Gdyby pytanie brzmiało „Jak ustawić 50% przezroczystości elementu”, byłaby to dobra odpowiedź.
lharby
29

Jeśli używasz obrazu jako punktora, możesz rozważyć pseudoelement: before.

#footer ul li {
}

#footer ul li:before {
    content: url(/images/arrow.png);
    filter:alpha(opacity=50);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);
    opacity:.50;
}
Pan Griever
źródło
3
Filtr to tylko rozwiązanie IE
Hussein
1
Myślę, że to prawdopodobnie najlepsze rozwiązanie. Jest to czyste rozwiązanie CSS. Możliwe jest również zhakowanie obsługi IE7 przy użyciu *zoom: expression( … );(patrz : po i: przed hakowaniem pseudoelementów css dla IE 7 ), ale IE7 w końcu staje się pasywny.
Thirdender
9
#footer ul li {
  position: relative;
  opacity: 0.99;
}

#footer ul li::before {
  content: "";
  position: absolute;
  width: 100%;
  height: 100%;
  z-index: -1;
  background: url(/images/arrow.png) no-repeat 0 50%;
  opacity: 0.5;
}

Hack z kryciem 0,99 (mniej niż 1) tworzy kontekst indeksu Z, więc nie możesz się martwić o globalne wartości indeksu Z. (Spróbuj go usunąć i zobacz, co się stanie w następnej wersji demonstracyjnej, w której opakowanie nadrzędne ma dodatni indeks Z).
Jeśli twój element ma już indeks Z, to nie potrzebujesz tego hacka.

Demo tej techniki .

użytkownik
źródło
Czy wiesz, dlaczego musimy ustawić wartość krycia mniejszą niż 1? Czy to rozwiązanie dla różnych przeglądarek?
zVictor
1
@zVictor tak, jest to standardowe zachowanie w3c. Zobacz Zrozumienie indeksu Z CSS: kontekst stosowy .
użytkownik
4

Niestety w chwili pisania tej odpowiedzi nie ma bezpośredniego sposobu, aby to zrobić. Musisz:

  1. użyj półprzezroczystego obrazu jako tła (znacznie łatwiej).
  2. dodaj dodatkowy element (np. div) obok dzieci, które mają być nieprzezroczyste, dodaj tło i po uczynieniu go półprzezroczystym, umieść go za wspomnianymi dziećmi.
Reyraa
źródło
4

Inną opcją jest podejście CSS Tricks polegające na wstawieniu pseudoelementu dokładnego rozmiaru oryginalnego elementu tuż za nim, aby uzyskać fałszywy efekt nieprzezroczystego tła, którego szukamy. Czasami trzeba ustawić wysokość pseudoelementu.

div {
  width: 200px;
  height: 200px;
  display: block;
  position: relative;
}

div::after {
  content: "";
  background: url(image.jpg);
  opacity: 0.5;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  position: absolute;
  z-index: -1;   
}
kaleazy
źródło
3

Właściwość „filter” wymaga liczby całkowitej dla procentowego krycia zamiast podwójnego, aby działała w IE7 / 8.

filter: progid:DXImageTransform.Microsoft.Alpha(opacity=50);

PS: Publikuję to jako odpowiedź, ponieważ SO potrzebuje co najmniej 6 zmienionych znaków do edycji.

lyubeto
źródło
2

Aby naprawdę dostroić rzeczy, zalecam umieszczenie odpowiednich opcji w opakowaniach kierowanych na przeglądarkę. To była jedyna rzecz, która działała dla mnie, gdy nie mogłem zmusić IE7 i IE8 do „ładnej zabawy z innymi” (ponieważ obecnie pracuję dla firmy programistycznej, która nadal je wspiera).

/* color or background image for all browsers, of course */            
#myBackground {
    background-color:#666; 
}
/* target chrome & safari without disrupting IE7-8 */
@media screen and (-webkit-min-device-pixel-ratio:0) {
    #myBackground {
        -khtml-opacity:.50; 
        opacity:.50;
    }
}
/* target firefox without disrupting IE */
@-moz-document url-prefix() {
    #myBackground {
        -moz-opacity:.50;
        opacity:0.5;
    }
}
/* and IE last so it doesn't blow up */
#myBackground {
    opacity:.50;
    filter:alpha(opacity=50);
    filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.5);
}

Mogę mieć zwolnienia w powyższym kodzie - jeśli ktoś chce go dalej posprzątać, nie krępuj się!

kod-sushi
źródło
3
Nie jest konieczne kierowanie na każdą przeglądarkę osobno, wystarczy użyć prefiksów przeglądarki w jednym bloku selektora. W przypadku prefiksów przeglądarki przeglądarka będzie używać tylko odpowiedniej właściwości CSS. W miarę upływu czasu, a składnia tej właściwości staje się znormalizowana, producenci przeglądarek porzucają obsługę prefiksów i używają właściwości CSS bez żadnego prefiksu (na przykład Firefox zrezygnował z obsługi prefiksu -moz-border-radiusw Firefox 13 i po prostu szuka border-radiusteraz standardowej właściwości). IE7 i IE8 to inna historia, ale to tylko IE :-p
Thirdender
Chciałbym wiedzieć, kto głosował za tym i dlaczego, proszę. Głosowanie jest bezużyteczne bez informacji zwrotnej. Chciałbym móc poprawić swoje odpowiedzi. Jeśli tylko dlatego, że informacje były nieaktualne, sprawdź datę. :) Dzięki.
code-sushi
@ code-sushi: Jeśli głosowanie przychodziło mniej więcej w tym samym czasie, co twój komentarz, należy wziąć pod uwagę, że mogło to być dzieło innej osoby, która zgodziła się z komentarzem osoby trzeciej (zwróć uwagę na opinie na temat samego komentarza). Nie głosowałem na twoją odpowiedź, ale muszę się zgodzić - chciałbym dodać, że 1) KHTML nigdy nie zobaczy, -khtml-opacityponieważ nie rozumie zapytania medialnego, co czyni go bezużytecznym 2) IE jest bardziej stabilny niż myślisz; nie zostanie „wysadzony” tylko dlatego, że dodajesz przedrostki inne niż IE do reguły odnoszącej się do IE. Problem, z którym się zmierzyłeś, musiał pochodzić z innych źródeł.
BoltClock
Moja pierwotna odpowiedź brzmiała prawie dwa lata temu, a głosowanie w dół miało miejsce niedawno, podobnie jak w tym roku. Byłem tylko ciekawy. Jeśli chodzi o komentarze IE, dotyczyły one 7, kiedy to wciąż wymagało wsparcia; Jestem prawie pewien, że teraz w większości przypadków można teraz ignorować IE 7. Dziękuję za twój komentarz.
code-sushi
1

Jeśli musisz ustawić krycie tylko na punktor, dlaczego nie ustawisz kanału alfa bezpośrednio na obrazie? Nawiasem mówiąc, nie sądzę, że istnieje sposób, aby ustawić krycie obrazu tła za pomocą css bez zmiany krycia całego elementu (i jego dzieci również).

Minkiele
źródło
1

Aby dodać do powyższego ... możesz użyć kanału alfa z nowymi atrybutami kolorów, np. rgba (0,0,0,0) ok, więc jest czarny, ale z zerowym kryciem, więc jako rodzic nie wpłynie na dziecko. Działa to tylko w Chrome, FF, Safari i .... ja cienki O.

przekonwertować kolory heksadecymalne na RGBA

przodem do góry
źródło
4
To nie będzie działać background-imagezgodnie z żądaniem PO.
Torsten Walter
1

Znalazłem całkiem niezły i prosty samouczek na temat tego problemu. Myślę, że działa świetnie (i chociaż obsługuje IE, po prostu mówię moim klientom, aby używali innych przeglądarek):

Przezroczystość tła CSS bez wpływu na elementy potomne, poprzez RGBa i filtry

Stamtąd możesz dodać obsługę gradientów itp.

Francisco
źródło
Cóż, to nie zadziała bezpośrednio. Na przykład musisz wstawić div jako element jawny z kolorem tła: (255,255,255,0,5)
Francisco
0
#footer ul li
     {
       position:relative;
       list-style:none;
     }
    #footer ul li:before
     {
       background-image: url(imagesFolder/bg_demo.png);
       background-repeat:no-repeat;
       content: "";
       top: 5px;
       left: -10px;
       bottom: 0;
       right: 0;
       position: absolute;
       z-index: -1;
       opacity: 0.5;
    }

Możesz wypróbować ten kod. Myślę, że to zadziała. Możesz odwiedzić wersję demonstracyjną

Jakir Hossain
źródło