說明如何為電視、手機、電腦等裝置建立回應式水平捲動檢視畫面。
在這篇文章中,我想分享如何為網路打造最精簡、回應式、方便操作且可在瀏覽器和平台 (例如電視) 上運作的橫向捲動體驗。試用示範模式。
如果你偏好觀看影片,請參閱這篇文章的 YouTube 版本:
總覽
我們將建構水平捲動版面配置,用於代管媒體或產品的縮圖。這個元件一開始只是簡單的 <ul>
清單,但經過 CSS 轉換後,便可提供令人滿意的流暢捲動體驗,展示圖片並將圖片套用至格狀檢視畫面。我們新增了 JavaScript,以便促進 roving-index 互動,協助鍵盤使用者略過超過 100 個項目的瀏覽。此外,實驗性媒體查詢 prefers-reduced-data
可用於將媒體捲軸轉換為輕量版標題捲軸體驗。
開始使用無障礙標記
媒體捲動器只包含幾個核心元件,以及包含項目的清單。最簡單的清單形式可以傳送到世界各地,並讓所有人清楚瞭解內容。進入這個頁面的使用者可以瀏覽清單,然後按一下連結來查看項目。這是我們的無障礙基礎。
使用 <ul>
元素提供清單:
<ul class="horizontal-media-scroller">
<li></li>
<li></li>
<li></li>
...
<ul>
使用 <a>
元素讓清單項目可供互動:
<li>
<a href="#">
...
</a>
</li>
使用 <figure>
元素以語意方式表示圖片及其標題:
<figure>
<picture>
<img alt="..." loading="lazy" src="https://picsum.photos/500/500?1">
</picture>
<figcaption>Legends</figcaption>
</figure>
請注意 <img>
上的 alt
和 loading
屬性。媒體捲動器的替代文字是一個使用者體驗機會,可協助顯示縮圖的額外背景資訊。如果圖片未載入,也能做為備用文字的替代文字,或為使用者提供語音使用者介面,讓他們仰賴螢幕閱讀器等輔助技術。如要進一步瞭解,請參閱五大關鍵規則,讓替代文字符合規範。
loading
屬性接受關鍵字 lazy
,用於指出只有在圖片位於檢視區範圍內時,才應擷取這個圖片來源。這對於大型清單來說非常實用,因為使用者只會下載他們捲動至畫面中的項目圖片。
支援使用者的色彩配置偏好設定
使用 color-scheme
做為 <meta>
標記,向瀏覽器傳達網頁需要淺色和深色提供的使用者代理程式樣式。這項免費功能可提供深色模式或淺色模式,具體取決於您如何查看:
<meta name="color-scheme" content="dark light">
元標記會提供最早的信號,因此如果使用者偏好深色主題,瀏覽器就能選取深色預設畫布顏色。也就是說,在網站的不同頁面之間瀏覽時,不會在載入期間閃爍白色畫布背景。載入後流暢的深色主題,在視覺上更加實用。
詳情請參閱 Thomas Steiner (https://web.dev/color-scheme/)。
新增內容
根據 ul > li > a > figure > picture > img
的內容結構,下一項工作是新增圖片和標題以捲動瀏覽。我已在示範中加入靜態預留位置圖片和文字,但您也可以使用自己偏好的資料來源。
使用 CSS 新增樣式
接著,CSS 會將這個一般內容清單轉換為體驗。Netflix、應用程式商店和許多其他網站和應用程式都會使用水平捲動區域,在檢視區中顯示多個類別和選項。
建立捲動器版面配置
請務必避免在版面配置中截斷內容,或使用刪節號截斷文字。許多電視機台都有像這是一種媒體捲動器 但其實都很擅長處理省略內容。但這個版面配置不會!它還可讓媒體內容覆寫欄大小,讓 1 個版面配置具有足夠的彈性,可處理許多有趣的組合。
容器可提供預設大小做為自訂屬性來覆寫資料欄大小。這個格狀版面配置會針對欄大小提供建議,只會管理間距和方向:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2); /* parent owned value for children to be relative to*/
margin: 0;
}
<picture>
元素接著會使用自訂屬性建立基本顯示比例:方塊:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
& picture {
inline-size: var(--size);
block-size: var(--size);
}
}
除了幾種次要樣式,請完成媒體捲軸的必備標準:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
& > li {
display: inline-block; /* removes the list-item bullet */
}
& picture {
inline-size: var(--size);
block-size: var(--size);
}
}
設定 overflow
會將 <ul>
設為允許捲動和鍵盤瀏覽清單,然後每個直接子項 <li>
元素都會因為取得新的 inline-block
顯示類型而移除其 ::marker
。
不過,圖片尚未回應,而且會直接從所屬的方塊中彈出。您可以使用一些大小、適合和邊框樣式,以及背景漸層來控制這些元素,以便在延遲載入時使用:
img {
/* smash into whatever box it's in */
inline-size: 100%;
block-size: 100%;
/* don't squish but do cover the space */
object-fit: cover;
/* soften the edges */
border-radius: 1ex;
overflow: hidden;
/* if empty, show a gradient placeholder */
background-image:
linear-gradient(
to bottom,
hsl(0 0% 40%),
hsl(0 0% 20%)
);
}
捲動邊框間距
對齊網頁內容,加上從邊到邊捲動的表面區域,對於打造和諧且簡約的元件至關重要。
如要完成從邊到邊捲動版面配置,並與我們的字體排版和版面配置線對齊,請使用與 scroll-padding
相符的 padding
:
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
padding-inline: var(--gap);
scroll-padding-inline: var(--gap);
padding-block: calc(var(--gap) / 2); /* make space for scrollbar and focus outline */
}
水平捲動邊框間距錯誤修正 上方說明如何輕鬆為捲動容器設定邊框間距,但其中仍有未解決的相容性問題 (不過,在 Chromium 91 以上版本已修正)。請參閱這篇文章,瞭解相關歷史資料。簡單來說,在捲動檢視畫面中,系統不一定會考量邊框間距。
為了讓瀏覽器將邊框間距放在捲軸的結尾,我會指定每個清單中的最後一個圖形,並附加一個所需邊框間距的虛擬元素。
.horizontal-media-scroller > li:last-of-type figure {
position: relative;
&::after {
content: "";
position: absolute;
inline-size: var(--gap);
block-size: 100%;
inset-block-start: 0;
inset-inline-end: calc(var(--gap) * -1);
}
}
使用邏輯屬性可讓媒體捲動器在任何書寫模式和文件方向中運作。
捲動貼齊
捲動容器 (含有溢位內容) 可透過一行 CSS 成為固定檢視區,然後由子項指定如何與該檢視區對齊。
.horizontal-media-scroller {
--size: 150px;
display: grid;
grid-auto-flow: column;
gap: calc(var(--gap) / 2);
margin: 0;
overflow-x: auto;
overscroll-behavior-inline: contain;
padding-inline: var(--gap);
scroll-padding-inline: var(--gap);
padding-block-end: calc(var(--gap) / 2);
scroll-snap-type: inline mandatory;
& figure {
scroll-snap-align: start;
}
}
專注
這個元件的靈感來自於電視、應用程式商店等平台的廣泛應用。許多電玩平台都會使用類似這個的媒體捲軸,做為主要的首頁版面配置。在這裡,「專注」是使用者體驗的巨大時刻假設你想在沙發上使用這個媒體捲動器,並透過遙控器進行互動,可以進行一些小幅改善:
.horizontal-media-scroller a {
outline-offset: 12px;
&:focus {
outline-offset: 7px;
}
@media (prefers-reduced-motion: no-preference) {
& {
transition: outline-offset .25s ease;
}
}
}
這會將焦點外框樣式 7px
設為遠離方塊,為其提供一些不錯的空間。如果使用者沒有減少動作偏好設定,系統會轉換偏移量,為焦點事件提供微妙的動作。
流動索引
在這些長長的捲動內容和選項清單中,遊戲控制器和鍵盤使用者需要特別留意。解決這個問題的常見模式稱為「漫遊索引」。當項目容器獲得鍵盤焦點,但一次只能允許 1 個子項保留焦點時,就會發生此錯誤。這個單一可聚焦項目一次一項的體驗設計,可讓您略過可能很長的項目清單,不必按下分頁鍵 50 次以上才能到達結尾。
示範的第一個捲動器只有 300 個項目我們可以做得更好,不必讓他們逐一檢查所有區段,才能到達下一個區段。
如要建立這項體驗,JavaScript 需要觀察鍵盤事件和焦點事件。我建立了npm 上的一個小型開放原始碼程式庫,方便實現這種使用者體驗。以下是如何為 3 個捲軸使用此方法:
import {rovingIndex} from 'roving-ux';
rovingIndex({
element: someElement
});
這個示範會查詢捲動器的文件,並為每個捲動器呼叫 rovingIndex()
函式。傳遞 rovingIndex()
元素,以便取得漫遊體驗 (例如清單容器),以及目標查詢選擇器 (如果焦點目標不是直接子項的話)。
document.querySelectorAll('.horizontal-media-scroller')
.forEach(scroller =>
rovingIndex({
element: scroller,
target: 'a',
}))
如要進一步瞭解此效果,請參閱開放原始碼程式庫 roving-ux。
顯示比例
截至本文撰寫時,aspect-ratio
的支援功能仍在 Firefox 的標記後方,但在 Chromium 瀏覽器或設定頂端方塊中可使用。由於媒體捲軸格線版面配置只會指定方向和間距,因此在媒體查詢中可變更大小,該功能會檢查是否支援顯示比例。漸進式強化功能,導入更動態的媒體捲動器。
@supports (aspect-ratio: 1) {
.horizontal-media-scroller figure > picture {
inline-size: auto; /* for a block-size driven ratio */
aspect-ratio: 1; /* boxes by default */
@nest section:nth-child(2) & {
aspect-ratio: 16/9;
}
@nest section:nth-child(3) & {
/* double the size of the others */
block-size: calc(var(--size) * 2);
aspect-ratio: 4/3;
/* adjust size to fit more items into the viewport */
@media (width <= 480px) {
block-size: calc(var(--size) * 1.5);
}
}
}
}
如果瀏覽器支援 aspect-ratio
語法,媒體捲軸圖片會升級為 aspect-ratio
大小。使用草稿巢狀結構語法時,每張相片的顯示比例會根據其位於第一、第二或第三列而有所不同。巢狀語法也允許設定一些小型檢視區調整,並與其他大小邏輯搭配使用。
有了 CSS,這項功能可在更多瀏覽器引擎中使用,因此會顯示易於管理但更具視覺吸引力的版面配置。
偏好使用較少的資料
雖然下列技巧僅適用於Canary 啟用標記的情況,但我想分享如何透過幾行 CSS 大幅縮短網頁載入時間和資料使用量。第 5 級的 prefers-reduced-data
媒體查詢可詢問裝置是否處於任何減少資料狀態,例如數據節省模式。如果是的話,我可以修改文件,在這種情況下,我會隱藏圖片。
figure {
@media (prefers-reduced-data: reduce) {
& {
min-inline-size: var(--size);
& > picture {
display: none;
}
}
}
}
使用者仍可瀏覽內容,但不會下載重型圖片,以下是新增 prefers-reduced-data
CSS 前的網站:
(7 個要求,100kb 的資源,耗時 131 毫秒)
新增 prefers-reduced-data
CSS 後,網站效能如下:
(71 個要求,1.2 mb 的資源,耗時 1.07 秒)
減少 64 個要求,也就是這個瀏覽器分頁的檢視區域內的約 60 張圖片 (在寬螢幕顯示器上進行測試),網頁載入速度提升約 80%,網路傳輸資料量減少 10%。相當強大的 CSS。
結論
現在你知道該怎麼做了,你會怎麼做?!🙂
讓我們多方嘗試,瞭解在網路上建構應用程式的所有方式。建立 Codepen 或自行發布示範內容,然後透過推文傳送給我,我會將其新增至下方的社群重混內容部分。
資料來源
社群重混作品
尚無任何資料可提供!