iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0

https://i.imgur.com/lOdI7dV.jpg

組件實作 : Demo

一、前言

在行動裝置當道的時代,網頁的版面也隨著手機出現而有所改變,為了符合各種裝置較好的閱讀體驗,RWD 技術【1】也隨之誕生。我們今天要使用 CSS 的 Media queries【2】來實作一個瀑布流排版,規劃如下:在桌機會以 4 欄布局呈現,切換到平板變成 2 欄布局,而在手機上則是單欄佈局的版面。


二、直接實作 RWD 圖片瀑布流

我們知道最簡單的圖片排版,只要將圖片的寬度設定為100%,圖片的寬度就會隨著螢幕大小縮放,寫法可以像是:

CSS:

.rwd__img {
  width: 100%;
  max-width: 500px;
  height: auto;
}

這樣寫可以做出簡單的圖片RWD【3】。接下來,我們要來做一個圖片的瀑布流排版。

首先,先用一個 Class 名稱為rows的 div,裡面加入 Class 名稱為column的 div,column裡面再包住你要的圖片元素img

HTML:

<div class="rows">
    <div class="column">
		<img src="https://source.unsplash.com/random/600x400?sig=1" />
</div>

column 裡面圖片根據需求來存放照片張數,照片會以直排顯示。在 rows 裡面可以放入多個 column 來當作欄數,因為我們最多要在桌機上顯示 4 個欄位,全部程式碼架構如下。

HTML:

<div class="rows">
	<div class="column">
		<img src="https://source.unsplash.com/random/600x400?sig=1" />
		<img src="https://source.unsplash.com/random/600x400?sig=2" />
		<img src="https://source.unsplash.com/random/600x800?sig=3" />
		<img src="https://source.unsplash.com/random/600x400?sig=4" />
		<img src="https://source.unsplash.com/random/600x400?sig=5" />
		<img src="https://source.unsplash.com/random/600x1000?sig=6" />
		<img src="https://source.unsplash.com/random/600x400?sig=7" />
		<img src="https://source.unsplash.com/random/600x400?sig=8" />
		<img src="https://source.unsplash.com/random/600x100?sig=9" />
		<img src="https://source.unsplash.com/random/600x400?sig=10" />
	</div>

	<div class="column">
		<img src="https://picsum.photos/300/300?random=1" />
		<img src="https://picsum.photos/600/200?random=2" />
		<img src="https://picsum.photos/600/400?random=3" />
		<img src="https://picsum.photos/600/400?random=4" />
		<img src="https://picsum.photos/600/300?random=5" />
		<img src="https://picsum.photos/600/400?random=6" />
		<img src="https://picsum.photos/600/400?random=7" />
		<img src="https://picsum.photos/600/400?random=8" />
		<img src="https://picsum.photos/600/400?random=9" />
		<img src="https://picsum.photos/600/400?random=10" />
	</div>
	<div class="column">
		<img src="https://picsum.photos/600/400?random=11" />
		<img src="https://picsum.photos/600/200?random=12" />
		<img src="https://picsum.photos/600/400?random=13" />
		<img src="https://picsum.photos/600/800?random=14" />
		<img src="https://picsum.photos/600/400?random=15" />
		<img src="https://picsum.photos/600/400?random=16" />
		<img src="https://picsum.photos/600/400?random=17" />
		<img src="https://picsum.photos/600/400?random=18" />
		<img src="https://picsum.photos/600/400?random=19" />
		<img src="https://picsum.photos/600/400?random=20" />
	</div>

	<div class="column">
		<img src="https://picsum.photos/600/400?random=21" />
		<img src="https://picsum.photos/600/800?random=22" />
		<img src="https://picsum.photos/600/400?random=23" />
		<img src="https://picsum.photos/600/400?random=24" />
		<img src="https://picsum.photos/600/400?random=25" />
		<img src="https://picsum.photos/600/400?random=26" />
		<img src="https://picsum.photos/600/400?random=27" />
		<img src="https://picsum.photos/600/400?random=28" />
		<img src="https://picsum.photos/600/800?random=29" />
		<img src="https://picsum.photos/600/400?random=30" />
	</div>
</div>

我們要先做手機的排版,把rowsdisplay設定為 flex,這樣不管在哪種螢幕寬度上,預設都是會橫排,flex-wrap設定為wrap則是超過父層寬度時會自動換行。在img設定上,我們讓圖片可以自動縮放,只需設定width:100%;即可,而vertical-align設定成middle則是為了解決圖片底部可能出現白邊的問題。

CSS:

.rows {
	display: flex;
	flex-wrap: wrap;
}
.rows img {
	width: 100%;
	vertical-align: middle;
	margin-top: 8px;
}

顯示結果:

https://i.imgur.com/pFGjHDO.jpg


三、Media Queries 的實作

在手機排版會式單欄的排版效果。圖片的高度主要來自於圖片本身,高度經由縮放比例而隨之變動,接著重頭戲我們要來處理 RWD 切換的排版,我常用的 RWD 模板(Media queries)長這樣。

CSS:

@media (min-width: 575.98px) { }
@media (min-width: 767.98px) { }
@media (min-width: 991.98px) { }
@media (min-width: 1199.98px) { }
@media (min-width: 1399.98px) { }

因為我們是以 mobile first,所以用min-width來判斷裝置的寬度,min-width 指的是最小以上,使用數值對應如下:

  1. 575.98px:手機直屏
  2. 767.98px:手機橫屏
  3. 991.98px:平板直屏
  4. 1199.98px:平板橫屏
  5. 1399.98px:桌機

這些數值參考 Bootstrap 5 的寫法【4】。

@media (min-width: 767.98px) {
	.column {
		flex: 50%;
		max-width: 50%;
		padding: 0 4px;
	}
}

@media (min-width: 1199.98px) {
	.rows {
		justify-content: center;
	}
	.column {
		flex: 25%;
		padding: 0 4px;
		max-width: 300px;
	}
}

顯示結果:

https://i.imgur.com/w79SAMM.jpg

我們發現大於 767.98px時,圖片沒有正常的顯示,這就代表圖片寬度超出了container的寬度,這時將box-sizing設定成border-box,這樣寫可以讓borderpadding不會額外的增加空間,此時圖片就能夠正常的排版。

CSS:

* {
	font-family: Arial;
	text-align: center;
	box-sizing: border-box;
}

我們在 CSS 順便設定font-family字型,以及在 HTML 補上一些文字。

HTML:

<h2>Responsive Image Grid</h2>
<h4>Resize the browser window to see the responsive effect.</h4>

顯示結果:

  1. 4欄

https://i.imgur.com/qRO4mh9.jpg

  1. 2欄

https://i.imgur.com/LVfWE4O.jpg

  1. 單欄

https://i.imgur.com/iYQKzvX.jpg

關於 flexbox 用法可以參考 Flexbox【5】,flex: 25%;這種用法能參考 MDN 的 flex


四、推薦資源

  1. CSS Media Queries - Examples
  2. 使用CSS Grid實現瀑布流布局
  3. RWD是什麼?響應式CSS怎麼寫?5分鐘快速指南!
  4. 【RWD關鍵】CSS media屬性判別使用裝置:(RWD)響應式網頁、手機網頁設計、CSS Media應用

五、結論

如果圖片的寬高都一樣,display可以使用grid來做,會做出很整齊、漂亮的版面。但是要用 Grid 做成瀑布流的排版,目前沒有找到最佳的解法【6】,有機會再深入研究。另外,瀑布流的排版方式,其實可以添加一些動畫特效,讓畫面更有互動性,那麼今天介紹就到這邊,感謝收看!


六、參考資料

  1. 回應式網頁設計
  2. Media queries
  3. Responsive Images
  4. Breakpoints
  5. A Complete Guide to Flexbox
  6. Masonry layout

上一篇
Day 07:Card 組件實作
下一篇
Day 09:Form 組件實作
系列文
從零開始手刻網站,30 天打造我的前端武器庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言