Web 發展的每個不同時期都有新的技術為 Web 布局提供支持,但不管是哪個時期,Web 布局相關的概念和術語都是相同的。如果你想徹底或者更好地掌握 Web 布局,那么首先需要對 Web 布局相關的技術術語有所了解。
在這一節中,我們一起來探討 Web 布局相關的術語。
Web 坐標軸
坐標軸不只是存在于數學中,它同樣存在于 Web 世界中。在 Web 中,我們常稱之為 Web 坐標軸 或 CSS 坐標系統 。
在 Web 中,默認原點是給定上下文的左上角,也就是元素盒子的左上角,它分為 x
軸(也稱為水平軸),向右為正值,向左為負值;y
軸(垂直軸),向上為負值,向下為正值:
請注意,這與大多數數學模型不同,其中原點位于左下角,正
y
坐標值位于原點上方。
事實上,除了大家熟悉的平面畫布中的 x
和 y
軸之外,還有控制第三維度的 z
軸。比如使用 CSS 的 transform
繪制 3D 圖形或使用第三維度從前往后對對象進行分層:
也會在定位元素(顯式使用position
屬性值為非 static
的元素)上使用 z-index
控制其層疊的順序(z
軸上的層疊順序),它表示的是用戶與屏幕的這條看不見的垂直線:
上面我們看到的 CSS 坐標系,只是最初的坐標系的定義。隨著 CSS 的邏輯屬性出現,CSS 的坐標系也隨之改變。它分為 內聯軸 (Inline Axis)和 塊軸 (Block Axis)。
眾所周知,在 CSS 中,每個元素都是一個盒子,默認情況之下,盒子會根據元素類型分為塊盒子(比如塊元素 div
)和 內聯盒子(比如span
)。其中塊盒會在垂直方向從上往下堆疊,內聯盒子將會按照書寫方式從左往右排列:
當我們的書寫方式改變時,塊盒子和內聯盒子也會有相應的變化,就拿內聯盒子為例,書寫模式改變之后,它的方向也會隨之改變:
簡而言之,塊元素遵循流方向,內聯元素遵循寫入方向:
也就是說,隨著 CSS 的邏輯屬性的出現,CSS 的坐標系就不再以 x
軸 和 y
軸來定義,而是以 內聯 (Inline)和 塊 (Block)來區分,并且內聯方向的稱之為 內聯軸 (Inline Axis),也就是書寫模式的方向;塊方向的稱之為 塊軸 (Block Axis),也就是塊盒子自然流的方向。它們隨著 CSS 的書寫模式改變,如下圖所示:
如此一來,在 CSS 中就有物理坐標系 和 邏輯坐標系 之分,它們的對應關系如下:
物理屬性 | 邏輯屬性(horizontal-tb ) | 邏輯屬性(vertical-lr ) | 邏輯屬性(vertical-rl ) |
---|---|---|---|
x 軸(水平軸) | Inline 軸(內聯軸) | Block 軸(塊軸) | Block 軸(塊軸) |
y 軸(垂直軸) | Block 軸(塊軸) | Inline 軸(內聯軸) | Inline 軸(內聯軸) |
注意 ,不管是在物理坐標系還是邏輯坐標系中,
z
軸是不變的!
容器和容器空間
容器這個概念很簡單。熟悉 CSS 的同學都知道,HTML 的每一個元素在 CSS 中都是一個盒子,這個盒子又被稱為 容器 。只不過,這個容器會隨著盒子的類型不同,容器的稱呼也會有不同。它主要由 CSS 的 display
屬性的值來決定,比如:
block
時稱為塊容器;
inline
時稱為內聯容器;
flex
或inline-flex
時稱為Flexbox容器;
grid
或inline-grid
時稱為 Grid 容器(網格容器)。
每個容器就像生活中的器皿一樣,不管是什么類型的容器,它都有空間。只不過這個空間的大小是由 CSS 盒模型相關的屬性來決定的:
只不過,Web 開發者習慣性以 width
、height
、 min-*
或 max-*
以及它們對應的邏輯屬性來顯式指定一個容器空間的大小:
而且容器大小計算方式也會受 CSS 的 box-sizing
屬性的值影響:
每個容器中都有可能會放置內容(文本內容或其他元素),隨著容器中放置的內容多少,可能會造成指定大小的容器無法容納嵌套的內容,造成內容溢出(超出指定容器的大小);也有可能放置的內容較少,無法填充滿整個容器。
按此呈現模式,每個容器的大小(空間)又有可用空間 (也稱為 剩余空間 )和 不可用空間 (也稱為 不足空間 ):
間距
Web 是由很多個元素堆疊而成的,為了讓 Web 頁面給用戶提供更好的體驗,Web 設計師在設計時,會根據美學相關的理論來設計元素與元素之間,元素內容與元素盒子邊緣之間的間距:
只不過,在 Web 布局中,我們常常是使用 CSS 的 margin
、padding
和 gap
三個屬性來設置間距。不同的是:
- 框與框(也就是元素與元素)之間的間距一般采用
margin
或gap
屬性來設置,也常稱為 外距 ;
- 內容與框的邊緣(元素內容與元素框邊緣)之間的間距一般采用
padding
來設置,也常稱為 內距。
如下圖所示:
特別要提出來的是,CSS 中的 margin
和 gap
表現形式是有較大差異的,它們之間的差異用下圖來闡述:
書寫模式
世界上有很多種語言(簡稱世界語言),比如漢語、英語、印度斯坦語、西班牙語、阿拉伯語、俄語、葡萄牙語、德語和法語等。在互聯中也有一些常用語言,比如英語、漢語、西班牙語、葡萄牙語、印尼語(馬來語)、法語、日語、俄語和德語等。
不同的語系,它們的書寫模式(閱讀模式)是有差異的:
- 拉丁語體系 是從左往右,比如英語、西班牙語、德語、法語等;
- 阿拉伯語體系 是從右往左,比如阿拉伯語、希伯來語等;
- 漢語體系 有兩種方式,有可能是從左往右,也有從上向往下,比如中文、日文、韓文等。
正因為語言的書寫方式不同,在 Web 中呈現不同語系時,CSS 中的塊(Block)和 內聯(Inline)表現的方式也會不同。
在 Web 布局中,尤其是針對多語言的 Web 布局,我們可以通過 HTML 元素的 dir
屬性或 CSS 的 direction
屬性來控制書寫模式,比如 ltr
(Left-To-Right,也就是從左往右的書寫方式),rtl
(Right-To-Left,也就是從右往左的書寫方式)。除此之外,還可以使用 CSS 的 writing-mode
屬性來控制:
正因為語系不同書寫模式不同,也將造成 CSS 中布局相關屬性最終呈現給用戶的效果有所差異,比如 Flexbox 中的 flex-direction
屬性,CSS Box Alignment 模塊中的屬性以及 Grid 布局等。
邏輯屬性
我們構建的 Web 頁面不僅是局限于單語種中,你負責的業務有可能是國際業務。這樣一來,你構建的 Web 頁面是一個多語種的 Web 頁面,那么你的布局會因為語種不同有所差異。比如 Facebook 的登錄頁面:
上圖中左側是漢語體系的布局效果,右側是阿拉伯語體系的布局效果。
眾所周知,CSS 中有很多屬性和值是遵循 TRBL (Top、Right、Bottom 和 Left ) 模式的:
比如,我們熟悉的元素位置會映射到 top
、right
、bottom
和 left
,除此之外,像 border
、 margin
、padding
和 border-radius
等屬性的子屬性也會映射到 TRBL 上,如 margin-top
、margin-right
、margin-bottom
和 margin-left
。它們帶有明確的方向性。只不過,針對多語言布局時,它給布局帶來很大的局限性,比如下面這個簡單地示例:
.thumb {margin-right: 1rem;
}
在ltr
模式(比如英文)和 rtl
模式(比如阿拉伯文),效果將會是像下圖一樣:
這個效果并不是我們所期待的,如果希望達到預期的效果,在以往編碼的時候,需要做額外的處理:
.thumb {margin-right: 1rem;
}
?
[dir="rtl"] .thumb {margin-left: 1rem;
}
為了解決類似上圖這樣的問題,2017 年 5 月 18 日,W3C 的 CSS 工作組(CSS Working Group) 發布了 CSS邏輯屬性和值(CSS Logical Properties and Values Level 1) 的首份工作草案(First Public Working Draft)。
在這個模塊中并沒有方向性的概念,只有開始(start
)、結束(end
)、塊(block
)和 內聯(inline
)的概念。這樣一來,在從左到右的(ltr
)中,start
對應的是 left
,但在從右到左(rtl
)中,start
對應的是 right
。也就是說,邏輯屬性更易于適應不同的書寫模式。
當然,邏輯屬性出現之后,很多 CSS 屬性和屬性值也隨之有了變化,在原有的物理屬性的基礎上映射了一份邏輯屬性。尤其是 CSS 的盒模型相關的屬性(比如 width
、height
、min-*
、max-*
、border
、margin
、padding
)、定位位移相關的屬性(比如 top
、right
、bottom
和 left
)、排版方面的(比如float
屬性的值 left
和 right
)以及圓角 border-radius
等:
而且映射關系與 CSS 的 writing-mode
屬性值也有關系,對應關系如下圖所示:
有了邏輯屬性之后,構建多語言 Web 的布局就要方便得多:
.thumb {margin-inline-end: 1rem;
}
對齊方式
這里所說的對齊方式指的是 CSS Box Alignment 模塊,該模塊的出現可以說改善了 CSS 中非常有限的對齊能力。在以往,我們控制對齊方式主要是依賴于 CSS 的 text-align
(水平方向文本對齊)和 vertical-align
(垂直方向文本對齊)兩個屬性,對于塊的對齊方式主要依賴于 float
屬性。它們是無法滿足 Web 布局中的對齊控制。
慶幸的是,隨著 CSS Flexbox 特性出現之后,CSS 新增了像 justify-content
、align-content
、align-items
、justify-items
和 justify-self
以及 align-self
等屬性,用來控制 Web 布局上的對齊方式。最初這些屬性是在 Flexbox 相關規范中定義的,但隨著 CSS Grid 布局出現之后,W3C 的 CSS 工作組將這些屬性單獨劃分到一個模塊中,即 CSS Box Alignment 模塊。
正如 @Pratham 發的 Twitter 信息上所說:
CSS Box Alignment 模塊是 Web 布局不可或缺的部分,而且其中有很多概念是極易于混淆的。
CSS Box Alignment 模塊中,取不同的值時,能得到不同的對齊結果,比如靠左(開始)、靠右(結束)、中間對齊、兩端對齊等:
注意,上圖由 @Pratham 繪制!
需要注意的是, CSS Box Alignment 模塊中的屬性同時可以運用于 CSS Flexbox 和 CSS Grid 布局中,在運用于 CSS Flexbox 和 CSS Grid 布局中時略有差異,具體我們會在后面介紹 Flexbox 和 Grid 布局中會提到,在這里不詳細闡述,大家只要知道,在現代 Web 布局技術中,對齊方式新增了該模塊!
小結
在這篇文章中,我們主要和大家一起探討了 Web 布局相關的概念和術語。從我們最為熟悉的坐標系統開始,到我們熟悉的容器以及容器空間,再到新增的書寫模式、邏輯屬性以及對齊方式等。我們花一個節課來介紹這方面,主要是為了和大家把布局相關的概念統一起來,為后續布局打下基礎。
有了這些基礎和認識之后,就可以開啟現代布局中的 Flexbox 布局了 !Let’s Go! (_)