INDEVELOPMENTbeta






Subskrybuj m1chu.eu – another devblog
 
  •  Pawel: Witam Na stronie http://www.rozenek.com/polski, 198 opisalem podobny problem:...
  •  wwww: Geniusze IT w Warszawie http://capital24.tv/film/4c336 f2d7c878/geniusze_it_w_warszaw ie
  •  Kpc21: Na Operze 10.53 działa już w postaci docelowej, bez „-o-”.
  •  m1chu: Prawda, to nie są strony zbyt funkcjonalne. Dlatego większość z nich to portfolia/personalne...
  •  No flash: Prawie wszystkie te strony to odwiedzić raz i już potem na nie nie wracać. Na pewno nie ułatwiają...
  •  m1chu: Faktycznie, lepiej brzmi. Zmieniłem, a komentarz nikogo nie obraża – więc może zostać :]
  •  bigZbig: Artykuł merytorycznie bardzo fajny tylko proszę zmień zdanie “wszelkie metody oraz funkcje...

Ankieta!

  • Jak oceniasz poziom artykułów? (dokładną opinię umieść w komentarzu)

    View Results

    Loading ... Loading ...




Efekt rollover w CSS bez przeładowywania obrazka


Rollover w światku tworzenia stron internetowych to efekt podmieniania danego obrazka na inny po najechaniu na ten pierwszy kursorem myszy. Początkowo termin ten dotyczył głównie JavaScriptu w którym to takowy efekt dało się osiągnąć. Od kilku jednak lat prym wieńczy w tej kategorii rollover CSS najczęściej w swojej najprostszej, książkowej formie. Często skutecznej, ale przy większej wadze grafik powodujący niemiły efekt przeładowania.

Każdy kto zaczyna naukę Kaskadowych Arkuszy Stylów spotyka się z przykładem wymienionego przeze mnie powyżej prostego efektu podmiany.

a {
	background-image: url('adres/obrazek.png');
	background-repeat: no-repeat;
	width: 200px;
	height: 150px;
}
a:hover {
	background-image: url('adres/obrazek_hover.png');
	background-repeat: no-repeat;
	width: 200px;
	height: 150px;
}

Na szybko przygotowałem Wam przykład, który zarazem doskonale obrazuje problem widoczności przeładowania obrazka. Pewnie niektórzy z Was zauważyli już, że przy pierwszy załadowaniu strony i najechaniu kursorem myszy na obrazek zanim pojawi się jego zamiennik grafika całkowicie znika. Wiąże się to z tym, że ważący ponad 30kB plik grafiki jest ładowany dopiero w momencie najechania na obszar domyślnego obrazka. Dlatego można wynieść z tego wniosek, że czym cięższy plik ładowany w pseudoklasie :hover, tym dłuższy “efekt zanikania” ujrzymy (oczywiście względnie do prędkości łącza które posiadamy).

Teoretycznie można by działać na tablicach w JavaScript-cie, bądź starać się zmniejszyć wagę używanych plików poprzez np. zwiększanie kompresji. Pytanie brzmi po co? Czy nie lepiej bezpośrednio połączyć grafiki przed i po najechaniu kursorem myszy, po czym dynamicznie zmieniać lokalizację tła?

Opierając się na pierwszym podanym przeze mnie przykładzie łącze na początek dwie grafiki w jedną, spójną – w moim przypadku w płaszczyźnie poziomej (zobrazowanie). Co za tym idzie szerokość już teraz jednego obrazka zwiększa swój rozmiar dwukrotnie. W momencie użycia pseudoklasy :hover po prostu zamiast ładować nowy obrazek nastąpi przesunięcie aktualnego tła grafiki o połowę jego szerokości poprzez użycie background-position. Należy też pamiętać, że pomimo iż cała szerokość grafiki zwiększyła się nam dwukrotnie to szerokość wyświetlanego obrazka jest nadal taka sama.

W obrazującym przykładzie można zauważyć, że najpierw wyświetlana jest lewa połowa obrazka o szerokości 200px x 150px, a po najechaniu kursorem następuje przesunięcie w lewo o 200px i pojawia się prawa połowa. Proste rozwiązanie, a diametralnie pozbywa się efektu przeładowania i zaniknięcia grafiki przy wykonaniu pseudoklasy :hover, gdyż całe tło ładowane jest wraz ze stroną.

Pewnie komuś już na myśl naszło pytanie:

“No dobra, ale co jeśli nie chcę posłużyć się atrybutem background, a mam ochotę użyć zwykłego tagu img?”

Najczęściej używanym przykładem jest w tym wypadku zastosowanie polecenia margin. Podobnie jak w poprzednim przypadku używamy złączonej grafiki. Tym razem jednak idąc za pytaniem używamy tagu img do wyświetlenia grafiki.

<a href="http://adres.pl/" title="about"><img src="adres/obrazek.png" alt="about" /></a>

Co do arkusza stylów na początek musimy określić rozmiary odnośnika, a także przekształcić go w element blokowy.

a {
	display: block;
	width: 200px;
	height: 150px;
}

Ponadto należałoby określić sposób wyświetlania tagu odpowiadającego za pokazywania obrazka. Robimy to podobnie jak w powyższym przypadku używając display: block;. No i ostatecznie musimy zdefiniować ujemne przesunięcie marginesu przy wywołaniu pseudoklasy :hover. Ponieważ w naszym przypadku łączenie obrazków nastąpiło w poziomie to przesunięcie musi nastąpić w lewo (dlatego występuje przesunięcie ujemne marginesu) o połowę szerokości całej grafiki.

Ci którzy już zaimplementowali sposób pewnie od razu zauważą, że zamiast połowy obrazu widać cały, a po najechaniu następuje przesunięcie, ale domyślna połowa nie zanika, a jest także przesuwana. Aby temu zapobiec należy przyciąć wystające części obrazka poprzez zastosowanie overflow: hidden;.

a {
	display: block;
	width: 200px;
	height: 150px;
	overflow: hidden;
}
a img {
	display: block;
}
a:hover img {
	margin-left: -200px;
}

Wszystkie trzy sposoby działają prawidłowo w Firefoxie 3, Operze 9.5b, IE7 i Safari 3.1.2.

PS: podobnych lub nawet pod względem podejścia identycznych rozwiązań problemu można znaleźć wiele w internecie. Są one po prostu w miarę uniwersalne. Przykładem może być notka Riddle’a, która dawno temu w dużym stopniu zaznajomiła mnie z tym tematem. W ramach przedstawienia swojego poglądu i tłumaczenia przypominam rozwiązanie problemu :D


22 komentarzy

  • gravatar
    1. ToMaj ()

    Ciekawy motyw, na pewno się kiedyś przyda ;) Ciekaw jestem tylko jak to łykają poprzednie wersje syfnego IE… :P

  • gravatar
    2. m1chu ()

    Szóstka, a co za tym idzie pewnie i poprzednie wersje potrzebują dla :hover samego odnośnika hacka w postaci ustawienia wyświetlania linku w postaci bloku (display: block;). Nie mam niestety tej wersji więc nie powiem Ci, czy to wystarczy. Nie pamiętam, a szukać tego mi się zbytnio nie chce :]

    Po za tym przestałem pisać cokolwiek pod IE<7, bo to przysparza więcej kłopotów niż korzyści ;] Niech się ludzie edukują (czytaj niech ten odsetek z IE6 wreszcie dokona aktualizacji), a nie ja się będę męczył :D

  • gravatar
    3. DoZer ()

    Polecam uzywac obrazow ktore udostepnil microsoft. System windows XP jest na obu oraz ie6 na jednej i ie8 na drugiej, dobre do testowania stron:
    http://www.microsoft.com/downloads/details.aspx?FamilyID=21eabb90-958f-4b64-b5f1-73d0a413c8ef&DisplayLang=en

  • gravatar
    4. m1chu ()

    Teoretycznie fajna sprawa taki obraz. Z drugiej strony waga tych plików zniechęca. I tylko po to, żeby przetestować czy strona zadziała na IEx, bo programistom nie chciało się poprawnie napisać przeglądarki?

    Co tam… znajdę chwilę to może przetestuje. Dzięki za link :D

  • gravatar
  • gravatar
    6. flausz ()

    A czy jest jakiś sposób aby podmienić input submit? Bo ta metoda mi nie działa.

  • gravatar
    7. m1chu ()

    Robisz to dokładnie tak jak w pierwszym przykładzie. Tylko, że na elemencie input.

    Powiedzmy, że jest to przycisk o klasie button.

    <input type="button" class="button" />

    Przykładowy CSS może wyglądać tak:

    input.button {
    	background-image: url('adres_grafiki');
    	background-repeat: none;
    	width: 200px;
    	height: 150px;
    	border: 0px; // brak obramowania
    	display: block;
    }
    input.button:hover {
    	background-position: -200px;
    }

    Przepraszam, że tak późno – miałem krótkie wakacje :D

  • gravatar
    8. Tekilla ()

    Ja robilem ten efekt w dreamweaverze dosc prosta metoda sciezka przed i po z tym że mam problem bo wstawielm div tag w srodku niego tabelkę – chciałem podmieniać obrazki z tym że efekt mi nie działa. Próbowałem również kodu ze strony ale też nie bardzo co mogę jeszcze zrobić? to kwestia diva? – bez diva efekt chodzi normalnie.

  • gravatar
    9. m1chu ()

    Podaj tą część kodu HTML w którym ma zaistnieć efekt (z tym divem i elementami tabeli) oraz CSS który używasz dla tego kodu. Łatwiej będzie udzielić Ci pomocy wtedy :]

  • gravatar
    10. Tekilla ()

    Moze problem tkwić też w tym ze mogłem nieprawidłowo wstawić twój css – 2 miesiąc bawie się programami typu corel,photoshop,edytory htmla, dremweaver(bardzo mi sie to podoba) od niedawna wiec tak wygląda mój fragment kodu:

    </div>
    <div id="apDiv2">
      <table width="547" height="355" border="0">
        <tr>
          <td width="175" height="117"><a href="obro/autofoto.jpg" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('autofoto','','rover/twarzzoltyov.jpg',1)" rel="nofollow"><img src="obrwlasciwemin/autofotomin.jpg" alt="autofoto" name="autofoto" width="171" height="106" border="0"></a></td>

    to jest 1 okienko tabeli które myślę trzeba odpowiednio przerobić – kod over dreamwever sobie zrobił poprawnie acz kolwiek właśnie jest ten div i nie działa z nim

    http://www.psdesign.yoyo.pl/

  • gravatar
    11. Tekilla ()

    Ehh wysłałem kod na twoją skrzynkę(m1chu@) jestem taki newbie że nie wiem jak się tu wstawia kod:P – skassuj tego mojego posta^^ i w jakimś zwrotnym emailu mnie uświadom delikatnie pls:) jak się to robi żeby nie było więcej żenady.

  • gravatar
    12. m1chu ()

    Kod wstawiasz w [nazwa_jezyka]kod[/nazwa_jezyka]. Np. dla HTML-a będzie to [html]kod[/html]. Poprawiłem i wstawiłem to co dostałem mailem.

    Nadal niezbyt rozumiem co chcesz zrobić. Próbujesz zmienić tło td, diva, czy pola input? W którym miejscu na Twojej stronie starasz się użyć rozwiązania które tutaj podałem?

  • gravatar
    13. Tekilla ()

    Wejdź w np pod stronkę obróbka tam są miniaturki obrazków – ja chcę zrolować obrazek tak żeby było widać miniaturę przed obróbką i po obróbce – czyli najechanie myszką obrazka a on zmienia się na inny.

  • gravatar
    14. m1chu ()
    #apDiv2 a {
    	display: block;
    	width: 200px;
    	height: 150px;
    	overflow: hidden;
    }
    #apDiv2 a img {
    	display: block;
    }
    #apDiv2 a:hover img {
    	margin-left: -200px;
    }

    To jest przykładowy arkusz stylów, jaki możesz użyć. Linijka pojedynczej grafiki (komórki tabeli) powinna wyglądać tak:

    <td style="width: 200px;"><a href="obro/brat1.jpg" rel="nofollow"><img src="obrobkamin/brat1min.jpg" alt="obraz2" style="width: 200px; height: 132px;"></a></td>

    Zapomniałeś o jednej rzeczy jeszcze. Np. ta grafika obrobkamin/brat1min.jpg musi być złączonym obrazkiem wyświetlanym przed i po najechaniu. To Ci pokaże o co chodzi. Inaczej nie nastąpi przesunięcie, bo nie ma czego przesunąć. I tak z każdą grafiką w img na której chcesz zastosować taki efekt.

    Nie ma tu nic nadzwyczajnego. Jest to ostatni przykład który podałem w artykule, bez żadnych dodatkowych efektów do napisania. Przeczytaj dokładnie mój wpis, a zrozumiesz o co chodzi.

  • gravatar
    15. Tekilla ()

    Head:

    <link href="stylkom.css" rel="stylesheet" type="text/css">

    nie wiem jak sie koduje:) zamiast < sa # w dalszym ciagu to jest styl kaskadowy?

    przeskok do body okienka w ktorym mam
    tak jak napisałeś

    <td style="width:175px;"><a href="obrwlasciwemin/autofotomin.jpg"
    rel="nofollow"><img src="over/over1.jpg" alt="obraz1" style="width: 171px;
    height: 106px;"></a></td>

    i zewnętrzny css taki:

    #apDiv2 a {
            display: block;
            width: 175px;
            height: 117px;
            overflow: hidden;
        }
        #apDiv2 a img {
            display: block;
        }
       #apDiv2 a:hover img {
           margin-left: -175px;

    z moimi wartościami – obraz over1.jpg jest obrazem 2×171= czyli jak u
    ciebie 400 u mnie 342(tak to połączone obrazki) – i teraz nie wiem -
    zastosowałem styl podmieniałem ścieżkę – czy to w a href najpierw
    over/over1.jpg czy to tak jak ma być że najpierw prawidłowy obrazek a potem
    ten 2 razy dłuższy . Daje to jednak nie efekt przesunięcia tylko pojawia
    się 1 obrazek jak najedziesz to on znika a 2 obrazek jest linkiem i po
    kliknieciu na obrazek się otwiera. Jeżeli wstawię 2 razy dłuższy obrazek to
    on ściska się w 171 pixeli i mam w 171pixlach 2 obrazki. Jeżeli miały to
    być 2 obrazki 2 razy dłuższe to jest 1 scisniety a 2 wyświetla się w linku
    na nowym blanku. Tak wiec co jest źle? nie wiem czy dobrze rozumiem idee
    tego według ciebie obrazek się przesuwa i pewnie tak jest tylko czemu u
    mnie tego nie ma:D. Ja używałem image ready w wersji 7.0 do zrobienia
    butonów na stronie – w image redy najpierw w photoshopie robisz buton potem
    włączasz efekty w 2 klatce efektu rollover i tak on powstaje. Czyli zasada
    dołożenia elementów- przynajmniej wzrokowo tak to wygląda.

    PS jak ktoś pragnie zobaczyć mój kod to proszę o fragment kodu na skrzynkę – bo ja niewiem jak kodować

  • gravatar
    16. Tekilla ()

    A nic widzę ze to jednak nie pokazuje od razu kodu myślałem że jak z tekstem no nic było dobrze kodowanie nauczone:D

  • gravatar
    17. 2 animowane menu za pomocą funkcji jQuery - animate() | m1chu.eu - another devblog ()

    [...] – klasa służąca do pobierania plików z wrzuta.pl, youtube.com i owned.com (wyświetleń: 700)Efekt rollover w CSS bez przeładowywania obrazka (wyświetleń: 609)Proste uruchamianie i zamykanie zewnętrznych programów w Visual C++/C# [...]

  • gravatar
    18. m1chu ()

    Znaczniki które podałem służą tylko do tego, żeby umieszczony w nich kod został pokolorowany wg. danej składni. Na maile tego typu nie odpowiadam, od tego są komentarze. Nie ma żadnej filozofii w użyciu podanych przeze mnie znaczników. Wystarczy przeczytać co nie co o BBCode, bądź odrobinę logicznie pomyśleć.

    Obrazek w odnośniku (a href) to zupełnie inna grafika. Ty masz połączyć dwie grafiki w jedną dla znacznika img. Nieważne czym to połączysz. Można to zrobić każdym programem do obróbki grafiki.

    Wszedłem na Twoją stronę i widzę pojedynczą grafikę pod tagiem img, a nie połączoną. Więc nic nie zmieniłeś.

    Jak już poprawisz powyższą rzecz to usuń style="width: 171px; height: 106px;" z img. Wtedy musi już działać :D

  • gravatar
    19. Mario ()

    Problem z podmianą obrazków istnieje nadal pod ie6. Polega na tym, że zmiana obrazków metodą background-position powoduje … ponowne załadowanie obrazka. Niezależnie od tego, czy robimy to za pomocą css’a, czy javascriptu. Nie pomagają przy tym skrypty images preload itp. Żeby się o tym przekonać że tak jest wystarczy wrzucić swoje “rollovery” gdzieś na sieć i po załadowaniu strony wyjąć wtyczkę sieciową … :(

  • gravatar
    20. m1chu ()

    Urok IE6. Bijmy pokłony programistom po raz kolejny :D

    Nie mam IE6 i szczerze mówiąc nie mam jak tego teraz sprawdzić. Więc piszę czysto teoretycznie – “z tego co wiem”. IE6 ma problem z obsługą background-position, na pewno na takim poziomie, że nie potrafi poprawnie “przesuwać” plików PNG (innych niż 8-bitowe). Spróbuj może z GIFem.

    Jeżeli to nie pomoże warto wskoczyć na MSDN (które tak nawiasem mówiąc jest dobrym kompendium wiedzy na tematy związane z aplikacjami i środowiskami MS) i zapoznać się z rozszerzeniami: -ms-background-position-x i -ms-background-position-y.

    Ostatecznie zostaje JS (backgroundPosition) lub np. jQuery (background-position-x, background-position-y, background-position). Te dwie metody, jeżeli są poprawnie napisane powinny działać.

  • gravatar
    21. bart ()

    A da się to zastosować do animowanego obrazku ? Np. obrazek 400px – lewa cześć 200px normalny statyczny obraz a druga animowany. Po zastosowaniu powyższego tutka animacja wyświetla się tylko 1 raz a zależało by mi na tym aby odtwarzana była za każdym razem po najechaniu gryzoniem.

  • gravatar
    22. m1chu ()

    Nie próbowałem uzyskać nigdy tego efektu z animacją. Nie mniej jednak polega on tylko i wyłącznie na przesunięciu widocznej części tła lub marginesu. Teoretycznie więc, jeżeli zapętlisz animację (prawą część grafiki) to nie powinno być problemu z jej odtwarzaniem.

Dodaj własny komentarz

Możesz użyć następujących tagów XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>