提供類似雜誌的網路版面配置,以及 CSS 區域和排除條件

Christian Cantrell
Christian Cantrell

簡介

網路是功能強大的文字平台,Adobe 在這方面擁有豐富的經驗和專業知識。Adobe 不斷尋求各種方法,幫助我們推動網際網路向前邁,因此想先改善網頁的文字功能,就如同一個明顯的起點。 網路一般會假設文字為單欄,且文字為垂直方向。雖然您可以在圖片周圍流動文字,甚至透過 CSS 將文字格式化為多欄,但要在網頁上達到類似雜誌的版面配置並不容易。Adobe 推出 CSS 區域CSS 排除條件,現正致力將電腦發布功能拓展到新式瀏覽器中。例如,在下方螢幕截圖中,我們使用 CSS 排除功能來沿山的輪廓顯示文字:

CSS 排除條件實際運作範例
CSS 排除功能應用實例

下方螢幕截圖中的文件也使用「CSS 排除」功能讓文字在圖片中繞行

CSS 區域實際運作範例
CSS 區域應用實例

CSS 區域

在進一步瞭解 CSS 區域前,我想先說明在 Google Chrome 中如何啟用區域。啟用 CSS 區域後,您可以試用本文中參照的幾個範例,並自行建立。

在 Google Chrome 中啟用 CSS 區域

自 Chrome 20 版 (20.0.1132.57 版) 起,CSS 區域會透過 chrome://flags 介面啟用。如要啟用 CSS 區域,請按照下列步驟操作:

  1. 在 Chrome 中開啟新分頁或視窗。
  2. 在位置列中輸入 chrome://flags
  3. 使用「在頁面中尋找」( Control/Command + f 鍵) 並搜尋「實驗性網路平台功能」部分。
  4. 按一下「啟用」連結。
  5. 按一下底部的「Relaunch Now」(立即重新啟動) 按鈕。

如要進一步瞭解 Chrome 的旗標,請參閱「關於 Chrome 標記」一文,進一步瞭解我的網誌文章。

重新啟動瀏覽器後,即可自由開始在「CSS 區域」中進行實驗。

CSS 區域總覽

CSS 區域允許含有語意標記的文字區塊,自動流入「方塊」(目前元素)。下圖展示了文字 (流程) 與方塊 (文字流入區域) 的區隔:

內容流入已定義的地區
內容流入已定義的區域

以下列舉實際的 CSS 區域使用情境。除了是 Adobe 的開發人員,我也是科幻作家。我經常依照創用 CC 授權在網路上發布我的作品。為了讓作品能在符合最多裝置和瀏覽器的情況下運作,我經常使用這種十分簡單的格式:

未設定樣式的人類舊版專案範例
未設定樣式的人類舊版專案範例

透過 CSS 區域,我成功打造視覺效果更吸引人的使用體驗,而且功能更實用,因為使用者比較容易瀏覽內容,也更方便閱讀:

顯示區域的人類遺產專案
具備區域的人類傳統專案。

為了進行示範,我在這個原型中加入顯示 CSS 區域的功能。下方的螢幕截圖顯示區域的排列方式,讓這些資料欄看起來像是圍繞一個圖形,還有中央的引文:

顯示區域的人類遺產專案
顯示區域的人舊版專案

您可以前往這裡實驗這種原型 (以及查看原始碼)。使用方向鍵瀏覽,按下 Esc 鍵可顯示區域。您也可以使用這裡提供的舊版原型。

建立已命名的流程

需要的 CSS 需要一段文字才能通過區域。下方的程式碼片段會將名為「article」的已命名流程指派給 ID 為「content」的 div,並將相同的「文章」命名流程指派給任何包含「region」類別的元素。這樣一來,「content」元素中包含的文字會自動穿過任何含有「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>

結果如下所示:

上述程式碼的結果
上述程式碼的結果

請注意,「content」div 內的文字與簡報內容無關。換句話說,即使它在通過不同區域傳輸,也能完全保持語意不變。此外,由於區域只是元素,系統會使用 CSS 來設定位置和大小,就像任何其他元素一樣,因此也與回應式設計原則完美相容。將元素設計為已命名流程的一部分,只是表示指定文字會自動穿過這些元素。

CSS 物件模型

CSS 物件模型 (簡稱 CSSOM) 可定義與 CSS 搭配使用的 JavaScript API。以下是與 CSS 區域相關的新 API 清單:

  • document.webkitGetNamedFlows():傳回文件中可用已命名流程集合的函式。
  • document.webkitGetNamedFlows().namedItem("article"):傳回特定已命名流程參照的函式。該引數會對應至用 flow-intofrom-from CSS 屬性值指定的名稱。如要取得上述程式碼片段中指定的已命名流程參照,請傳入「article」字串。
  • WebKitNamedFlow:以物件表示法呈現已命名的 floe,包含下列屬性和函式:
    • firstEmptyRegionIndex:整數值,指向與已命名資料流相關聯的第一個空白區域的索引。請參閱下方的 getRegions(),瞭解如何取得區域集合。
    • name:包含資料流名稱的字串值。
    • overset:布林值屬性,如下所示:
      • 當已命名流程的內容符合相關區域時,則為 false
      • true:如果內容不符合條件,且需要納入更多區域才能包含所有內容,
    • getContent():這個函式會傳回集合,其中包含流入已命名流程中的節點參照。
    • getRegions():一種函式會傳回集合,且參照到保留已命名流程內容的區域。
    • getRegionsByContentNode(node):會傳回包含指定節點區域參照的函式。這個做法特別適合用於尋找含有具名錨點等事物的區域。
  • webkitregionoversetchange 事件。每當相關內容的版面配置基於任何原因 (新增或移除、字型大小變更、區域形狀變更等) 而導致區域的 webkitRegionOverset 屬性變更時,都會在 WebkitNamedFlow 上觸發此事件。如要監聽粗略的版面配置變更,這個事件就十分實用。狀態表示有重要問題,而版面配置可能需要注意,例如:需要更多區域、部分區域可能空白等。
  • webkitregionfragmentchange 事件。目前未進行這項修改。每當相關內容的版面配置基於任何原因 (與 webkitregionoversetchange 類似) 變更時,就會在 WebkitNamedFlow 上觸發此事件,但「無論」webkitRegionOverset 屬性發生任何變更。此事件有助於監聽精細的版面配置變更,而這不一定會影響已命名流程的完整版面配置,例如:內容從一個區域移動到另一個地區,但整體內容仍適用於所有區域。
  • Element.webkitRegionOverset:元素具有 flow-from CSS 屬性後,就會成為區域。這些元素具有 webkitRegionOverset 屬性,如果這些元素屬於已命名流程的一部分,則會指出資料流的內容是否溢出區域。webkitRegionOverset 可能的值包括:
    • 如果內容超過地區可容納的更多內容,則為「overflow」(溢位)
    • 如果內容在區域結束之前停止,則為「fit」
    • 如果內容未到達地區,則為「empty」

CSSOM 的主要用途之一是監聽 webkitregionoversetchange 事件,並動態新增或移除區域來因應不同的文字量。舉例來說,如果要格式化的文字數量無法預測 (也許是由使用者產生),那麼在調整瀏覽器視窗大小,或者如果字型大小改變,您可能需要新增或移除區域,才能因應流程的變化。此外,如果您想要將內容整理到不同頁面,則需要運用動態修改 DOM 和區域的機制。

下列 JavaScript 程式碼片段示範如何使用 CSSOM,視需要動態新增區域。請注意,為求簡單易懂,這項服務不會移除區域或定義區域大小和位置,僅供示範之用。

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.
}

如要查看更多示範,請前往 CSS 區域範例頁面

CSS 頁面範本

運用 CSSOM 或許是功能最強大、最具彈性的方式實作分頁和回應式版面配置等項目,但 Adobe 多年來持續與文字和電腦發布工具搭配運作,表示設計人員和開發人員也希望找到相對較通用的分頁功能。因此,我們正著手規劃名為「CSS 頁面範本」的提案,以完全宣告的方式定義分頁行為。

來看看 CSS 頁面範本的常見用途。以下程式碼片段說明如何使用 CSS 建立兩個已命名的流程:「article-flow」和「Timeline-flow」。此外,它還定義了另一個名為「合併文章」的選取器,其中將包含兩個流程。在「合併文章」選取器中加入 overflow-style 屬性後,內容就應沿著 X 軸自動分頁 (或水平移動):

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

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

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

現在您已定義流程,並指定所需的溢位行為後,就可以建立頁面範本本身:

@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; % }
    }
}

網頁範本是使用新的「at」語法來定義。在上方的程式碼片段中,我們定義了三個版位,每個版位都對應一個資料欄。「文章流」中的文字會流經左側欄,而位於中間的資料欄,則位於中間的資料欄。結果可能會像這樣:

頁面範本範例
頁面範本範例

請注意,文章文字 (左欄和右欄的文字) 為英文,而中央的時間軸為德文。此外,文件頁面會水平方向,不需要任何 JavaScript 程式碼。所有操作都是在 CSS 中以宣告方式完成。

CSS 網頁範本仍是一項提案,不過我們準備了採用 JavaScript「填充碼」(又稱 polyfill) 的原型,方便您立即進行實驗。

如要進一步瞭解「CSS 區域」的一般資訊,請造訪 html.adobe.com 的「CSS 區域」頁面

CSS 排除條件

為了達成真正的雜誌型版面配置,不能在區域之間流通文字。在不規則的圖像和形狀周圍或周圍顯示文字,是優質又有吸引力的電腦版發布機制的關鍵要素。CSS 排除計畫可將生產品質提升至網路。

下方螢幕截圖是來自 CSS 排除原型,會顯示與大型岩石輪廓相符的路徑,讓文字動態流動:

CSS 排除條件實際運作範例
CSS 排除功能應用實例

下一張螢幕截圖則顯示反向圖像:文字在不規則形狀的多邊形中流動:

文字流向不規則形狀的多邊形
流向不規則形狀的多邊形

如要在任意形狀周圍或周圍流動文字,第一步是開發並最佳化所需的演算法。Adobe 目前正在處理實作,並且會直接提供給 WebKit 使用。這些演算法經過最佳化處理後,將成為建構 CSS 排除規則的基礎基礎。

如需 CSS 排除規則的詳細資訊,請參閱 html.adobe.com 上的「CSS 排除」網頁;如要進一步瞭解 Adobe 針對 CSS 排除技術所做的努力,請參閱 Hans Muller 的網誌文章「Horizontal Box: Polygon Intersection for CSS 排除」。

目前的 CSS 區域和 CSS 排除狀態

我第一次談到 CSS 區域和 CSS 排除功能,是在 2011 年 Google I/O 大會的 Adobe Developer Pod 上。當時,我還在自家的自訂原型瀏覽器中示範操作。它的收穫非常令人振奮,然而,當觀察者發現我展示的功能無法在任何主要瀏覽器中使用時,我感到很失望。

我今年又在 Google I/O 大會 (2012 年) 出席 Google I/O 大會,這次是與 Google 同事 Vincent HardyAlex Danilo 共同擔任的主講者 (你可以在這裡觀看簡報)。就在一年後,WebKit 中約有 80% 的 CSS 區域規格已導入 WebKit,並且已在最新版本的 Google Chrome 中導入 (請注意,CSS 區域目前必須透過 chrome://flags 啟用)。Android 版 Google Chrome 現已推出 CSS 區域的初步支援:

Google Chrome Android 版的區域
在 Android 版 Google Chrome 中使用的區域

此外,CSS 區域和 CSS 排除設定已在 Internet Explorer 10 預先發布版中導入,且目前都在 Mozilla Firefox 的 2012 年發展藍圖中。下一個主要版本的 Safari 應支援大部分的 CSS 區域規格,後續更新則應納入其餘項目。

我們從 2011 年 4 月首次向 W3C 提案提案以來,以下是我們針對 CSS 區域和 CSS 排除功能所提供的進度詳細時間表:

區域與排除進度
區域和排除進度

結論

Adobe 對文字、字型和桌面發布功能的基本使用經驗都十分廣泛,例如 InDesign 等工具。雖然網路已是非常強大的文字處理平台,但我們希望能運用自身的知識和經驗,讓文字簡報更加完善。CSS 區域和 CSS 排除清單可讓內容維持語意結構,同時支援類似雜誌的版面配置,最終提供更生動的網頁內容。