排序彈性項

彈性盒子(flexbox)和網格(grid)等佈局方法可以控制內容的順序。在本文中,我們將探討使用彈性盒子時可以改變內容視覺順序的方法。我們還將探討重新排序對可訪問性的影響。

反轉專案的顯示順序

flex-direction 屬性可取以下四個值之一:

  • row
  • column
  • row-reverse
  • column-reverse

前兩個值會保持專案在文件原始碼中出現的順序,並從起始線開始依次顯示它們。

The items are displayed in a row starting on the left.

The items are displayed as a column starting from the top

後兩個值透過交換起始線和結束線來反轉專案。

The items are displayed in reverse order starting on the right-hand line.

The items are displayed in a column in reverse order starting at the bottom line.

請記住,起始線與書寫模式有關。上面與行相關的示例演示了 rowrow-reverse 在從左到右書寫的語言(如英語)中是如何工作的。如果你正在使用從右到左書寫的語言(如阿拉伯語),那麼 row 將從右側開始,row-reverse 將從左側開始。

Flex containers with Arabic letters showing how row starts from the right-hand side and row-reverse from the left.

這看起來像是一種以相反順序顯示內容的簡單方法。但是,你應該注意,專案只是在*視覺上*以相反的順序顯示。彈性佈局的重新排序功能隻影響視覺渲染。Tab 鍵順序和語音順序遵循原始碼的順序。這意味著只有視覺呈現發生了變化;原始碼順序保持不變,這為非 CSS 使用者代理(比如 Siri 或 Alexa)和輔助技術使用者提供了不同的使用者體驗。如果你更改了導航欄的順序,Tab 鍵順序仍然是文件原始碼順序,而不是你的視覺順序,這可能會在認知上造成混淆。

如果你正在使用反向值,或者以其他方式重新排序你的專案,你應該考慮是否真的應該更改原始碼中的邏輯順序。

彈性盒子佈局規範警告我們不要使用重新排序來修復原始碼問題:

“作者絕不能使用 order 或 flex-flow/flex-direction 的 *-reverse 值來代替正確的原始碼順序,因為這會破壞文件的可訪問性。”

當你在下面的即時示例中從一個連結切換到另一個連結時,焦點樣式會高亮顯示,這表明使用 flex-direction 更改彈性專案的順序不會改變 Tab 鍵順序,它將繼續遵循原始碼的順序。

html
<div class="box">
  <div><a href="#">One</a></div>
  <div><a href="#">Two</a></div>
  <div><a href="#">Three</a></div>
</div>
css
.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  padding: 10px;
}

.box > * a:focus {
  background-color: yellow;
  color: black;
}

.box {
  border: 2px dotted rgb(96 139 168);
  display: flex;
  flex-direction: row-reverse;
}

就像更改 flex-direction 的值不會改變 Tab 鍵順序一樣,更改此值也不會改變繪製順序。它僅僅是專案在視覺上的反轉。

order 屬性

除了反轉彈性專案的視覺顯示順序外,你還可以針對單個專案,並使用 order 屬性更改它們在視覺順序中出現的位置。

order 屬性旨在將專案按序陣列進行佈局。這意味著為專案分配一個代表其組別的整數。然後,專案會根據該整數按視覺順序放置,值越小的越靠前。如果多個專案具有相同的整數值,那麼在該組內,專案將按照原始碼順序進行佈局。

例如,為五個彈性專案分配 order 值如下:

  • 源專案 1:order: 2
  • 源專案 2:order: 3
  • 源專案 3:order: 1
  • 源專案 4:order: 3
  • 源專案 5:order: 1

這些專案將按以下順序顯示在頁面上:

  • 源專案 3:order: 1
  • 源專案 5:order: 1
  • 源專案 1:order: 2
  • 源專案 2:order: 3
  • 源專案 4:order: 3

Items have a number showing their source order which has been rearranged.

在下面的即時示例中嘗試調整這些值,看看順序會如何變化。此外,嘗試將 flex-direction 更改為 row-reverse,看看會發生什麼——起始線被切換了,所以排序從相反的一側開始。

html
<div class="box">
  <div><a href="#">1</a></div>
  <div><a href="#">2</a></div>
  <div><a href="#">3</a></div>
  <div><a href="#">4</a></div>
  <div><a href="#">5</a></div>
</div>
css
.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  padding: 10px;
}

.box {
  border: 2px dotted rgb(96 139 168);
  display: flex;
  flex-direction: row;
}
.box :nth-child(1) {
  order: 2;
}
.box :nth-child(2) {
  order: 3;
}
.box :nth-child(3) {
  order: 1;
}
.box :nth-child(4) {
  order: 3;
}
.box :nth-child(5) {
  order: 1;
}

彈性專案的預設 order 值為 0。因此,整數值大於 0 的專案將顯示在任何未被賦予明確 order 值的專案之後。

你也可以對 order 使用負值,這非常有用。如果你想讓一個專案顯示在最前面,並保持所有其他專案的順序不變,你可以給該專案一個 -1 的 order 值。由於這個值小於 0,該專案將始終顯示在最前面。

在下面的即時程式碼示例中,專案使用彈性盒子佈局。透過在 HTML 中更改哪個專案被分配了 active 類,你可以改變哪個專案首先顯示,從而在佈局頂部佔據全部寬度,而其他專案則顯示在它下面。

html
<div class="box">
  <div><a href="#">1</a></div>
  <div><a href="#">2</a></div>
  <div class="active"><a href="#">3</a></div>
  <div><a href="#">4</a></div>
  <div><a href="#">5</a></div>
</div>
css
* {
  box-sizing: border-box;
}

.box > * {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  padding: 10px;
}

.box {
  width: 500px;
  border: 2px dotted rgb(96 139 168);
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
}

.active {
  order: -1;
  flex: 1 0 100%;
}

專案以*經順序修改的文件順序*顯示,這意味著在顯示專案之前會考慮 order 屬性的值。

Order 也會改變專案的繪製順序;order 值較低的專案會先被繪製,order 值較高的專案會後被繪製。

order 屬性與可訪問性

使用 order 屬性對可訪問性的影響與使用 flex-direction 改變方向相同。使用 order 會改變專案的繪製順序以及它們在視覺上出現的順序,但它不會改變專案的順序導航順序。因此,如果使用者使用鍵盤透過 Tab 鍵在頁面內容中切換,他們可能會發現自己以一種非常混亂的方式在內容中跳轉。

透過在本頁的任何即時示例中按 Tab 鍵,你可以看到 order 對於不使用滑鼠等指標裝置的人來說,可能會造成多麼奇怪的體驗。要了解更多關於視覺順序和邏輯順序脫節以及它可能引發的一些可訪問性問題,請參閱以下資源。

order 的用例

在某些用例中,彈性專案的邏輯順序(即閱讀順序)與視覺順序分離是很有幫助的。如果小心使用,order 屬性可以輕鬆實現一些有用的常見模式。

你可能有一個設計,比如一個顯示新聞條目的卡片。新聞的標題是需要突出的關鍵內容,也是使用者在標題之間切換以查詢想閱讀的內容時可能會跳轉到的元素。卡片上還有一個日期;我們想要建立的最終設計是這樣的。

A design component with a date, then heading and then content.

在視覺上,日期出現在標題上方。然而,在原始碼中,如果這張卡片被螢幕閱讀器讀出,我更希望先讀出標題,然後再讀出釋出日期。我們可以用 order 屬性來實現這一點。

這張卡片是我們的彈性容器,flex-direction 設定為 column。我們給日期一個 -1order 值,將它置於標題之上。

html
<div class="wrapper">
  <div class="card">
    <h3>News item title</h3>
    <div class="date">1 Nov 2017</div>
    <p>This is the content of my news item. Very newsworthy.</p>
  </div>
  <div class="card">
    <h3>Another title</h3>
    <div class="date">6 Nov 2017</div>
    <p>This is the content of my news item. Very newsworthy.</p>
  </div>
</div>
css
body {
  font-family: sans-serif;
}

.wrapper {
  display: flex;
  flex: 1 1 200px;
  gap: 1em;
}

.card {
  border: 2px solid rgb(96 139 168);
  border-radius: 5px;
  background-color: rgb(96 139 168 / 0.2);
  padding: 1em;
  display: flex;
  flex-direction: column;
}

.date {
  order: -1;
  text-align: right;
}

這些小調整正是 order 屬性發揮作用的場景。保持邏輯順序與文件的閱讀和 Tab 鍵順序一致,並以最易訪問和結構化的方式維護它。然後將 order 用於純粹的視覺設計調整。不要對會接收鍵盤焦點的專案進行重新排序。請確保始終只用鍵盤而不是滑鼠或觸控式螢幕來測試你的內容;這將揭示你的開發選擇是否使內容導航變得更加複雜。

另見