Przejście obrazu tła CSS3

122

Próbuję uzyskać efekt „zanikania, zanikania”, używając przejścia CSS. Ale nie mogę zmusić tego do pracy z obrazem tła ...

CSS:

.title a {
    display: block;
    width: 340px;
    height: 338px;
    color: black;
    background: transparent;
    /* TRANSITION */
    -webkit-transition: background 1s;
    -moz-transition: background 1s;
    -o-transition: background 1s;
    transition: background 1s;
}

.title a:hover {
    background: transparent;
    background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
    /* TRANSITION */
    -webkit-transition: background 1s;
    -moz-transition: background 1s;
    -o-transition: background 1s;
    transition: background 1s;
}​

Spójrz: http://jsfiddle.net/AK3La/

Nick Zani
źródło

Odpowiedzi:

104

Możesz przejść background-image. Użyj poniższego kodu CSS na imgelemencie:

-webkit-transition: background-image 0.2s ease-in-out;
transition: background-image 0.2s ease-in-out;

Jest to obsługiwane natywnie przez Chrome, Opera i Safari. Firefox jeszcze go nie zaimplementował ( bugzil.la ). Nie jestem pewien co do IE.

Hengjie
źródło
106
background-imagenie jest animowaną właściwością ( w3.org/TR/css3-transitions/#animatable-properties ), więc Twoje rozwiązanie nie jest zgodne ze standardami.
TLindig
12
To nie jest rozwiązanie - FF i IE go nie obsługują i jak wspomniano powyżej, nie jest to właściwość, która według specyfikacji powinna być obsługiwana.
Sentinel
Zobacz także aktualny rozwój w Fx: bugzilla.mozilla.org/show_bug.cgi?id=546052
Volker E.,
2
@TLindig Powinna to być animowana właściwość.
3
Animatable property to backgroundi to jest to, czego należy użyć (w moim przypadku działa w Chrome). Może specyfikacja (lub impl) uległa zmianie od czasu wysłania pytania
fps
37

Rozwiązaniem (które znalazłem sam) jest sztuczka ninja, mogę ci zaoferować dwa sposoby:

najpierw musisz utworzyć „kontener” dla <img>, będzie on zawierał jednocześnie stany normalne i po najechaniu :

<div class="images-container">
    <img src="http://lorempixel.com/400/200/animals/9/">
    <img src="http://lorempixel.com/400/200/animals/10/">
</div>

Zasadniczo musisz ukryć „normalny” stan i pokazać jego „najechanie” po najechaniu kursorem

i to wszystko, mam nadzieję, że ktoś uzna to za przydatne.

Ruffo
źródło
Niezłe rozwiązanie. Eksperymentując z pierwszą próbką zauważyłem, że jeśli zwiększysz czas trwania przejścia do 4s, możesz zobaczyć bardzo zauważalny skok, gdy indeks z przełącza się w środku przejścia. Przynajmniej w Chrome 35 możesz przesunąć czas przełączania z-index i wyczyścić przejście, zmieniając wartość właściwości na „all 4s easy , z-index 1ms” ( jsfiddle.net/eD2zL/330 ).
Neal Stublen
2
@NealS. masz rację. Ta odpowiedź ma jednak 2 lata, usunąłbym z-index, wydaje się niepotrzebny. Obrazy muszą być po prostu uporządkowane.
Ruffo
Wielkie dzięki. Twoje rozwiązanie jest dla mnie bardzo pomocne.
Slam
Czy możliwe jest „leniwe ładowanie”, jeśli używam tego rozwiązania?
Daniel
16

Znalazłem rozwiązanie, które zadziałało dla mnie ...

Jeśli masz element listy (lub element div) zawierający tylko link i powiedzmy, że dotyczy to linków społecznościowych na Twojej stronie do Facebooka, Twittera itp. i używasz obrazka sprite'a, możesz to zrobić:

<li id="facebook"><a href="facebook.com"></a></li>

Ustaw tło „li” jako obraz przycisku

#facebook {
   width:30px;
   height:30px;
   background:url(images/social) no-repeat 0px 0px;
}

Następnie ustaw obraz tła linku jako stan po najechaniu na przycisk. Dodaj również atrybut krycia do tego i ustaw go na 0.

#facebook a {
   display:inline-block;
   background:url(images/social) no-repeat 0px -30px;
   opacity:0;
}

Teraz wszystko, czego potrzebujesz, to „krycie” pod „a: hover” i ustaw na 1.

#facebook a:hover {
   opacity:1;
}

Dodaj atrybuty przejścia krycia dla każdej przeglądarki do „a” i „a: hover”, aby ostateczny plik CSS wyglądał mniej więcej tak:

#facebook {
   width:30px;
   height:30px;
   background:url(images/social) no-repeat 0px 0px;
}
#facebook a {
   display:inline-block;
   background:url(images/social) no-repeat 0px -30px;
   opacity:0;
   -webkit-transition: opacity 200ms linear;
   -moz-transition: opacity 200ms linear;
   -o-transition: opacity 200ms linear;
   -ms-transition: opacity 200ms linear;
   transition: opacity 200ms linear;
}
#facebook a:hover {
   opacity:1;
   -webkit-transition: opacity 200ms linear;
   -moz-transition: opacity 200ms linear;
   -o-transition: opacity 200ms linear;
   -ms-transition: opacity 200ms linear;
   transition: opacity 200ms linear;
}

Jeśli poprawnie wyjaśniłem, że powinno to pozwolić na zanikający przycisk obrazu tła, mam nadzieję, że przynajmniej pomoże!

Austin Parrish Thomas
źródło
3
Stworzyłem również wersję samouczka wideo. youtube.com/watch?v=6ieR5ApVpr0
Austin Parrish Thomas
Nie powinieneś, AFAIK, musieć określać przejść w pseudoklasie hover; definicja przejścia dla typu znacznika zakotwiczenia przeniesie się do zachowania po najechaniu, wszystko, co musisz zmienić, to krycie. Należy pamiętać, że ten przykład działa dobrze, ponieważ style są stosowane bezpośrednio do identyfikatorów / typów tagów; jeśli robisz to z klasami, musisz upewnić się, że nie dodajesz i nie usuwasz klasy ze zdefiniowanym przejściem.
KeithS
15

Niestety nie możesz użyć przejścia background-image, zobacz listę animowanych właściwości w3c .

Możesz zrobić kilka sztuczek z background-position.

Olwaro
źródło
13

Możesz użyć pseudoelementu, aby uzyskać pożądany efekt, tak jak to zrobiłem w tym Fiddle .

CSS:

.title a {
    display: block;
    width: 340px;
    height: 338px;
    color: black;
    position: relative;
}
.title a:after {
    background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
    content: "";
    opacity: 0;
    width: inherit;
    height: inherit;
    position: absolute;
    top: 0;
    left: 0;
    /* TRANSISITION */
    transition: opacity 1s ease-in-out;
    -webkit-transition: opacity 1s ease-in-out;
    -moz-transition: opacity 1s ease-in-out;
    -o-transition: opacity 1s ease-in-out;
}
.title a:hover:after{   
    opacity: 1;
}

HTML:

<div class="title">
    <a href="#">HYPERLINK</a>
</div>
MaxCloutier
źródło
2
Działa to doskonale, ale można uruchomić na 2 problemy: 1) jeśli nie widzisz :afterelementu, spróbuj ustawić widthi heightjak 100%zamiast inherit, 2) jeżeli background-imagejest faktycznie wyświetlane w planie , indeks użycie negatywne dla :afterelementu:z-index: -1;
Radek Pech
9

Jeśli możesz używać jQuery, możesz wypróbować wtyczkę BgSwitcher, aby przełączyć obraz tła z efektami, jest bardzo łatwy w użyciu.

Na przykład :

$('.bgSwitch').bgswitcher({
        images: ["style/img/bg0.jpg","style/img/bg1.jpg","style/img/bg2.jpg"],
        effect: "fade",
        interval: 10000
});

Dodaj własny efekt, zobacz dodawanie typów efektów

MaxDhn
źródło
Dzięki, rozwiązałem problem z animacją zmiany tła tabeli za pomocą tej wtyczki.
userlond
4

Spróbuj tego, sprawi, że animacja tła będzie działać w sieci, ale hybrydowa aplikacja mobilna nie będzie działać

@-webkit-keyframes breath {
 0%   {  background-size: 110% auto; }
 50%  {  background-size: 140% auto; }
 100% {  background-size: 110% auto; }      
}
body {
   -webkit-animation: breath 15s linear infinite;
   background-image: url(images/login.png);
    background-size: cover;
}
Hesham Nasser
źródło
4

Biorąc pod uwagę, że obrazy tła nie mogą być animowane, stworzyłem małą mieszankę SCSS pozwalającą na przejście między 2 różnymi obrazami tła za pomocą pseudoselektorów przed i po . Znajdują się na różnych warstwach indeksu Z. Ten, który jest przed nami, zaczyna się od krycia 0 i staje się widoczny po najechaniu kursorem.

Możesz użyć tego samego podejścia do tworzenia animacji z liniowymi gradientami.

scss

@mixin bkg-img-transition( $bkg1, $bkg2, $transTime:0.5s ){  
  position: relative;  
  z-index: 100; 
  &:before, &:after {
    background-size: cover;  
    content: '';    
    display: block;
    height: 100%;
    position: absolute;
    top: 0; left: 0;    
    width: 100%;    
    transition: opacity $transTime;
  }
  &:before {    
    z-index: -101;
    background-image: url("#{$bkg1}");    
  }
  &:after {    
    z-index: -100;
    opacity: 0;
    background-image: url("#{$bkg2}");    
  }
  &:hover {
     &:after{
       opacity: 1; 
     }
  }  
}

Teraz możesz go po prostu używać z

@include bkg-img-transition("https://picsum.photos/300/300/?random","https://picsum.photos/g/300/300");

Możesz to sprawdzić tutaj: https://jsfiddle.net/pablosgpacheco/01rmg0qL/

Pablo SG Pacheco
źródło
Bardzo fajne rozwiązanie! Dał mi lepsze zrozumienie, jak dobrze wykorzystać stan elementu „: before” i „: after” jako bonus :-)
joronimo
3

Jeśli animowanie opacitynie wchodzi w grę, możesz także animować background-size.

Na przykład użyłem tego CSS, aby ustawić backgound-imagez opóźnieniem.

.before {
  background-size: 0;
}

.after {
  transition: background 0.1s step-end;
  background-image: $path-to-image;
  background-size: 20px 20px;
}
shock_one
źródło
Jeśli chcesz uzyskać efekt zanikania z .afterdo .beforedla obrazu tła, musisz ustawić obraz tła na .before. W przeciwnym razie po prostu zniknie bez animacji.
Radek Pech
2

Salam, ta odpowiedź działa tylko w Chrome, ponieważ IE i FF obsługują przejście kolorów.

Nie ma potrzeby tworzenia elementów HTML opacity:0, ponieważ czasami zawierają one tekst i nie ma potrzeby podwajania elementów !.

Pytanie z linkiem do przykładu w jsfiddle wymagało niewielkiej zmiany, to znaczy wstawienia pustego obrazu w .title ataki background:url(link to an empty image);sam sposób, w jaki go umieściłeś, .title a:hoverale uczyń go pustym obrazem, a kod będzie działał.

.title a {
display: block;
width: 340px;
height: 338px;
color: black;
background: url(https://upload.wikimedia.org/wikipedia/commons/5/59/Empty.png) repeat;
/* TRANSISITION */
transition: background 1s;
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
  }
  .title a:hover{   background: transparent;
   background: url(https://lh3.googleusercontent.com/-p1nr1fkWKUo/T0zUp5CLO3I/AAAAAAAAAWg/jDiQ0cUBuKA/s800/red-pattern.png) repeat;
/* TRANSISITION */
transition: background 1s;
-webkit-transition: background 1s;
-moz-transition: background 1s;
-o-transition: background 1s;
}

Sprawdź to https://jsfiddle.net/Tobasi/vv8q9hum/

mohammed Suleiman
źródło
Nadal nie działa na fire fox lub IE :(, ale wygląda dobrze w chromie
mohammed Suleiman
1

Z inspirującym postem Chrisa tutaj:

https://css-tricks.com/different-transitions-for-hover-on-hover-off/

Udało mi się to wymyślić:

#banner
{
    display:block;
    width:100%;
    background-repeat:no-repeat;
    background-position:center bottom;
    background-image:url(../images/image1.jpg);
    /* HOVER OFF */
    @include transition(background-image 0.5s ease-in-out); 

    &:hover
    {
        background-image:url(../images/image2.jpg);
        /* HOVER ON */
        @include transition(background-image 0.5s ease-in-out); 
    }
}
Carol McKay
źródło
0

Można to osiągnąć dzięki większej obsłudze różnych przeglądarek niż akceptowana odpowiedź, używając pseudoelementów, czego przykładem jest ta odpowiedź: https://stackoverflow.com/a/19818268/2602816

vaer-k
źródło
0

Przez chwilę się z tym zmagałem, najpierw użyłem stosu obrazów jeden na drugim i co trzy sekundy próbowałem animować do następnego obrazu w stosie i wrzucać bieżący obraz na spód stosu. W tym samym czasie korzystałem z animacji pokazanych powyżej. Nie mogłem zmusić go do pracy dla mojego życia.

Możesz użyć tej biblioteki, która pozwala na ** dynamicznie zmieniany rozmiar obrazu tła z możliwością pokazu slajdów ** przy użyciu jquery-backstretch.

https://github.com/jquery-backstretch/jquery-backstretch

Akhil Khanna
źródło