HTML 列表通常被認為比較單調,功能有限,因此我們往往忽略了它們廣泛的應用。 儘管如此,我們仍然可以使用一些老方法來定制列表,例如移除標記、反轉順序和創建自定義計數器。
然而,在使用列表時,也有一些“新的”知識點,甚至包括潛在的風險需要注意。這些風險大多微不足道,但其發生頻率遠超你的想像。我們將探討這些風險,以及一些新的列表用法,甚至是一些改進舊方法的新思路。
需要明確的是,本文討論的 HTML 元素包括:
<dl></dl>
<menu></menu>
有序列表、無序列表和交互式列表都包含列表項 (<code><li>
),其顯示方式取決於列表類型。有序列表 (<ol></ol>
) 在列表項旁邊顯示數字;無序列表 (<code><ul></ul>
) 和菜單元素 (<menu></menu>
) 在列表項旁邊顯示項目符號。我們稱這些為“列表標記”,甚至可以使用 ::marker
偽元素對其進行樣式設置。描述列表使用描述術語 (<dt></dt>
) 和描述細節 (<dd></dd>
),而不是數字或項目符號,通常用於顯示元數據和詞彙表,但在實際應用中並不常見。
讓我們從簡單的部分開始——如何正確(至少在我看來)重置列表樣式。之後,我們將探討一些可訪問性問題,然後重點介紹難以捉摸的 <menu></menu>
元素,你可能會驚訝地發現……它實際上也是一種列表!
瀏覽器會自動應用其自身的 User Agent 樣式來幫助列表的視覺結構。這有時非常有用!但如果我們想從一個沒有樣式的空白狀態開始,那麼我們必須首先重置這些樣式。
例如,我們可以很容易地移除列表項旁邊的標記。這裡沒有什麼新東西:
/* 清除所有列表标记! */ ol, ul, menu { list-style: none; }
但是現代 CSS 提供了新的方法來幫助我們定位特定的列表實例。假設我們想要清除所有列表的標記,但如果這些列表出現在長篇內容(如文章)中,則保留標記。如果我們結合使用較新的 CSS 偽類函數 :where()
和 :not()
,我們可以隔離這些實例並在這些情況下允許標記:
/* 对于不是文章中的列表... */ :where(ol, ul, menu):not(article :where(ol, ul, menu)) { list-style: none; }
為什麼使用 :where()
而不是 :is()
? where()
的特異性始終為零,而 :is()
則採用其選擇器列表中最特定元素的特異性。因此,使用 :where()
是一個不太強制性的覆蓋方法,並且很容易被自身覆蓋。
UA 樣式還會應用填充,以將列表項的內容與其標記分隔開。在某些情況下,這是一種不錯的默認效果,但如果我們像上面那樣已經移除了列表標記,那麼我們不妨也清除該填充。這又是 :where()
的另一個用例:
/* 清除所有列表标记! */ ol, ul, menu { list-style: none; }
好的,這將防止無標記的列表項看起來懸浮在空間中。但是我們有點矯枉過正,在所有情況下都去除了填充,包括我們之前在 <article></article>
中隔離的那些。所以,現在那些帶有標記的列表有點懸掛在內容框的邊緣之外。
請注意,UA 樣式會額外向 <menu></menu>
元素應用 40px 的填充。所以我們要做的是防止列表標記“懸掛”在容器外部。我們可以使用 list-style-position
屬性來解決這個問題:
或者不……也許這取決於風格偏好?
不幸的是,即使在現代,列表也存在一些可訪問性問題。一個問題是應用 list-style: none;
的結果,就像我們在重置 UA 樣式時所做的那樣。
簡而言之,Safari 不會將使用 list-style: none;
樣式化的有序和無序列表讀取為實際列表,例如使用屏幕閱讀器導航內容時。換句話說,移除標記也會移除列表的語義含義。解決方法是在列表上應用 ARIA 列表角色,並在列表項上應用列表項角色,以便屏幕閱讀器可以識別它們:
/* 对于不是文章中的列表... */ :where(ol, ul, menu):not(article :where(ol, ul, menu)) { list-style: none; }
奇怪的是,Safari 將此視為一項功能而不是錯誤。基本上,用戶會報告屏幕閱讀器宣布了過多的列表(因為開發人員傾向於過度使用它們),所以現在,只有那些具有 role="list"
的列表才會被屏幕閱讀器宣布,這實際上並不奇怪。 Scott O’Hara 對這一切是如何發生的進行了詳細的描述。
第二個可訪問性問題不是我們造成的(萬歲!)。所以,你知道你應該為沒有標題的元素添加 aria-label
嗎?好吧,有時對不包含有助於描述列表的標題元素的列表執行相同的操作也是有意義的。
:where(ol, ul, menu) { padding-left: 0; /* 或 padding-inline-start */ }
你絕對不必使用這兩種方法。使用標題或 ARIA 標籤只是增加了上下文,而不是要求——請務必使用屏幕閱讀器測試你的網站,並選擇最適合當前情況的用戶體驗。
在相關的新聞中,Eric Bailey 寫了一篇關於為什麼以及如何認為 aria-label
是代碼異味的文章。
<menu></menu>
也是列表? 好的,所以,你可能想知道我一直在代碼示例中插入的所有 <menu></menu>
元素。這實際上非常簡單;菜單是無序列表,只是它們用於交互式項目。它們甚至在可訪問性樹中作為無序列表顯示。在語義網的早期,我錯誤地認為菜單類似於 <nav></nav>
,然後認為它們用於上下文菜單(或規範所說的“工具欄”),因為這是 HTML 規範的早期版本所說的。 (如果你感興趣,MDN 對所有與 <menu></menu>
相關的已棄用內容有一個有趣的介紹。)
然而,今天,這是使用菜單的語義方式:
/* 清除所有列表标记! */ ol, ul, menu { list-style: none; }
就我個人而言,我認為 <menu></menu>
有一些很好的用例。最後一個示例顯示了一個包含在帶標籤的 <menu></menu>
元素中的社交分享按鈕列表,值得注意的是,“分享文章”標籤貢獻了大量上下文,有助於描述按鈕的功能。菜單絕對必要嗎?不。它們是 HTML 里程碑嗎?絕對不是。但是,如果你喜歡更少的 <div>,並且你認為組件可以使用 <code>aria-label
來提供額外的上下文,那麼它們就在那裡。
是的,還有前面提到的 <dl></dl>
(描述列表)元素,但是,MDN 似乎並不認為它們與其他列表相同——它是由術語組成的組列表——而且我不能說我真正見過它們被使用。根據 MDN 的說法,它們應該用於元數據、詞彙表和其他類型的鍵值對。我會避免使用它們,因為所有屏幕閱讀器對它們的宣布方式都不同。但是,讓我們不要以負面評價結尾。以下是可以使用列表執行的一些非常酷的事情:
以上是關於好ol'HTML列表的較新的知識的詳細內容。更多資訊請關注PHP中文網其他相關文章!