Układ strony w internecie jak w formacie typowym dla czasopism z wykluczeniami i regionami CSS

Christian Cantrell
Christian Cantrell

Wprowadzenie

Internet to niezwykle zaawansowana platforma do pracy z tekstem, a Adobe ma w tej dziedzinie ogromne doświadczenie i wiedzę. Gdy firma Adobe szukała sposobów na rozwój internetu, dalsze rozwijanie możliwości związanych z tekstem wydawało się oczywistym punktem wyjścia. W internecie tekst jest zwykle wyświetlany w jednej kolumnie i w orientacji pionowej. Chociaż możliwe jest opływanie grafiki przez tekst, a nawet formatowanie tekstu w kilku kolumnach za pomocą CSS, nadal bardzo trudno jest uzyskać w internecie układ przypominający prawdziwy magazyn. Dzięki regionom CSS i wykluczeniom CSS firma Adobe jest liderem w dziedzinie wprowadzania możliwości DTP do nowoczesnych przeglądarek. Na przykład na zrzucie ekranu poniżej wykluczenia CSS są używane do przepływu tekstu wzdłuż konturu góry:

Przykład wykluczeń CSS w działaniu
Przykład wykluczeń CSS w działaniu

W dokumencie na zrzucie ekranu poniżej użyto też wykluczeń CSS, aby umożliwić zawijanie tekstu wokół kształtów na obrazach, oraz regionów CSS, aby sformatować tekst w kolumnach i wokół cytatu:

Przykład regionów CSS w działaniu
Przykład działania regionów CSS

Regiony usług porównywania cen

Zanim przejdziemy do szczegółów regionów CSS, chciałbym omówić, jak można je włączyć w Google Chrome. Po włączeniu regionów CSS możesz wypróbować niektóre przykłady wymienione w tym artykule i utworzyć własne.

Włączanie regionów CSS w Google Chrome

Od wersji 20 Chrome (dokładnie od wersji 20.0.1132.57) regiony CSS są włączone w interfejsie chrome://flags. Aby włączyć regiony CSS, wykonaj te czynności:

  1. Otwórz nową kartę lub nowe okno w Chrome.
  2. Wpisz chrome://flags na pasku lokalizacji.
  3. Użyj funkcji znajdź na stronie (Ctrl/Cmd + F) i wyszukaj sekcję „Eksperymentalne funkcje platformy internetowej”.
  4. Kliknij link Włącz.
  5. Kliknij przycisk Uruchom ponownie teraz u dołu.

Więcej informacji o flagach Chrome znajdziesz w moim poście na blogu Wszystko o flagach Chrome.

Po ponownym uruchomieniu przeglądarki możesz zacząć eksperymentować z regionami CSS.

Omówienie regionów CSS

Regiony CSS umożliwiają automatyczne umieszczanie bloków tekstu z oznaczeniami semantycznymi w „polach” (obecnie elementach). Diagram poniżej przedstawia oddzielenie tekstu (przepływu) i pól (regionów, do których przepływa tekst):

Treści są kierowane do określonych regionów.
Treść jest umieszczana w zdefiniowanych regionach

Przyjrzyjmy się rzeczywistemu przypadkowi użycia regionów CSS. Oprócz pracy jako programista w Adobe piszę też powieści science fiction. Często publikuję swoje prace online na licencji Creative Commons. Aby zapewnić ich działanie na jak największej liczbie urządzeń i przeglądarek, często używam bardzo prostego formatu, podobnego do tego:

Przykład projektu Human Legacy bez stylów
Przykład projektu Human Legacy bez stylów

Dzięki regionom CSS udało mi się stworzyć coś, co jest zarówno ciekawsze wizualnie, jak i znacznie bardziej funkcjonalne, ponieważ łatwiej się po tym poruszać i wygodniej czytać:

Human Legacy Project z wyświetlonym regionem
Projekt Human Legacy z regionami.

W celach demonstracyjnych dodałem w tym prototypie możliwość wyświetlania regionów CSS. Zrzut ekranu poniżej pokazuje, jak regiony są ułożone, aby sprawiały wrażenie kolumn, które otaczają grafikę i cytat w środku:

Human Legacy Project z regionami
Human Legacy Project z widocznymi regionami

Możesz eksperymentować z tym prototypem (oraz wyświetlić kod źródłowy) tutaj. Do nawigacji użyj klawiszy strzałek, a następnie naciśnij klawisz Esc, aby wyświetlić regiony. Wcześniejsze prototypy są też dostępne tutaj.

Tworzenie przepływu z nazwą

Kod CSS wymagany do przepływu bloku tekstu przez regiony jest bardzo prosty. Poniższy fragment kodu przypisuje nazwany przepływ o nazwie „article” do elementu div o identyfikatorze „content” i ten sam nazwany przepływ „article” do dowolnego elementu z klasą „region”. W rezultacie tekst zawarty w elemencie „content” będzie automatycznie przepływać przez dowolny element z klasą „region”.

<!DOCTYPE html>
<html>
<head>
    <style>
    #content {
        { % mixin flow-into: article; % }
    }

    .region {
        { % mixin flow-from: article; % }
        box-sizing: border-box;
        position: absolute;
        width: 200px;
        height: 200px;
        padding: 10px;
    }

    #box-a {
        border: 1px solid red;
        top: 10px;
        left: 10px;
    }

    #box-b {
        border: 1px solid green;
        top: 210px;
        left: 210px;
    }

    #box-c {
        border: 1px solid blue;
        top: 410px;
        left: 410px;
    }
    </style>
</head>
<body>
    <div id="box-a" class="region"></div>
    <div id="box-b" class="region"></div>
    <div id="box-c" class="region"></div>
    <div id="content">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent eleifend dapibus felis, a consectetur nisl aliquam at. Aliquam quam augue, molestie a scelerisque nec, accumsan non metus. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin cursus euismod nisi, a egestas sem rhoncus eget. Mauris non tortor arcu. Pellentesque in odio at leo volutpat consequat....
    </div>
</body>
</html>

Wynik wygląda tak:

Wynik powyższego kodu
Wynik powyższego kodu

Zwróć uwagę, że tekst w elemencie div „content” nie zawiera żadnych informacji o swojej prezentacji. Innymi słowy, może zachować nienaruszoną semantykę, nawet gdy przepływa przez różne regiony. Dodatkowo, ponieważ regiony są tylko elementami, ich położenie i rozmiar są określane za pomocą CSS, tak jak w przypadku każdego innego elementu, dzięki czemu są one w pełni zgodne z zasadami elastycznego projektowania stron. Oznaczenie elementów jako części nazwanego przepływu oznacza po prostu, że określony tekst automatycznie przez nie przepływa.

Model obiektowy CSS

Model obiektowy CSS (CSSOM) definiuje interfejsy API JavaScriptu do pracy z CSS. Poniżej znajdziesz listę nowych interfejsów API związanych z regionami CSS:

  • document.webkitGetNamedFlows(): funkcja, która zwraca kolekcję nazwanych przepływów dostępnych w dokumencie.
  • document.webkitGetNamedFlows().namedItem("article"): funkcja, która zwraca odwołanie do konkretnej nazwanej automatyzacji. Argument odpowiada nazwie określonej jako wartość właściwości CSS flow-into i from-from. Aby uzyskać odwołanie do nazwanego przepływu określonego w powyższym fragmencie kodu, należy przekazać ciąg znaków „article”.
  • WebKitNamedFlow: obiektowa reprezentacja nazwanego floe z tymi właściwościami i funkcjami:
    • firstEmptyRegionIndex: liczba całkowita, która wskazuje indeks pierwszego pustego regionu powiązanego z nazwanym przepływem. Aby dowiedzieć się, jak uzyskać kolekcję regionów, zobacz getRegions() poniżej.
    • name: wartość ciągu tekstowego z nazwą przepływu.
    • overset: właściwość logiczna, która:
      • false, gdy zawartość nazwanego przepływu mieści się w powiązanych regionach
      • true, gdy treść nie mieści się i potrzebne są dodatkowe regiony, aby pomieścić całą treść.
    • getContent(): funkcja, która zwraca kolekcję z odwołaniami do węzłów, które wpływają do nazwanej automatyzacji.
    • getRegions(): funkcja, która zwraca kolekcję z odwołaniami do regionów zawierających treść nazwanego przepływu.
    • getRegionsByContentNode(node): funkcja, która zwraca odwołanie do regionu zawierającego określony węzeł. Jest to szczególnie przydatne do znajdowania regionów zawierających elementy takie jak nazwane kotwice.
  • webkitregionoversetchange zdarzenie. To zdarzenie jest wywoływane w elemencie WebkitNamedFlow, gdy układ powiązanej treści ulega zmianie z dowolnego powodu (dodanie lub usunięcie treści, zmiana rozmiaru czcionki, zmiana kształtu regionu itp.) i powoduje zmianę właściwości webkitRegionOverset regionu. To zdarzenie jest przydatne do nasłuchiwania zmian w ogólnym układzie. Wskazuje, że wydarzyło się coś ważnego i układ może wymagać uwagi, np. potrzebnych jest więcej regionów, niektóre regiony mogą być puste itp.
  • webkitregionfragmentchange zdarzenie. Nie zaimplementowano w momencie wprowadzania tej zmiany. To zdarzenie jest wywoływane w obiekcie WebkitNamedFlow, gdy układ powiązanych treści ulega zmianie z dowolnego powodu, podobnie jak w przypadku webkitregionoversetchange, ale niezależnie od zmian we właściwościach webkitRegionOverset. To zdarzenie jest przydatne do wykrywania drobnych zmian układu, które niekoniecznie wpływają na cały układ nazwanego przepływu, np. gdy treść jest przenoszona z jednego regionu do innego, ale ogólnie nadal mieści się we wszystkich regionach.
  • Element.webkitRegionOverset: elementy stają się regionami, gdy mają przypisaną właściwość CSS flow-from. Te elementy mają właściwość webkitRegionOverset, która wskazuje, czy zawartość przepływu przepełnia region, jeśli są one częścią nazwanego przepływu. Możliwe wartości webkitRegionOverset to:
    • „overflow”, jeśli jest więcej treści, niż może pomieścić region;
    • „fit”, jeśli treść kończy się przed końcem regionu;
    • „empty”, jeśli treści nie dotarły do regionu.

Jednym z głównych zastosowań CSSOM jest nasłuchiwanie zdarzeń webkitregionoversetchange i dynamiczne dodawanie lub usuwanie regionów w celu dostosowania ich do różnych ilości tekstu. Jeśli na przykład ilość tekstu do sformatowania jest nieprzewidywalna (np. jest to tekst wygenerowany przez użytkownika), jeśli rozmiar okna przeglądarki zostanie zmieniony lub jeśli zmieni się rozmiar czcionki, może być konieczne dodanie lub usunięcie regionów, aby dostosować je do zmiany przepływu. Jeśli chcesz podzielić treści na strony, potrzebujesz mechanizmu do dynamicznego modyfikowania modelu DOM i regionów.

Poniższy fragment kodu JavaScript pokazuje, jak używać CSSOM do dynamicznego dodawania regionów w razie potrzeby. Pamiętaj, że dla uproszczenia nie obsługuje on usuwania regionów ani definiowania ich rozmiaru i pozycji. Służy on tylko do celów demonstracyjnych.

var flow = document.webkitGetNamedFlows().namedItem("article")
flow.addEventListener("webkitregionoversetchange", onLayoutUpdate);

function onLayoutUpdate(event) {
    var flow = event.target;
    
    // The content does not fit
    if (flow.overset === true) {
    addRegion();
    } else {
    regionLayoutComplete();
    }
}

function addRegion() {
    var region = document.createElement("div");
    region.style = "flow-from: article";
    document.body.appendChild(region);
}

function regionLayoutComplete() {
    // Finish up your layout.
}

Więcej wersji demonstracyjnych znajdziesz na stronie z przykładami regionów CSS.

Szablony stron usługi porównywania cen

Wykorzystanie CSSOM jest prawdopodobnie najpotężniejszym i najbardziej elastycznym sposobem wdrażania takich funkcji jak stronicowanie i układ elastyczny, ale firma Adobe pracuje z narzędziami do edycji tekstu i DTP wystarczająco długo, aby wiedzieć, że projektanci i programiści będą chcieli również łatwiejszego sposobu na uzyskanie stosunkowo ogólnych możliwości stronicowania. Dlatego pracujemy nad propozycją o nazwie Szablony stron CSS, która umożliwia definiowanie zachowania stronicowania w całości deklaratywnie.

Przyjrzyjmy się częstemu przypadkowi użycia szablonów stron CSS. Poniższy fragment kodu pokazuje, jak za pomocą CSS utworzyć 2 nazwane przepływy: „article-flow” i „timeline-flow”. Dodatkowo definiuje trzeci selektor o nazwie „combined-articles”, w którym będą zawarte oba przepływy. Samo umieszczenie właściwości overflow-style w selektorze „combined-articles” wskazuje, że treść powinna być automatycznie dzielona na strony wzdłuż osi X, czyli poziomo:

<style>
    #article {
    { % mixin flow-into: article-flow; % }
    }

    #timeline {
    { % mixin flow-into: timeline-flow; % }
    }

    #combined-articles {
    overflow-style: paged-x;
    }
</style>

Po zdefiniowaniu przepływów i określeniu pożądanego zachowania w przypadku przepełnienia możemy utworzyć szablon strony:

@template {
    @slot left {
    width: 35%;
    float: left;
    { % mixin flow-from: article-flow; % }
    }

    @slot time {
    width: 25%;
    float: left;
    { % mixin flow-from: timeline-flow; % }
    }

    @slot right {
    width: 35%;
    float: left;
    { % mixin flow-from: article-flow; % }
    }
}

Szablony stron są definiowane za pomocą nowej składni „at”. W powyższym fragmencie kodu definiujemy 3 boksy, z których każdy odpowiada kolumnie. Tekst z „article-flow” będzie przepływać przez kolumny po lewej i prawej stronie, a tekst z „timeline-flow” wypełni kolumnę pośrodku. Wynik może wyglądać tak:

Przykład szablonów stron
Przykład szablonów stron

Zwróć uwagę, że tekst artykułu – w lewej i prawej kolumnie – jest w języku angielskim, a oś czasu pośrodku jest w języku niemieckim. Dodatkowo dokument jest dzielony na strony w poziomie bez konieczności używania kodu JavaScript. Wszystko zostało zrobione całkowicie deklaratywnie w CSS.

Szablony stron CSS są nadal w fazie propozycji, ale mamy prototyp, który używa „podkładki” JavaScript (tzw. polyfill), aby umożliwić Ci eksperymentowanie z nimi już teraz.

Więcej informacji o regionach CSS znajdziesz na stronie regionów CSS w witrynie html.adobe.com.

Wykluczenia usług porównywania cen

Aby uzyskać prawdziwy układ magazynu, nie wystarczy tylko możliwość przepływu tekstu przez regiony. Kluczowym elementem wysokiej jakości i atrakcyjnych wizualnie publikacji komputerowych jest możliwość umieszczania tekstu wokół nieregularnych grafik i kształtów lub wewnątrz nich. Wykluczenia CSS zapewniają tę jakość produkcji w internecie.

Zrzut ekranu poniżej pochodzi z prototypu wykluczeń CSS i pokazuje tekst dynamicznie opływający ścieżkę, która pasuje do konturu dużej formacji skalnej:

Przykład wykluczeń CSS w działaniu
Przykład wykluczeń CSS w działaniu

Odwrotny przypadek jest przedstawiony na kolejnym zrzucie ekranu: tekst przepływa wewnątrz wielokątów o nieregularnych kształtach:

Tekst przepływający do wielokątów o nieregularnych kształtach
Tekst w wielokątach o nieregularnych kształtach

Pierwszym krokiem do umożliwienia oblewania tekstem dowolnych kształtów lub wypełniania ich tekstem jest opracowanie i zoptymalizowanie wymaganych algorytmów. Adobe pracuje obecnie nad implementacjami, które zostaną przekazane bezpośrednio do WebKit. Po zoptymalizowaniu tych algorytmów staną się one podstawą, na której zostaną zbudowane pozostałe wykluczenia CSS.

Więcej informacji o wykluczeniach CSS znajdziesz na stronie poświęconej wykluczeniom CSS w witrynie html.adobe.com. Bardziej szczegółowe informacje o pracach firmy Adobe nad technologią wykluczeń CSS znajdziesz w poście Hansa Mullera na blogu zatytułowanym Horizontal Box: Polygon Intersection for CSS Exclusions (Poziome pole: przecięcie wielokątów w wykluczeniach CSS).

Stan regionów CSS i wykluczeń CSS (2012)

Pierwszy raz publicznie mówiłem o regionach i wykluczeniach CSS na stanowisku Adobe Developer Pod podczas konferencji Google I/O 2011. W tym czasie prezentowałem wersje demonstracyjne w naszej własnej, niestandardowej przeglądarce prototypowej. Odbiór był niezwykle entuzjastyczny, ale gdy widzowie dowiedzieli się, że żadna z prezentowanych przeze mnie funkcji nie jest jeszcze dostępna w żadnej z głównych przeglądarek, dało się wyczuć rozczarowanie.

W tym roku (2012) znów uczestniczyłem w konferencji Google I/O, tym razem jako prezenter razem z moim współpracownikiem Vincentem Hardym i Alexem Danilo z Google (tutaj możesz obejrzeć prezentację). Zaledwie rok później około 80% specyfikacji CSS Regions zostało zaimplementowane w WebKit i jest już dostępne w najnowszej wersji Google Chrome (pamiętaj, że CSS Regions trzeba obecnie włączyć przez chrome://flags). Wstępna obsługa CSS Regions pojawiła się nawet w Chrome na Androida:

Regiony w Chrome na Androida
Regiony w Chrome na Androida

Dodatkowo zarówno regiony CSS, jak i wykluczenia CSS są zaimplementowane w wersji testowej Internet Explorera 10 i obecnie znajdują się w planie rozwoju Firefoksa Mozilli na 2012 rok. Następna wersja główna Safari powinna obsługiwać większość specyfikacji regionów CSS, a kolejne aktualizacje powinny obejmować pozostałe elementy.

Poniżej przedstawiamy szczegółowy harmonogram postępów, jakie poczyniliśmy w zakresie regionów i wykluczeń CSS od czasu naszej pierwszej propozycji dla W3C w kwietniu 2011 r.:

Postęp w regionie i wykluczenia
Postęp przenoszenia danych między regionami i wykluczania

Podsumowanie

Firma Adobe ma ogromne doświadczenie w zakresie tekstu, czcionek i ogólnie DTP dzięki narzędziom takim jak InDesign. Chociaż internet jest już bardzo zaawansowaną platformą do obsługi tekstu, chcemy wykorzystać naszą wiedzę i doświadczenie, aby jeszcze bardziej rozwinąć prezentację tekstu. Regiony CSS i wykluczenia CSS umożliwiają zachowanie semantycznej struktury treści, a jednocześnie pozwalają na tworzenie układu przypominającego czasopismo, co ostatecznie przekłada się na znacznie bardziej ekspresyjną sieć.