ES6 – default + rest + spread

javascript

Biorąc pod uwagę całe lata narzekań, ECMAScript 2015 przynosi nam wiele nowości, czego rezultatem jest spora ilość usprawnień. Sprawiają one, że pisanie kodu w JavaScript jest bardziej intuicyjne oraz po prostu szybsze. Spójrzmy zatem na nowy sposób przekazywania parametrów do funkcji.


Zobacz całą serię: Let-s talk about ECMAScript 2015


default

Jest to małe, ale bardzo przydatne usprawnienie w przekazywaniu parametrów do funkcji. Wiemy przecież, że funkcje w języku JavaScript pozwalają na przekazanie do nich dowolnej ilości parametrów. Z pewnością nie raz spotkaliście się z podobnym kodem:

function inc(number, increment) {
  // set default to 1 if increment not passed
  // (or passed as undefined)
  increment = increment || 1;
  return number + increment;
}
console.log(inc(2, 2)); // 4
console.log(inc(2));    // 3

Operator logiczny OR (||) przypisuje w tym wypadku wartość 1 do zmiennej increment, ponieważ lewy człon wyrażenia to undefined, czyli false.

ES6 pozwoli pozbyć się tego typu wyrażeń, wykorzystując w tym celu parametry z domyślnymi wartościami. Funkcja inc z wykorzystaniem składni ES6 prezentuje się zatem następująco:

function inc(number, increment = 1) {
  return number + increment;
}
console.log(inc(2, 2)); // 4
console.log(inc(2));    // 3

Tym samym parametry z wartościami domyślnymi są opcjonalne.

Możemy również definiować domyślne wartości parametrów, które występują w środku sygnatury funkcji:

function sum(a, b = 2, c) {
  return a + b + c;
}
console.log(sum(1, 5, 10));         // 16 -> b === 5
console.log(sum(1, undefined, 10)); // 13 -> b as default

Wykorzystanie wartości domyślnej następuje w tym wypadku w momencie, gdy jako wartość parametru podamy undefined.

Wartości domyślne nie muszą być typami prymitywnymi. Jako domyślną wartość możemy przypisać choćby rezultat wykonania funkcji:

function getDefaultIncrement() {
  return 1;
}
function inc(number, increment = getDefaultIncrement()) {
  return number + increment;
}
console.log(inc(2, 2)); // 4
console.log(inc(2));    // 3

rest

Spróbujmy napisać wcześniejszą funkcję sum tak, by brała pod uwagę wszystkie parametry jakie do niej przekażemy. By zachować czystość kodu, pominiemy tutaj walidację. Jeżeli próbowalibyśmy użyć do tego zadania składni dobrze znanej z ES5, to z pewnością otrzymalibyśmy coś takiego:

function sum() {
   var numbers = Array.prototype.slice.call(arguments),
       result = 0;
   numbers.forEach(function (number) {
       result += number;
   });
   return result;
}
console.log(sum(1));             // 1
console.log(sum(1, 2, 3, 4, 5)); // 15

Przy takim podejściu nie wiemy od razu co robi dana funkcja. Nie wystarczy, że spojrzymy na jej sygnaturę. Musimy jeszcze przeskanować jej ciało, znaleźć obiekt arguments i wywnioskować, że chodzi tutaj o zsumowanie wszystkich parametrów przekazanych do funkcji.

Składnia ES6 znacznie lepiej radzi sobie z podobnym problemem . Wprowadza ona pojęcie rest parameters, gdzie parametr poprzedzony (trzema kropkami) staje się tablicą, do której “wpadają” wszystkie pozostałe parametry przekazane do funkcji.

Obiekt arguments zawierać będzie wszystkie parametry funkcji - te nazwane i nie.

Możemy użyć nowej składni ECMAScript 2015 i przepisać funkcję sum:

function sum(…numbers) {
  var result = 0;
  numbers.forEach(function (number) {
    result += number;
  });
  return result;
}
console.log(sum(1)); // 1
console.log(sum(1, 2, 3, 4, 5)); // 15

Jest jednak jedno ALE: nie możemy posiadać więcej niż jednego parametru typu …rest. W przeciwnym razie otrzymamy błąd jak niżej:

function sum(…numbers, last) { // causes a syntax error
  var result = 0;
  numbers.forEach(function (number) {
    result += number;
  });
  return result;
}

spread

Kolejne wyrażenie, to spread, które przypomina trochę konstrukcję rest ze względu na swoją notację z trzema kropkami. Dzieli tablicę na poszczególne wartości, które przekazywane są jako osobne parametry do ciała funkcji.

Po raz kolejny zdefiniujmy funkcję sum, do której przekażemy wyrażenie typu spread:

function sum(a, b, c) {
  return a + b + c;
}
var args = [1, 2, 3];
console.log(sum(…args)); // 6

Odpowiednik takiego kodu w ES5, to:

function sum(a, b, c) {
  return a + b + c;
}
var args = [1, 2, 3];
console.log(sum.apply(undefined, args)); // 6

Zamiast więc używać funkcji apply możemy od teraz posługiwać się “rozbiciem” tablicy na osobne parametry. Rozwiązanie prostsze i według mnie również bardziej czytelne.

Ciekawostką jest fakt, że wyrażenie spread możemy łączyć ze standardowym sposobem przekazywania parametru do funkcji:

function sum(a, b, c) {
  return a + b + c;
}
var args = [1, 2];
console.log(sum(…args, 3)); // 6

Rezultat jest dokładnie taki sam jak w poprzednim przykładzie. Tym razem tablica z dwiema wartościami zostaje rozbita na dwa parametry odpowiadające ab, zaś trzecim parametrem jest liczba 3, która odpowiada zmiennej c.

ES6 – arrow functions

javascript

Kolejnym elementem standardu ECMAScript 2015 będą bez wątpienia arrow functions. Znane również jako fat functions, pozwolą tworzyć kod bez – zbędnego w wielu przypadkach – słowa kluczowego function oraz ze zbindowanym this do ciała funkcji.


Zobacz całą serię: Let-s talk about ECMAScript 2015


Syntactic sugar

(w oryginalnym artykule użyłem właśnie tego nagłówka, jako, że polski odpowiednik brzmi idiotycznie)

Spójrzmy na sygnaturę nowej składni anonimowej funkcji:

([param] [, param]) => {
 statements
}
           param => expression
(param1, param2) => { block }

, którą możemy użyć w następujący sposób:

    () => { … }            // no argument
     x => { … }            // one argument
(x, y) => { … }            // several arguments
     x => { return x * x } // block
    x => x * x             // expression, same as above
Pamiętaj: każda tak tworzona funkcja jest anonimowa!

Wyrażenia lambda w JavaScript! Wspaniale :)

Zamiast pisać:

[3, 4, 5].map(function (n) {
 return n * n;
});

możemy po prostu zrobić coś takiego:

[3, 4, 5].map(n => n * n);

Już jest dobrze, a jest coś jeszcze..

Fixed “this” = lexical “this”

Funkcja tworzona przy pomocy konstrukcji z => binduje this wewnątrz ciała funkcji w miejscu jej deklaracji, a nie użycia. Tym samym nie musimy już używać funkcji bind, call czy apply. Nie musimy również tworzyć konstrukcji typu:

var self = this;

Dla mnie to naprawdę spore ułatwienie, a przy okazji sposób na lepszą optymalizację kodu.

// ES5
function FancyObject() {
 var self = this;
 
 self.name = 'FancyObject';
 setTimeout(function () {
  self.name = 'Hello World!';
 }, 1000);
}

// ES6
function FancyObject() {
 this.name = 'FancyObject';
 setTimeout(() => {
  this.name = 'Hello World!'; // properly refers to FancyObject
 }, 1000);
}

Konstrukcja funkcji za pomocą =>, to:

  • typeof zwracające function
  • instanceof zwracające Function

, ale niestety także kilka niedogodności:

  • Tak stworzona funkcja nie może być użyta w formie konstruktora i każde jej wywołanie ze słowem new rzuci wyjątek.
  • Fixed this oznacza, że wartość zbindowana wewnątrz funkcji nie może zostać zmieniona przez cały cykl jej życia.
  • Funkcja nie może być funkcją nazwaną.
  • Nie mamy samej deklaracji funkcji, stąd nie istnieje tutaj hoisting pozwalający użyć danej funkcji przed jej inicjalizacją.

ES6  – let + const

javascript

Pierwszy temat związany z nadchodzącym ECMAScript 2015, czyli letconst. Oba pojęcia bardzo mocno związane są ze scope deklarowanych zmiennych, co postaram się pokazać w porównaniu ze sposobem deklaracji zmiennych za pomocą słowa kluczowego var.


Zobacz całą serię: Let-s talk about ECMAScript 2015


Spójrzmy wpierw jednak na przykład pokazujący użycie var i deklaracji zmiennych znanych z ES5 i wcześniej.

var a = 1;
 
if (1 === a) {
 var b = 2; 
}
 
for (var c = 0; c < 3; c++) {
 // …
}
 
function letsDeclareAnotherOne() {
 var d = 4;
}
 
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3
console.log(d); // ReferenceError: d is not defined
 
// window
console.log(window.a); // 1
console.log(window.b); // 2
console.log(window.c); // 3
console.log(window.d); // undefined
  1. Zmienna a deklarowana jest jako globalna.
  2. Zmienna b deklarowana jest wprawdzie wewnątrz bloku if, ale jest ona również widoczna poza nim.
  3. Podobnie jak deklaracja b, zmienna c deklarowana jest w bloku for, który nie ogranicza jej swoim zasięgiem.
  4. Dopiero zmienna d posiada swój własny scope, ponieważ ograniczona jest ciałem funkcji.
Variables in JavaScript are hoisted to the top!

Hoisting, to w JavaScript domyślne zachowanie w momencie deklaracji zmiennych = wynoszenie dekleracji na samą górę skryptu lub ciała funkcji.

Tym samym zmienna w języku JavaScript może być użyta zanim zostanie zainicjalizowana. Różnicę w dekleracji zmiennych, a ich inicjalizacji przedstawia poniższy przykład:

var n = 1;
 
(function () {
 console.log(n);
 var n = 2;
 console.log(n);
})();
 
console.log(n);

let

Spójrzmy teraz na nowy sposób deklaracji zmiennych, który bezpośrednio wpływa na ich zakres działania.

let a = 1;
 
if (1 === a) {
 let b = 2; 
}
 
for (let c = 0; c < 3; c++) {
 // …
}
 
function letsDeclareAnotherOne() {
 let d = 4;
}
 
console.log(a); // 1
console.log(b); // ReferenceError: b is not defined
console.log(c); // ReferenceError: c is not defined
console.log(d); // ReferenceError: d is not defined
 
// window
console.log(window.a); // 1
console.log(window.b); // undefined
console.log(window.c); // undefined
console.log(window.d); // undefined

Jest to ten sam przykład kodu, który podawałem wyżej dla ES5. Tym razem jednak widzimy różnice w wartościach, które otrzymamy w konsoli przeglądarki. Tylko zmienna a zadeklarowana została jako globalne, a wszystkie pozostałe mają zasięg blokowy.

const

W przypadku użycia const otrzymamy dokładnie takie same wyniki jak dla deklaracji zmiennych z użyciem słowa kluczowego let. const tym samym również pozwala deklarować zmienne o zasięgu blokowym. Różni się jednak od let (i var również) tym, że raz zainicjalizowana wartość zmiennej nie może zostać nadpisana. Można było się tego domyślać po nazwie const (stała).

{
 const PI = 3.141593;
 PI = 3.14; // throws “PI” is read-only
}
 
console.log(PI); // throws ReferenceError: PI is not defined

Każda próba nadpisania zmiennej utworzonej za pomocą słówka const skończy się rzuceniem wyjątku przez interpeter JavaScript.

Powyższy przykład w ES5 mógłby wyglądać następująco:

var PI = (function () {
 var PI = 3.141593;
 return function () { return PI; };
})();

ES6 – Let’s talk about ECMAScript 2015

javascript

Czas na powrót wraz z serią Let’s talk about ECMAScript 2015, którą miałem okazję tworzyć na @medium.com. Wracać tutaj nie zamierzałem, ale ostatecznie zdecydowałem, że przetłumaczę wszystkie artykuły na język polski, a tym samym wniosę trochę świeżości na bloga.


Zobacz całą serię: Let-s talk about ECMAScript 2015


Oficjalna specyfikacja ECMAScript 2015 niedawno ujrzała światło dzienne i tym samym przygoda z ES6 zaczyna stanowić codzienność w JavaScriptowym świecie.

ES6 to znacząca zmiana dla języka JavaScript. Poprzednia wersja istnieje na rynku od 2009 roku. W tym czasie pojawiły się (i / lub rozwijały) frameworki takie jak AngularJS, Backbone, Ember, Meteor, Aurelia, ReactJS, Ionic i wiele innych. Ich kolejne wersje będą już wykorzystywać dobrodziejstwa, które oferuje standard ECMAScript 2015.

ECMAScript 2015 to szereg nowości:

  • arrows
  • classes
  • enhanced object literals
  • template strings
  • destructuring
  • default + rest + spread
  • let + const
  • iterators + for..of
  • generators
  • unicode
  • modules
  • module loaders
  • map + set + weakmap + weakset
  • proxies
  • symbols
  • subclassable built-ins
  • promises
  • math + number + string + object APIs
  • binary and octal literals
  • reflect api
  • tail calls

Celowo zachowuję tutaj angielskie nazewnictwo, ponieważ tytuły kolejnych wpisów będą je odzwierciedlać. Znaczącą większość zakresu udało mi się opisać na bazie draftu specyfikacji, który istniał przed pojawieniem się oficjalnej wersji.

Producenci przeglądarek są na dobrej drodze, by z czasem w pełni wspierać nowy standard. Natomiast dzisiaj, dzięki takim narzędziom jak Babel, czy Traceur, możemy w dużej mierze korzystać z możliwości ES6 już teraz.

Zobacz: aktualne wsparcie przeglądarek dla ES6.

Wielokrotnie podkreślałem w swoich artykułach stwierdzenie: Future is bright. Jesteśmy na dobrej drodze by wypchnąć JavaScript na kolejny poziom.


ECMAScript 2015 - Let's talk about ES6

PS. Na bazie serii powstała również książka ECMAScript 2015 – Let’s talk about ES6, którą możecie poczytać ZA DARMO ONLINE.

Reorganizacja i przenosiny na @medium.com

medium.com

Jakiś czas temu postanowiłem sobie, że zacznę pisać po angielsku, bo:

  • Przecież nikt nie czyta treści związanych z IT po polsku (A czyta? Mi się zdarza, ale w 99% zaglądam raczej do anglojęzycznych źródeł);
  • Chcę dotrzeć do większej społeczności (Głównie chodzi o komentarze i wymianę opinii);
  • Chcę odbudować, a potem dalej rozwijać swoje umiejętności językowe (Nie mam na to szans na co dzień, więc warto postawić przed sobą wyzwanie).

Postanowienie zacząłem przekuwać w działanie. Zarejestrowałem domenę, znów postawiłem bloga od zera, wykorzystując w tym celu dobrze sobie znaną platformę Wordpress. Zrobiłem wszystko, by tylko upodobnić całość do mojego ulubionego serwisu @medium.com. I co? I nie napisałem tam ani jednego wpisu. Mógłbym się tłumaczyć dlaczego, ale przecież nie o to chodzi. Przemyślałem tym samym sprawę i skupię się na tym, na czym zależy mi najbardziej.. na pisaniu. Wtedy gdy będę miał na to czas, ochotę i pomysł. Ot i tyle.

Jeżeli zamierzacie śledzić mnie dalej, to zapraszam na profil: @mrzepinski Już niedługo pojawi się tam seria wpisów o ECMAScript 2015 (ES6).

Niniejszą domenę postaram się utrzymać, ale po nowe wpisy zapraszam jednak do nowego miejsca. Mam też nadzieję, że Wam się spodoba.

70-480 – Tworzenie struktury pliku CSS przy użyciu selektorów CSS

70-480

Prawidłowe odwołania do elementów; wdrażanie dziedziczenia; zastępowanie dziedziczenia przez stosowanie dyrektywy !important, określanie stylu elementów na podstawie pseudo-elementów i pseudo-klas (np. :before, :first-line, :first-letter, :target, :lang, :checked, :first-child).



To już ostatni wpis poświęcony egzaminowi 70-480, a o większości elementów wymienionych w opisie podrozdziału wspominałem w poprzednim artykule. Opowiem dziś zatem tylko o dziedziczeniu w CSS oraz nadpisywaniu styli.

Dziedziczenie w CSS

Dziedziczenie w CSS możliwe jest za pomocą selektorów zależnych, o których była pokrótce mowa w poprzednim wpisie.

Spójrzmy na przykład (zerknij na strukturę HTML, a potem style CSS):

[wp-js-fiddle url="https://jsfiddle.net/mrzepinski/652nc16u/1/" style="width:100%;height:400px;border:solid #4173A0 1px;"]

Kontenerowi div ustawiony został styl, który nadaje czerwony kolor dla tekstu. Następnie wykorzystano selektor zależny div p, który dodatkowo zwiększa czcionkę oraz dodaje podkreślenie tekstu dla elementów p, które znajdują się bezpośrednio wewnątrz div. W strukturze HTML mamy dwa krótkie teksty – pierwszy bezpośrednio w elemencie blokowym div, a drugi w paragrafie. Rezultatem jest czerwony kolor tekstu znajdującego się bezpośrednio w bloku div oraz również czerwony kolor tekstu znajdujący się w paragrafie oraz dodatkowo większa czcionka i podkreślenie. Widać wyraźnie, że kolor czerwony dla tekstu, ustawiony dla elementu nadrzędnego jest dziedziczony przez elementy znajdujące się wewnątrz struktury, które nie nadpisały tego stylu.

Więcej szczegółów w specyfikacji W3C: http://www.w3.org/TR/CSS21/cascade.html

Nadpisywanie styli CSS

Spójrzmy od razu na przykład (zerknij na strukturę HTML, a potem style CSS):

[wp-js-fiddle url="https://jsfiddle.net/mrzepinski/652nc16u/2/" style="width:100%;height:400px;border:solid #4173A0 1px;"]

Widzimy tutaj, że dla elementu div.container ustawiony został kolor tekstu na czerwony. W środku znajduje się kolejny element div.inside, który ma ustawiony kolor tekstu na niebieski. Tekst, który znajduje się poza tym wewnętrznym elementem div posiada rzeczywiście kolor czerwony, a tekst znajdujący się wewnątrz elementu .inside posiada kolor niebieski.

By wymusić styl również dla elementów podrzędnych wykorzystać możemy wyrażenie !important. Nie powinno być ono jednak nadużywane i najlepiej jest go unikać i tworzyć właściwą strukturę HTML, która nie będzie wymagała takich rozwiązań.

Spójrzmy na przykład wymuszenia stylu dla elementów podrzędnych. Jest to ten sam przykład, co wyżej, z tą różnicą, że tym razem dla bloku .container nałożony został styl, który zawiera wyrażenie !important:

[wp-js-fiddle url="https://jsfiddle.net/mrzepinski/652nc16u/3/" style="width:100%;height:400px;border:solid #4173A0 1px;"]

Podsumowanie

I to byłoby na tyle :) Powodzenia w przygotowaniach do egzaminu 70-480 i na samym egzaminie. Jest to dopiero początek drogi w wielkim świecie WWW.

70-480 – Wyszukiwanie elementów przy użyciu selektorów arkusza CSS i kwerendy jQuery

70-480

Wybór odpowiedniego selektora w celu odwołania do elementu; definiowanie selektorów elementu, stylu i atrybutu; wyszukiwanie elementów przy użyciu pseudo-elementów i pseudo-klas (np. :before, :first-line, :first-letter, :target, :lang, :checked, :first-child).



Przedostatnim tematem dotyczącym egzaminu 70-480 będzie biblioteka jQuery. Nakłada ona na czysty język JavaScript (Vanilla) pewną warstwę abstrakcji oraz udostępnia API, które nie dość tego, że jest znacznie bogatsze i prostsze niż standardowe metody dostępu do elementów DOM, to wspiera wiele różnych wersji przeglądarek. Każdy kto zetknął się z pisaniem kodu JavaScript z pewnością słyszał o jQuery, więc dzisiejszy wpis będzie krótki, lecz treściwy.

Selektory CSS

Wyszukiwanie elementów jQuery jest bardzo podobne do nakładania styli poprzez stosowanie selektorów dostępnych w CSS. Spójrzmy na te podstawowe:

  • * – pobranie wszystkich elementów
  • #id – id elementu (pamiętajmy, że tylko jeden element na stronie może posiadać takie samo id)
  • .class – wszystkie elementy, które posiadają klasę class
  • .class1, .class2 – wszystkie elementy, które  mają ustawioną klasę class1 lub class2

Dzięki selektorom zależnym jesteśmy w stanie odwoływać się do poszczególnych elementów, które znajdują się w pewnej hierarchii względem innych elementów:

  • parent child – wszystkie elementy child, które są potomkami elementu parent, bez względu na stopień pokrewieństwa
  • parent > child – to samo co wyżej, ale w tym wypadku elementy child muszą być bezpośrednimi potomkami parent
  • element + next-element – wybranie elementu next-element, który występuje zaraz za elementem element
  • element ~ siblings – wszystkie elementy siblings, które są rodzeństwem dla element

Możemy również odwoływać się do poszczególnych atrybutów, a nawet ich wartości:

  • [attr=] – znak równości, więc wartość atrybutu musi równać się podanemu wyrażeniu
  • [attr!=…] – wartość atrybutu różna od podanego wyrażenia
  • [attr$=…] – wartość atrybutu kończyć się musi według podanego wyrażenia
  • [attr^=…] – wartość atrybutu zaczynać się musi według podanego wyrażenia
  • [attr~=…] – wartość atrybutu zawierać musi podane słowo
  • [attr*=…] – wartość atrybutu zawierać musi podane znaki

Mamy poza tym szereg pseudo-selektorów. Najpopularniejsze z nich to:

  • :hover – element wskazywany właśnie przez wskaźnik myszy
  • :focus – element, który aktualnie jest aktywny
  • :first-child – pierwsze dziecko danego elementu
  • :odd – wszystkie nieparzyste elementy w liście
  • :even – wszystkie parzyste elementy w liście
  • :disabled – wyłączonynieaktywny element

Pełna lista selektorow CSS na stronie w3schools.com – http://www.w3schools.com/cssref/css_selectors.asp

Wyszukiwanie elementów DOM przy pomocy jQuery

Podobnie sprawa wygląda w jQuery. Mają co dyspozycji utworzony obiekt jQuery / $ jesteśmy w stanie bardzo szybko wyłuskiwać poszczególne elementy ze struktury HTML.

// id
$('#myId');

// klasa
$('.myClass');

// atrybut
$('input[name="first_name"]');

// zagnieżdżone elementy
$('#contents ul.people li');

// pseudo - selektory
$('a.external:first');
$('tr:odd');
$('#myForm:input');
$('div:visible');
$('div:gt(2)');
$('div:animated');

Pełna lista dostępnych selektorów jQuery: http://api.jquery.com/category/selectors/

Na w3schools.com znajdziemy też ciekawe demo, które w interaktywny sposób unaoczni nam możliwości jQuery jeśli chodzi o znajdowanie elementów w strukturze HTML: http://www.w3schools.com/jquery/trysel.asp

70-480 – Tworzenie animowanego i adaptacyjnego interfejsu użytkownika

70-480

Animacja obiektów poprzez stosowanie przejść CSS; stosowanie przekształceń 3-D i 2-D; dostosowywanie interfejsu użytkownika na podstawie kwerend dotyczących nośników (dostosowywanie urządzeń do formatów wyjściowych, rozwiązań do wyświetlania i prezentowania informacji), ukrywanie lub wyłączanie elementów sterujących.



Tytuł oraz opis materiału dzisiejszego wpisu zaczerpnięte z oficjalnego przewodnika do egzaminu 70-480 nie są być może zbyt czytelne i zrozumiałe. Jest to część poświęcona transformacjom CSS (2D oraz 3D) oraz @media queries.

CSS3 transitions

Dzięki CSS3 jesteśmy w stanie zdefiniować przejścia / animacje bez użycia Flash, czy JavaScript. Dzieje się tak za sprawą właściwości transition, która pozwala pokazać przejście z jednego stylu w inny. Tworzone animacje można łączyć z właściwościami translate oraz transform, o czym pisałem już wcześniej.

Dzięki właściwości transition jesteśmy w stanie wskazać jaką inną właściwość chcemy animować oraz przez jak długi czas. Tym samym musimy podać dwa argumenty:

  • właściwość, którą chcemy animować
  • czas animacji – bez podania czasu nie zobaczymy animacji, bo wartość domyślnie ustawiona będzie na 0

Spójrzmy na przykład animacji zmiany wysokości elementu blokowego, która trwać będzie jedną sekundę: transition: height 1s. Wystarczy, że najedziemy na poniższy czerwony prostokąt by zobaczyć efekt.

[wp-js-fiddle url="https://jsfiddle.net/mrzepinski/299ms1rq/" style="width:100%;height:400px;border:solid #4173A0 1px;"]

Należy pamiętać, że np. przeglądarka Internet Explorer 9 nie wspiera własności: transiton. Pełny wykaz wsparcia: http://caniuse.com/#feat=css-transitions

Efekty możemy również łączyć, podając kolejne wartości po przecinku. Spójrzmy zatem na przykład animacji zarówno wysokości jak i szerokości: transition: height 1s, width 2s z tą różnicą, że efekt animacji dla zmiany wysokości elementu potrwa jedną sekundę, a zmiana szerokości elementu dwie sekundy.

[wp-js-fiddle url="https://jsfiddle.net/mrzepinski/299ms1rq/1/" style="width:100%;height:400px;border:solid #4173A0 1px;"]

Własność transition rozbita została na kilka różnych własności, które podawać możemy niezależnie:

  • transition-property – jaką własność chcemy animować
  • transition-duration – przez jaki czas
  • transition-timing-function – jaką funkcję czasu chcemy użyć w stosunku do prędkości oraz czasu animacji (ease, linear, ease-in, ease-out, ease-in-out, step-start, step-end, cubic-bezier)
  • transition-delay – opóźnienie w wywołaniu animacji

Wszystkie cztery wartości możemy oczywiście połączyć w jedno: transition. Spójrzmy na przykład dwóch takich samych animacji utworzonych na dwa róże sposoby.

[wp-js-fiddle url="https://jsfiddle.net/mrzepinski/299ms1rq/2/" style="width:100%;height:400px;border:solid #4173A0 1px;"]

Jeśli chodzi o funkcje czasu, to świetnie opisano i pokazano to na stronie: http://www.the-art-of-web.com/css/timing-function/

Różnymi opcjami możemy eksperymentować ponownie na tech demo przygotowanym przez Microsoft: http://ie.microsoft.com/testdrive/graphics/hands-on-css3/hands-on_transitions.htm

Transformacje CSS3 2D

O transformacja 2D pisałem już w jednym z pierwszych wpisów: 70-480 – Programowe stosowanie stylów do elementów HTML

Transformacje CSS3 3D

Spójrzmy najpierw na przykład:

[wp-js-fiddle url="https://jsfiddle.net/mrzepinski/299ms1rq/3/" style="width:100%;height:400px;border:solid #4173A0 1px;"]

Widzimy tutaj wykorzystanie animacji za pomocą własności transition, która określona została dla własności transform. To własnie ta własność powoduje, że możemy manipulować elementami blokowymi, wykorzystując w tym celu następujące funkcje:

  • rotateX (angle) – obrót wokół osi X
  • rotateY (angle) – obrót wokół osi Y
  • rotateZ (angle) – obrót wokół osi Z
  • rotate3d (x, y, z, angle) – obrót wokół wektora definiowanego przez parametry x, y, z
  • scaleX (x) – skalowanie wzdłuż osi X
  • scaleY (y) – skalowanie wzdłuż osi Y
  • scaleZ (z) – skalowanie wzdłuż osi Z
  • scale3d (x, y, z) – skalowanie wzdłuż wektora definiowanego przez parametry x, y, z
  • translateX (x) – przesunięcie wzdłuż osi X
  • translateY (y) – przesunięcie wzdłuż osi Y
  • translateZ (z) – przesunięcie wzdłuż osi Z
  • translate3d (x, y, z) – przesunięcie wzdłuż wektora definiowanego przez parametry x, y, z
  • perspective (n) – definicja perspektywy
  • matrix3d (n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n) – mix wszystkiego powyżej, poszczególne wartości odpowiadają odpowiednim przekształceniom

Oprócz własności transform, wyróżniamy także:

Tutaj również przychodzi nam z pomocą demo od Microsoft:  http://ie.microsoft.com/testdrive/graphics/hands-on-css3/hands-on_3d-transforms.htm

CSS3 @media queries

W kontekście własności / atrybutu @media można napisać bardzo wiele. Atrybut (html) / własność (CSS) ten / ta służy do definiowania (w uproszczeniu) różnych rodzajów styli w zależności od urządzenia, które wyświetla stronę oraz od rozdzielczości dostępnej na ów urządzeniu.

Świetny, a zarazem krótki artykuł, który to opisuje znalazłem na css-tricks.com i pozwolę sobie odesłać Was do niego: Logic in Media Queries

Pokazywanie i ukrywanie elementów za pomocą CSS

O tym również pisałem już wcześniej: 70-480 – Programowe stosowanie stylów do elementów HTML