Carousel 輪播、CSS grid 與 CSS scroll-snap | 用 React 造輪子

YY
7 min readFeb 1, 2020
Photo by Alex Grodkiewicz on Unsplash

如今,carousel 已悄悄地佔據了你我生活的一大部分,像是 Instagram 的多圖貼文、Facebook 等 app 的限時動態列表、Medium app 的 Reading list 與 Topics For You、YouTube Music 的音樂清單、(…下略 1000 字),以及在各式電商平台中也絕對少不了

因此在網頁開發上有很大的機會要處理到 carousel 也就是輪播 (圖片輪播、商品卡輪播等),但喜歡 <del>造輪子</del> 精進自我的你且為了兼顧老闆的需求,於是決定放棄打開 google 輸入 react grid carousel 找尋相關套件而是打開了編輯器準備動手做一個,但…要怎麼開始呢?

CSS grid

欸不是,這篇不是來講 carousel 的嗎

在進入正題前先描繪一下我所想像的 carousel,反正就是有很多頁,每頁裡面有一列甚至多列的很多格子陳列物品,然後在 mobile 下單獨顯示單一物品並可以左右滑動

Product carousel on https://tw.buy.yahoo.com/
City carousel on https://www.klook.com/
News carousel on https://answers.yahoo.com

說到很多「頁」、一列甚至多「列」、很多「格子」,就讓人想用 CSS grid 來處理這一切,這邊會將整個 carousel 視為 grid container,而每一頁則是 grid item 同時也是個 grid container 包著每個你想陳列出來的 item

藉由 grid-template-columns & grid-template-rows 來決定每頁的 layout,以及 grid-gap 管理每個 item 間距

至於更多的 CSS grid 可以參考下文

Carousel

進入主題,如何做出一個輪播元件,來人啊~把 code 給我端上來

首先在 src/index.jsApp 中可以看到這邊的輪播元件設計為一個 Carousel 容器可以設定每頁要有幾欄 cols 以及項目間隔 gap ,接著把所有想放進來的項目都包在 Carousel.Item ,最後就變成以每頁 cols 個項目來呈現的輪播元件

再來看看 src/Carousel.js 的架構,包含了一個 container、上下頁按鈕 Carousel__btn--prev & Carousel__btn--next 以及主體 Carousel__railWrapperCarousel__railCarousel__ItemSet

part of src/Carousel.js

其中最關鍵的就是 Carousel__railWrapperCarousel__rail,後者即是包著每一頁的 grid container,並透過 css grid-template-columns 設定頁數以及left 來換頁

在搞定了分頁的 layout 後來看看 Carousel__ItemSet ,這邊的 item set 即為「一頁」,將包著 cols 個 items,一樣透過 grid-template-columnsgrid-gap 來設定每一頁的 layout,在這之前要先做一些簡單的資料處理把一堆 Carousel.Item 依照給予的 cols 做分頁

part of src/Carousel.js

最後就是加上前後頁的按鈕、綁上事件與 state 就可以完成一個基本的 carousel 囉

scroll-snap

Article carousel on Medium app

在許多 app 或 mobile web 中時常看到像上圖這種一次只滑動一個項目的 carousel,透過 css 中的 scroll-snap-typescroll-snap-align 就可達到這樣的效果,更詳細的使用方式可以參考下列文章

react-grid-carousel

最後,如果你覺得上述的步驟很麻煩,但也想要個可以設定多欄多列的 carousel,又能在 mobile 大小下有 scroll-snap 的效果,那你可以參考這個套件

Demo:

喜歡的話也歡迎順手幫 GitHub repo 按星星 🌟

如果你喜歡這篇文章可以拍 11 下手,不喜歡的話可以拍 1 下再分享給其他 5 個人,感恩~

--

--