Nadszedł czas na drugą część opisującą elastyczne interfejsy CSS3 (oczywiście nadal w ramach przygotowań do egzaminu 70-480 należącego do ścieżki certyfikacyjnej MCSD Web Applications). Wpis ten poświęcony będzie takim zagadnieniom jak opływanie elementów blokowych, wyrównywanie do siatki oraz definiowanie regionów. Myślę, że nie ma sensu tracić czasu na przydługie wstępy, przejdźmy więc do rzeczy!

Opływanie elementów blokowych

Myślę, że temat definiowania opływania elementów blokowych za pomocą właściwości ‘float’ jest wszystkim dość dobrze znany, dlatego tytułem wstępu tylko małe przypomnienie. Dotychczas, za pomocą wspomnianej właściwości ‘float’ możliwe było zdefiniowanie opływania elementu blokowego w ten sposób, że tekst lub inne elementy opływały go z prawej strony (ustawienie “float: left” dla elementu blokowego) lub z lewej strony (ustawienie “float: right” elementu blokowego). Pamiętamy też, że aby zakończyć opływanie można było użyć właściwości “clear”. I to w zasadzie wszystkie dostępne wcześniej możliwości definiowania takiego zachowania elementów.

Jednak w CSS3 wprowadzona została nowa możliwość określania opływania, za pomocą “wykluczeń” (ang. exclusions) - tak jak w przypadku modelu “flexbox” w artykule tym skupie się na implementacji tego mechanizmu w IE10 dlatego wszystkie opisywane tutaj właściwości posiadać będą przedrostek “-ms-“. Oczywiście aby zapewnić prawidłowe działanie strony wykorzystującej “wykluczenia” należy dodać też ustawienia tych właściwości z innymi przedrostkami o ile takowe są obsługiwane.

Zanim zaczniemy omawianie “wyłączeń”, spójrzmy na kod HTML, który będzie podstawą kolejnych przykładów:

<div id="container">
    <p>... jakiś długi tekst ...</p>
    <div id="box"></div>
</div>

Za pomocą tak utworzonego kodu HTML, będziemy chcieli uzyskać efekt opływania elementu o identyfikatorze “box” przez tekst zawarty w paragrafie. Zapewne wielu z Was od razu widzi, że aby to uzyskać, trzeba będzie ustawić elementowi blokowemu właściwość ‘position’ na wartość ‘absolute’ i odpowiednio odsunąć go od krawędzi kontenera za pomocą właściwości np. ‘top’ oraz ‘left’. Poniższe style CSS zawierają wszystkie potrzebne ustawienia do uzyskania odpowiedniego efektu:

#container {
    width: 300px;
    height: 300px;

    background: grey;
}

#box {
    width: 80px;
    height: 80px;

    background: red;

    position: absolute;
    left: 100px;
    top: 120px;

    -ms-wrap-flow: both;
}

Objaśnienie

Myślę, że większość powyższych ustawień jest jasna. Mamy kontener, zawierający tekst oraz czerwony kwadrat, który dzięki pozycjonowaniu “absolute” znajduje się jakby nad tekstem. I teraz do gry wchodzi właściwość ‘-ms-wrap-flow’ (linia osiemnasta). W momencie kiedy ustawiliśmy jej wartość na ‘both’, tekst znajdujący się pod kwadratem, nagle go “zauważa” i zamiast chować się pod nim zaczyna go opływać z obu stron! Efekt zobaczyć możemy na poniższym zrzucie ekranu (celowo umieszczam tutaj zrzut aby można było zaobserwować efekt we wszystkich przeglądarkach):

przykład

Oczywiście właściwość ‘-ms-wrap-float’ ma również inne możliwości ustawień. Poniżej lista wszystkich:

  • auto - ustawienie domyślne; brak opływania
  • both - opływanie ze wszystkich stron, tak jak w przykładzie
  • start - opływanie tylko od strony startowej/lewej wyłączenia, od strony końcowej/prawej pusta przestrzeń
  • end - odwrotność ustawienia ‘start’ - od strony startowej/lewej pusta przestrzeń, od strony końcowej/prawej opływanie
  • maximum - podobny do dwóch wcześniejszych - opływanie od strony, która pozwala na zapełnienie większej przestrzeni, przeciwną stronę pozostawiając pustą
  • clear - wyłącza zarówno prawą jak i lewą stronę - czyli de facto opływanie tylko od góry i od dołu

Opływaniem możemy również sterować z punktu widzenia elementu opływającego, tzn. w jego kontekście (w przykładzie jest to element <p>) możliwe jest ustawienie właściwości ‘-ms-wrap-through’. Domyślnie ma ona ustawioną wartość ‘wrap’, możemy jednak, ustawić jej także wartość ‘none’ dzięki czemu opływanie zostanie wyłączone.

Jest jeszcze jedna właściwość dotycząca “wyłączeń”. Chodzi o ‘-ms-wrap-margin’ - ustawiamy ją w kontekście opływanego elementu blokowego, a pozwala ona na ustawienie dodatkowego marginesu wokół tego elementu, dzięki czemu możemy odsunąć pływającą treść od niego. ‘-ms-wrap-margin’ może przyjmować standardowe wartości jakie przypisać możemy zwykłemu marginesowi (‘px’, ‘em’, ‘pt’ itp).

Wyrównywanie do siatki

Kolejną nowością dostępną w CSS3 jest możliwość definiowania siatek (ang. grid) oraz określania przynależności elementów do poszczególnych komórek siatki. Tutaj znów różne przeglądarki posiadają różne implementacje tego mechanizmu, dlatego na potrzeby egzaminu 70-480, skupię się tylko na implementacji w IE10 - dlatego w przykładach posługiwać się będę właściwościami z przedrostkiem ‘-ms-‘.

Kontener

Najlepiej będzie przedstawić to zagadnienie na przykładzie, dlatego od tego zacznijmy. Poniżej przykładowy HTML:

<div id="container">
    <div id="box1"></div>
    <div id="box2"></div>
</div>

Mamy tutaj prosty kontener, zawierający dwa elementy blokowe - będziemy chcieli je rozmieścić według zdefiniowanej siatki. Na początek zdefiniujmy więc samą siatkę, robi się to w kontekście kontenera:

#container {
    width: 300px;
    height: 300px;

    background: grey;

    display: -ms-grid;
    -ms-grid-columns: 80px 100px;
    -ms-grid-rows: 80px 100px;
}

Pierwsze linie tego definicji styli dla elementu o identyfikatorze ‘container’ są myślę oczywiste. To co ciekawe zaczyna się linii siódmej - aby zadeklarować siatkę, należy przypisać do właściwości ‘display’ wartość ‘-ms-grid’. Kolejne dwa ustawienia to definicja kolumn i wierszy. W powyższym przykładzie mamy definicję dwóch kolumn: pierwsza o szerokości 80px oraz druga o szerokości 100px. Następnie widzimy definicję wierszy: podobnie, pierwsza kolumna o wysokości 80px i druga o wysokości 100px.

Wszystkie sposoby definiowania kolumn i wierszy

W tym miejscu się na chwilę zatrzymajmy i przyjrzyjmy się wszystkim dostępnym sposobom definiowania kolumn i wierszy. Jak widać z przykładu, kolejne kolumny i wiersze definiuje się poprzez podanie ich odpowiednich rozmiarów. Jeśli chcielibyśmy mieć więcej kolumn, musimy odpowiednio więcej ustawień przypisać do właściwości (są możliwe także skróty ale o tym za moment). Oprócz konkretnych wartości (tutaj w pikselach), możliwe jest przypisanie do tych właściwości poniższych wartości:

  • standardowe jednostki długości (‘px’, ‘em’, ‘pt’ itd)
  • auto - szerokość lub wysokość ustalana jest na podstawie rozmiaru elementów wewnętrznych
  • min-content - najmniejsza z szerokości lub wysokości elementów wewnętrznych
  • max-content - największa z szerokości lub wysokości elementów wewnętrznych
  • minmax(a, b) - funkcja pozwalająca określić zakres spomiędzy którego ma być ustalona szerokość lub wysokość
  • jednostki części - ang. fraction units; szerokość lub wysokość ustalana jest na podstawie dostępnego miejsca, np. ustawienie “1fr 2fr” oznacza, że pierwsza kolumna/wiersz zabiera 1/3 dostępnego miejsca a druga 2/3.

Wspomniałem wcześniej o skrótowej opcji zapisu - w przypadku gdy mamy wiele kolumn z powtarzającymi się ustawieniami, na przykład “10px 250px 10px 250px”, zamiast takiego zapisu możemy napisać “(10px 250px)[2]”. Myślę, że jest to przydatne przy wielu takich samych kolumnach/wierszach.

Style dla elementów

Wracamy do przykładu. Mając zdefiniowaną siatkę, należy teraz określić przynależność poszczególnych elementów do jej komórek. W naszym kodzie HTML widzieliśmy, że w kontenerze znajdują się dwa elementy blokowe. Spójrzmy zatem na ich style CSS:

#box1 {
    width: 80px;
    height: 80px;

    background: red;

    -ms-grid-column: 1;
    -ms-grid-row: 1;
}

#box2 {
    width: 100px;
    height: 100px;

    background: yellow;

    -ms-grid-column: 2;
    -ms-grid-row: 2;
}

Jak widać, element o identyfikatorze “box1” przynależy do kolumny numer 1 i wiersza numer 1 (patrz linie siedem i osiem) natomiast drugi element, ten o id “box2” należy do kolumny 2 i wiersza 2 (linie siedemnaście oraz osiemnaście). Takie ostylowanie daje następujący efekt (ponownie zrzut ekranu, tak aby efekt można było zobaczyć we wszystkich przeglądarkach):

przykład

Jeśli chodzi o ustawienia styli elementów należących do poszczególnych komórek siatki, to mamy jeszcze kilka możliwości konfiguracji. Mamy na przykład możliwość określania wyrównania elementów - szczególnie przydatne, gdy elementy mają inne rozmiary niż komórki. Do wyrównania elementów w kontekście kolumn i wierszy służą odpowiednio właściwości ‘-ms-grid-column-align’ oraz ‘-ms-grid-row-align’. Można im przypisać właściwości takie jak “cener”, “start”, “end” oraz “stretch” - myślę, że ich nazwy mówią same za siebie ;)

Ostatnią możliwością jest definiowanie rozpiętości elementów na więcej niż jedną komórkę (ang. span). Służą do tego właściwości ‘-ms-grid-column-span’ dla kolumn oraz ‘-ms-grid-row-span’ dla wierszy. Jako właściwość podajemy im po prostu wartość liczbową określającą na ile kolumn lub wierszy ma się rozciągać dany element (domyślną wartością jest “1”).

Tutaj mała uwaga. Jeśli na przykład mamy zdefiniowane dwie kolumny, a elementowi wewnętrznemu, który znajduje się w pierwszej kolumnie ustawimy rozciąganie na trzy kolumny, automatycznie zostanie dodana trzecia kolumna, a jej rozmiar ustawiony zostanie na wartość “auto”!

Klikalną wersję powyższego przykładu znaleźć możecie na jsfiddle.net.

Definiowanie regionów

W ostatnim poruszanym dziś temacie, zajmiemy się regionami. Ten element CSS3 pozwala nam na definiowanie kontenerów zwanych właśnie regionami, które mogą być porozrzucane po całym dokumencie HTML. Ich główną zaletą jest to, że mogą one współdzielić treść, dzięki czemu możliwe jest tworzenie interfejsów użytkownika podobnych na przykład do układu znanego nam z gazet i magazynów.

IFrame

Definiowanie regionów jest bardzo proste. Na początek należy zdefiniować element <iframe>, w którym definiujemy źródło współdzielonej treści. Spójrzmy na przykład:

<iframe id="data-source" src="content.aspx" />

Widzimy wskazanie na stronę “content.aspx” jako źródło treści. Następnie dla powyższego elementu definiujemy styl CSS określający go jako źródło treści dla regionów:

#data-source {
  -ms-flow-into: flowToken;
}

Elementowi <iframe> z naszego przykładu ustawiamy wartość właściwości ‘-ms-flow-into’. Możemy przypisać do niej jakąkolwiek wartość tekstową, ponieważ stanowi ona “token” oznaczający dane źródło danych. Ustawienie tej wartości elementowi <iframe> powoduje, że jego “display” ustawiany jest na “none” i nie jest on w żaden sposób wyświetlany na ekranie.

Regiony

Kolejna sprawa to same regiony. Mogą to być na przykład zwykłe elementy blokowe <div>, które za pomocą odpowiednich styli rozmieszczone są w jakiś “fikuśny” sposób na stronie. Spójrzmy na poniższy przykład:

<div class="region"></div>
<div class="region"></div>
<div class="region"></div>

To co w tym przykładzie jest ważne, to że wszystkie powyższe elementy blokowe mają tę samą klasę CSS. Spójrzmy więc na jej definicję:

.region {
  -ms-flow-from: flowToken;
}

Myślę, że teraz wszystko jest jasne - wszystkie elementy mające przypisaną tę klasę współdzielą zdefiniowany wcześniej “token” dzięki czemu wiadomo, że dzielą się zawartością pochodzącą ze źródła zdefiniowanego w elemencie <iframe>. Teraz treść ze źródła powędruje najpierw do pierwszego z “regionów”, wypełni go maksymalnie, a gdy zabraknie miejsca, dalszy jej ciąg pojawi się w kolejnym “regionie” itd.

Dobrym pomysłem jest użycie regionów wraz z przyciąganiem do siatki, dzięki czemu można łatwo sterować rozmieszczeniem poszczególnych “regionów” na stronie.

Elastyczne interfejsy CSS3 - podsumowanie

To tyle na dziś, mam nadzieję, że ten i poprzedni post w pełni wyjaśniły Ci elastyczne interfejsy CSS3. W kolejnym wpisie zajmę się tworzeniem animacjami w interfejsie użytkownika. Jak zwykle zapraszam!