CSS Transitions, czyli efekty przejścia w CSS

W wersji Firefoksa obecnie oznaczanej jako 3.7 pojawi się wsparcie dla efektów przejścia (ang. transitions) w CSS. Czym są efekty przejścia? W momencie zmiany stanu danego elementu (np. zmiany pseudoklasy, jak :hover, albo zmiany stylu wywołanej np. z poziomu JavaScriptu) wskazane własności CSS zmienią swe wartości w sposób płynny, a nie skokowy.

CSS Transitions pojawiły się najpierw w silniku WebKit, a od niedawna obsługuje je także silnik Gecko 1.9.3. Apple zgłosiło specyfikację CSS Transitions do konsorcjum W3C; ma ona obecnie status „Working Draft” (wersji roboczej).

Jak to wygląda?

Tutaj znajdziecie prosty przykład (potrzebny jest testowy nightly-build Firefoksa z mozilla-central lub w miarę nowe Safari lub Chrome).

Jak tego używać?

Specyfikacja definiuje własności:

transition-property
określa, jaka własność stylu ma podlegać efektowi przejścia
transition-duration
określa, jak długo ma trwać ten efekt
transition-timing-function
określa przyspieszenie lub spowolnienie animacji
transition-delay
określa opóźnienie z jakim ma zacząć się efekt
transition
skrót dla wszystkich pozostałych własności

Omówmy je pokrótce.

transition-property

Podajemy tutaj, jaka własność (lub jakie własności) mają być animowane. Jeśli nie określimy tej własności, lub podamy tu słowo kluczowe all, animowane będą wszystkie własności CSS, które tylko da się animować. Wartość none wyłącza efekty przejścia.

Przykład:

transition-property: color;

transition-duration

Tutaj podajemy czas trwania przejścia.

Przykład:

transition-duration: 5s;

Ta animacja będzie trwała 5 sekund.

transition-timing-function

Własność ta pozwala animacji zwalniać lub przyspieszać w trakcie jej trwania. Do określenia tych zmian wykorzystywane są sześcienne krzywe Béziera.

Dopuszczalne wartości to cubic-bezier(x2, y2, x3, y3), gdzie x2 i y2 oraz x3 i y3 to odpowiednio współrzędne punktów kontrolnych P2 i P3 krzywej (punkty P0 i P1są ustalone jako (0, 0) i (1, 1)).

Kilka szczególnie przydatnych wartości uzyskało także wygodne do zapamiętania aliasy:

Słowo kluczowe Odpowiednik cubic-bezier
ease cubic-bezier(0.25, 0.1, 0.25, 1.0)
linear cubic-bezier(0.0, 0.0, 1.0, 1.0)
ease-in cubic-bezier(0.42, 0, 1.0, 1.0)
ease-out cubic-bezier(0, 0, 0.58, 1.0)
ease-in-out cubic-bezier(0.42, 0, 0.58, 1.0)

Wartość linear oznacza po prostu liniową zmianę wartości, czyli tempo animacji będzie jednostajne. Pozostałe wartości z powyższej tabeli sprawiają, że animacja zwolni lub przyspieszy na początku lub na końcu.

Przykład:

transition-timing-function: linear;

transition-delay

Możemy tu podać opóźnienie, z jakim wykona się animacja. Wartość równa 0 oznacza brak opóźnienia. Dozwolone są również wartości ujemne (-x), wówczas animacja zacznie się natychmiast (tak, jak przy wartości 0), ale początkowa wartość animowanej własności będzie taka, jakby przejście trwało już od |x| sekund.

Przykład:

transition-delay: 0.5s;

transition

Własność transition to skrótowy zapis wszystkich pozostałych, w kolejności: property, duration, timing function, delay. Na przykład:

transition-property: color;
transition-duration: 5s;
transition-timing-function: ease-in;
transition-delay: 2s;

można krótko zapisać jako:

transition: color 5s ease-in 2s;

Zarówno własności transition-* jak i skrótowa własność transition mogą przyjmować wiele wartości równolegle, tj. można
określić efekt przejścia np. dla własności color oraz dodatkowo inny dla width:

transition: color 5s ease-in 2s, width 3s ease-out 3s;

Jak zrobić div, który rozwinie się po najechaniu kursorem?

Bardzo prosto:

HTML:

<div id="slideDiv">witaj świecie!</div>

CSS:

#slideDiv {
  width: 5px;
  height: 20px;
  overflow: hidden;
  background: green;
  color: #fff;
  -moz-transition: width 1s linear;
  -webkit-transition: width 1s linear;
}

#slideDiv:hover {
  width: 20px;
}

Ograniczenia obecnych implementacji

Specyfikacja jest dopiero w stadium roboczym, tak więc wszystko tutaj może się jeszcze zmienić. Zarówno Gecko, jak i WebKit implementują powyższe własności w tzw. przedrostkiem producenta. Oznacza to, że obecnie żaden kod z powyższych przykładów nie zadziała, dopóki nie poprzedzimy odpowiednim przedrostkiem wszystkich omawianych własności. Dla Gecko jest to -moz-, dla WebKitu: -webkit-.

Aby nasze przejścia obecnie działały w obu tych silnikach musimy niestety napisać je dwukrotnie (albo i potrójnie, jeśli chcemy zachować na przyszłość składnię bez przedrostków). W poniższym przykładzie odnośniki będą płynnie zmieniać swój kolor w ciągu pół sekundy od najechania na nie myszą:

a {
  color: #f00;
  -moz-transition: color 0.5s linear;
  -webkit-transition: color 0.5s linear;
  transition: color 0.5s linear;
}

a:hover {
  color: #0f0;
}

W przypadku dostępu do tych własności z poziomu JavaScriptu należy pamiętać o tym, że minus przechodzi w powiększenie następującej po niej litery, tak więc
do własności efektów przejścia z poziomu JS na razie dobieramy się w Gecko przez element.style.MozTransition, a w WebKicie przez
element.style.WebkitTransition.

Nie wszystkie własności są obecnie animowane. Szerszy zakres ma na razie WebKit (obsługuje np. transformacje -webkit-transform; Gecko na dzień dzisiejszy nie pozwala na przejścia dla -moz-transform), ale wkrótce Mozilla powinna tutaj dogonić Apple. :)

Ważna sprawa: ani Gecko, ani WebKit nie animują przejść od wartości w rodzaju auto do wartości liczbowej. Zmiany tutaj odbywają się niestety skokowo.

Poprawna degradacja

Deklaracje własności transition w przeglądarkach nie obsługujących efektów przejścia (w tym obecne wersje Opery, IE, Firefox 3.6 i starsze, stare WebKity) nie powodują żadnych problemów, po prostu wymiary czy kolory elementów zmienią się w nich skokowo, tak jak bez transition.

Czy już to stosować?

Na poważnych witrynach najlepiej będzie się wstrzymać, przynajmniej do czasu względnego ustabilizowania się specyfikacji i jej implementacji.
Ale nikt nie broni dzisiaj poeksperymentować! :)

Linki

Mozilla Hacks: Eliptyczne obramowania w Firefoksie 3.5

W ramach serii tłumaczeń artykułów z bloga Mozilla Hacks, przedstawiam dzisiaj tłumaczenie artykułu Elliptical Borders in Firefox 3.5, którego autorem jest Lim Chee Aun (web developer z Malezji, autor ikon i motywu Phoenity). Oryginalny artykuł i jego tłumaczenie dostępne są na warunkach licencji Creative Commons Attribution 3.0 USA.

Własność border-radius jest prawdopodobnie jedną z bardziej interesujących części specyfikacji CSS 3, umożliwiającą tworzenie zaokrąglonych rogów elementów dokumentu. Na przykład:

div {

  border-radius: 10px;
  -moz-border-radius: 10px;
  -webkit-border-radius: 10px;

}

W Firefoksie 3.5 własność -moz-border-radius jest obecnie zgodna z najnowszą wersją (roboczą – przyp. tłum.) specyfikacji CSS 3. Dzięki temu można tworzyć także eliptyczne obramowania.

Co to więc znaczy? Według specyfikacji składnia jest następująca:

-moz-border-radius: <border-radius>{1,4} [ / <border-radius>{1,4}]?

Mamy tutaj zbiór wartości tej własności rozdzielonych ukośnikiem. Tutaj leży cała magia. Jeśli dwa zbiory wartości rozdzielone są ukośnikiem, wartości z lewej strony określają półoś poziomą, a wartości z prawej – półoś pionową.

Oferuje to ciekawe możliwości. Poniższe demo pokazuje kilka eksperymentów z różnymi kształtami, które można w ten sposób uzyskać.

W przykładzie tym eksperymentujemy nie tylko z grubością i promieniem/półosiami obramowania, ale także i jego stylem – o wartościach ridge, double i groove. Obecnie wartości dotted i dashed nie działają, wyświetlane są jak solid. Więcej informacji na ten temat znaleźć można w zgłoszeniu błędu Mozilli nr 431176 .

Mozilla Hacks: API selektorów w DOM w Firefoksie 3.5

W ramach serii tłumaczeń artykułów z bloga Mozilla Hacks, przedstawiam dzisiaj tłumaczenie artykułu DOM Selectors API in Firefox 3.5 autorstwa Johna Resiga. Oryginalny artykuł i jego tłumaczenie dostępne są na warunkach licencji Creative Commons Attribution 3.0 USA.

API selektorów w DOM w Firefoksie 3.5

Specyfikacja Selectors API, rekomendacja W3C, to nowe rozwiązanie pozwalające programistom JavaScriptu odnajdywać elementy drzewa DOM strony przy użyciu selektorów CSS. To pojedyncze API pozwala na przeszukiwanie drzewa DOM i odnajdywanie jego elementów przy użyciu prostego, ujednoliconego interfejsu.

API selektorów jest jednym z lepiej obsługiwanych przez wszystkie przeglądarki nowych standardów: można z niego korzystać już dziś w Internet Explorerze 8, Chrome, Safari, Firefoksie 3.5 i wkrótce w Operze 10.

Korzystanie z querySelectorAll

Selectors API zawiera dwie metody dostępne na wszystkich dokumentach, elementach i fragmentach DOM: querySelector i querySelectorAll. Metody te działają prawie identycznie – obie przyjmują jako argument selektor CSS i zwracają pasujące do niego elementy DOM (z tą różnica, że querySelector zwraca tylko pierwszy pasujący element).

Na przykład, mając dany poniższy fragment kodu HTML:

<div id="id" class="class">
    <p>Pierwszy akapit.</p>

    <p>Drugi akapit.</p>
</div>

możemy wykorzystać querySelectorAll do ustawienia czerwonego koloru tła wszystkich akapitów leżących wewnątrz diva o ID równym „id”:

var p = document.querySelectorAll("#id p");

for ( var i = 0; i < p.length; i++ ) {

    p[i].style.backgroundColor = "red";
}

Możemy też odnaleźć pierwszy akapit diva o klasie „class” i ustawić jego nazwę klasy na „first”.

document.querySelector("div.class > p:first-child")
    .className = "first";

Dotychczas, bez użycia Selectors API, tego rodzaju przeszukiwanie wymagałoby napisania długiego kodu JavaScript/DOM, złożonego z wielu linii i wielu zapytań.

O ile metody Selectors API są relatywnie proste w użyciu (pobierają tylko jeden argument), o tyle bardziej problematyczną sprawą jest dobór selektorów CSS. API selektorów korzysta z selektorów CSS natywnie obsługiwanych przez przeglądarkę do stylowania elementów przy użyciu CSS. W większości przeglądarek (Firefoksa, Safari, Chrome i Opery) oznacza to, że możemy w pełni korzystać z selektorów CSS 3. Internet Explorer 8 obsługuje bardziej ograniczony podzbiór selektorów, włączając w to selektory CSS 2 (które i tak są bardzo przydatne).

Największym wyzwaniem dla nowych użytkowników API selektorów jest więc określenie, które selektory CSS są odpowiednie do odnalezienia pożądanych elementów – szczególnie, że większość programistów piszących kod działający w wielu przeglądarkach ma doświadczenie głównie z ograniczonym podzbiorem w pełni działających selektorów CSS 1.

Dobrze jest zacząć od specyfikacji selektorów CSS 2 i CSS 3, ale warto też przejrzeć poniższe artykuły, by dowiedzieć się więcej (w języku angielskim – przyp. tłum.):

Implementacje w bibliotekach

Najciekawszy przypadek użycia API selektorów to nie tyle ich bezpośrednie stosowanie przez programistów WWW, ale ich wykorzystanie w bibliotekach, które już teraz dostarczają funkcjonalność selektorów CSS w DOM. Istotnym dziś problemem w szerszym stosowaniu API selektorów jest fakt, że nie są one dostępne we wszystkich przeglądarkach, dla których tworzy się obecnie strony (w tym IE 6, IE 7 i Firefox 3). Dlatego też, dopóki starsze przeglądarki są w użyciu, musimy korzystać z narzędzia pośredniczącego, aby odtworzyć zachowanie selektorów CSS w DOM.

Na szczęście w wielu istniejących bibliotekach jest dostępne API zgodne z Selectors API (w rzeczywistości Selectors API zostało w dużej mierze zainspirowane przez istniejące biblioteki). Co więcej, wiele z tych implementacji używa wewnętrznie właśnie Selectors API. Oznacza to, że można stosować selektory CSS w DOM w wielu przeglądarkach już teraz, zapewniając większą wydajność w nowych przeglądarkach obsługujących Selectors API, bez nadmiernego wysiłku.

Oto niektóre z istniejących implementacji, które korzystają z Selectors API, o ile to możliwe:

Warto jeszcze raz podkreślić duży skok w wydajności, jaki powoduje korzystanie z nowego API (w porównaniu z tradycyną mieszanką DOM i JabaScriptu, stosowaną do tej pory). Różnicę tę widać na przykład we wzroście wydajności bibliotek javascriptowych, odkąd zaimplementowały one Selectors API.

Ostatnio wykonane testy przyniosły następujące wyniki:

Widać tu dramatyczny wzrost wydajności po zaimplementowaniu natywnego API selektorów w bibliotekach – całkiem możliwe, że podobny wzrost wydajności zobaczysz także w swoich aplikacjach.

Zestaw testów

Razem ze specyfikacją Selectors API przygotowany został zbiór testów Selectors API, jego autorem jest John Resig z Mozilli. Ten zbiór testów pozwala określić jakość implementacji API selektorów w głównych przeglądarkach.

Aktualne wyniki (w momencie pisania oryginalnego artykułu – przyp. tłum.) dla przeglądarek obsługujących nowe API:

  • Firefox 3.5: 99.3%
  • Safari 4: 99.3%
  • Chrome 2: 99.3%
  • Opera 10b1: 97.5%
  • Internet Explorer 8: 47.4%

Internet Explorer 8, jak wspomniano wcześniej, nie obsługuje większości selektorów CSS 3, dlatego nie przechodzi większości powiązanych testów.

Selectors API pozwala na proste i szybkie odnajdywanie elementów DOM strony. Już teraz przynosi ono pożytek osobom korzystającym z bibliotek javascriptowych zapewniających podobną funkcjonalność, dlatego też zachęcamy do wypróbowania nowego API już teraz.

Mozilla Hacks: Nieprzezroczystość w Firefoksie 3.5

W ramach serii tłumaczeń artykułów z bloga Mozilla Hacks, przedstawiam dzisiaj tłumaczenie (króciutkiego) artykułu Opacity in Firefox 3.5, autorstwa Chrisa Blizzarda. Oryginalny artykuł i jego tłumaczenie dostępne są na warunkach licencji Creative Commons Attribution 3.0 USA.

Nieprzezroczystość w Firefoksie 3.5

To będzie bardzo krótka notka, ale warta opublikowania, bo pokazuje, jak możliwości przeglądarek rozwijają się, począwszy od własnej implementacji producenta po w pełni wspierany standard.

Firefox 3.5 nie obsługuje już specyficznej dla Mozilli własności CSS -moz-opacity. Programiści chcący określić stopień nieprzezroczystości elementu powinni stosować standardową własność opacity.

Własność opacity pojawiła się już w Firefoksie 0.9, a -moz-opacity została oznaczona jako przestarzała. W Firefoksie 3.5 została ostatecznie usunięta.

Trwało to długo, jak na prostą własność, ale warto o tym wspomnieć, by pokazać perspektywę czasową dla tego rodzaju funkcji i ich związku ze standardami.