W dzisiejszym wpisie krótki poradnik, w którym przedstawiam jak łatwo naprawić przesunięcie 1px przy efekcie transition. Co prawda nie jest to częsty problem, który możecie napotkać ale być może komuś się przyda…

Przykład

Jeśli zaglądacie tutaj raz na jakiś czas, zauważyliście pewnie, że w nowym interfejsie na stronie głównej, raz na kilka wpisów dorzucam zdjęcie nagłówkowe. Wspominałem zresztą o tym ostatnio, kiedy opisywałem na przykładzie tych zdjęć,jak stworzyć własną wtyczkę jQuery. Na liście najnowszych wpisów, oprócz tego, że zdjęcia są w locie “przycinane”, dodałem też efekt rozjaśniania się obrazka w momencie gdy najedzie się na niego myszką. Efekt ten uzyskałem dzięki właściwości opacity oraz transition. Kod który odpowiada za ten efekt poniżej:

img {
    opacity: 0.8;

    -moz-transition: all 0.4s ease-in;  /* FF4+ */
    -o-transition: all 0.4s ease-in;  /* Opera 10.5+ */
    -webkit-transition: all 0.4s ease-in;  /* Saf3.2+, Chrome */
    -ms-transition: all 0.4s ease-in;  /* IE10? */
    transition: all 0.4s ease-in;
}

img:hover {
    opacity: 1;

    -moz-transition: all 0.4s ease-out;  /* FF4+ */
    -o-transition: all 0.4s ease-out;  /* Opera 10.5+ */
    -webkit-transition: all 0.4s ease-out;  /* Saf3.2+, Chrome */
    -ms-transition: all 0.4s ease-out;  /* IE10? */
    transition: all 0.4s ease-out;
}

Prosta sprawa, obrazek ma ustawioną przezroczystość na 0.8 (czyli jest nie do końca przezroczysty), a dla pseudo-klasy hover przezroczystość jest całkowicie wyłączona (opacity: 1). Pozostałe ustawienia to efekt tranzycji czyli przekształcenie - dzięki temu po najechaniu wskaźnikiem myszy na zdjęcie, przezroczystość zmienia się ładnie i powoli (trwa dokładnie 0.4 sekundy).

Wszystko fajnie, tylko przy takim ustawieniu CSS’a występuje mało fajny błąd objawiający się tym, że po zakończeniu przekształcenia, następuje przesunięcie 1px tzn. obrazek (czy też inny element, na którym wykonujemy tranzycję) tak jakby przeskakuje czy też przesuwa się właśnie o taką wartość. Jest to błąd przeglądarek, obecnie występuje nadal w Firefox ver. 29 (sprawdzałem też w Chrome ver. 35 oraz IE 11 - w tym przypadku nie ma tego brzydkiego efektu, jednak z tego co mi wiadomo, występuje on w starszych wersjach przeglądarek).

Przesunięcie 1px - rozwiązanie problemu

Rozwiązaniem problemu okazało się zaaplikowanie elementowi img właściwości backface-visibility: hidden czyli dla mojego przykładu CSS będzie wyglądał w ten sposób:

img {
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;

    opacity: 0.8;

    -moz-transition: all 0.4s ease-in;  /* FF4+ */
    -o-transition: all 0.4s ease-in;  /* Opera 10.5+ */
    -webkit-transition: all 0.4s ease-in;  /* Saf3.2+, Chrome */
    -ms-transition: all 0.4s ease-in;  /* IE10? */
    transition: all 0.4s ease-in;
}

Dla zachowania kompatybilności (i dla pewności) dodałem to ustawienie w wersji standardowej oraz dla silnika webkit - dokumentacja mówi, że tylko taki prefiks jest obsługiwany. Na pewno zastanawiacie się, co też takiego robi to ustawienie… Otóż standardowo ma ono zastosowanie w przekształceniach 3D - jeśli dla przykładu obracamy element o 180 stopni (za pomocą transform: rotateY(180deg)), wówczas ustawienie to mówi przeglądarce czy “tył” (czyli de facto lustrzane odbicie) elementu ma być widoczny podczas przekształcenia czy też nie (możliwe ustawienia to visible, hidden oraz inherit). Fajny opis tej właściwości znajdziecie na css-tricks.com. Jak więc widać, sama właściwość ma nie wiele wspólnego z opisywanym dziś problemem, mamy więc do czynienia z “hackiem”… Myślę jednak, że czasem warto znać takie “kwiatki” :)