基本介紹如何針對電視、手機、電腦等裝置建構回應式橫向捲動檢視畫面。
在這篇文章中,我想分享一些方式來打造水平捲動網頁體驗,讓網頁和平台和平台 (例如電視) 的橫向捲動體驗變得最低、回應式且易於存取。立即試用示範。
如果你偏好使用影片,也可以觀看這篇 YouTube 文章:
總覽
我們將建構水平捲動版面配置,用來代管媒體或產品縮圖。這個元件一開始是以默示的 <ul>
清單開始,但經由 CSS 轉換成令人滿意且順暢的捲動體驗,進而展示圖片並貼齊至格狀版面。新增 JavaScript 以協助核准-索引互動,協助鍵盤使用者略過瀏覽 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
屬性。媒體捲動器的替代文字是一種使用者體驗商機,可協助提供縮圖的額外背景資訊;如果圖片無法載入,則會以備用文字呈現;如果圖片無法載入,則會提供語音 UI,供需要輔助技術 (例如螢幕閱讀器) 的使用者使用。詳情請參閱符合標準的替代文字的五大黃金規則。
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、App Store 及其他許多網站和應用程式會使用水平捲動區域,將可視區域封裝至類別和選項。
建立捲軸版面配置
請務必避免切斷版面配置中的內容,或以刪節號避免文字截斷。許多電視機都有和本類媒體捲動器一樣,但通常都很難看在略過內容。此版面配置不會!媒體內容也可讓媒體內容覆寫欄大小,讓 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;
}
}
突顯重點
這個元件的靈感來自於電視、App Store 等大受歡迎。許多電玩遊戲平台使用媒體捲軸非常類似,以作為主畫面的主要版面配置。重點是使用者體驗重大的時刻 不再只有小小的修改想像一下,在沙發上透過遙控器使用這個媒體捲軸時 可以稍做改進
.horizontal-media-scroller a {
outline-offset: 12px;
&:focus {
outline-offset: 7px;
}
@media (prefers-reduced-motion: no-preference) {
& {
transition: outline-offset .25s ease;
}
}
}
這會將焦點外框樣式 7px
從方塊外設定,使其留出一些空間。如果使用者對減少動作沒有動作偏好設定,系統會移動偏移,為聚焦事件提供細微的動作。
旋轉索引
在這些長串捲動內容和選項清單中,遊戲手把和鍵盤使用者需要特別留意。解決這個問題的常見模式稱為「核准索引」。這指的是一個項目的容器聚焦於鍵盤,但一次只允許 1 個子項處於聚焦狀態。以往,這個單一可聚焦項目就是在設計上可以略過可能過長的項目清單,而不是在抵達終點時按下 Tab 鍵超過 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。
顯示比例
本文撰寫本文時,在 Firefox 中會隱藏對 aspect-ratio
的支援,但只能在 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,由於這項功能已在更多的瀏覽器引擎中推出,因此管理方式較容易,但也更容易呈現出視覺效果更佳的版面配置。
偏好使用較少數據用量
雖然這項下一個技巧只能在初期測試旗標後方使用,但我想分享如何運用幾行 CSS 節省大量網頁載入時間和資料使用方式。第 5 級的 prefers-reduced-data
媒體查詢會詢問裝置是否處於任何資料縮減狀態,例如數據節省模式。如果有,我可以修改文件;在這種情況下,請隱藏圖片。
figure {
@media (prefers-reduced-data: reduce) {
& {
min-inline-size: var(--size);
& > picture {
display: none;
}
}
}
}
雖然內容仍可瀏覽,但無需下載大量圖片的代價。以下是新增 prefers-reduced-data
CSS 前的網站:
(7 個要求,131 毫秒為 100 KB 的資源)
以下是新增 prefers-reduced-data
CSS 後的網站成效:
(71 個要求,1.07 秒有 1.2 MB 的資源)
要求減少 64 則要求,也就是這個瀏覽器分頁可視區域範圍內約 60 張圖片 (以寬螢幕顯示進行測試) 和約 80% 的網頁載入,另外 10% 的資料來自線路。功能強大的 CSS
結論
現在你知道我怎麼做,你會怎麼做?🙂
讓我們帶您更多元的方法,並瞭解運用網路打造網站的所有方式。 建立 Codepen 或代管自己的示範影片,透過 Twitter 推文附上,我會將程式碼加到下方的「社群重混」部分。
資料來源
社群重混作品
這裡還沒有內容!