設計稿 - 台灣旅遊景點導覽,今天要實作的區塊是景點列表,共分為三個部分。
有興趣的朋友可以下載 GitHub 專案檔 一起來練習,今天是 Day 27 這個資料夾,example 為完成的範例,exercise 為練習檔,之後會陸續更新每天的進度。
外層區塊與四邊的距離為上 40px、左右 20px、下 60px p:40|20|60
。
<section class="p:40|20|60"></section>
標題左側的裝飾線條會使用偽元素絕對定位,因此給予相對定位 rel
,內距為左 16px pl:16
,大小 24px f:24
,字重 400 f:regular
,白色 f:white
,數字的部分為主色,因此使用 span 元素包起來給予 f:primary
。
<h2 class="rel pl:16 f:24 f:regular f:white">
搜尋結果,共有 <span class="f:primary">64</span> 筆
</h2>
左側裝飾線條因為使用偽元素的關係,需要給予 content 才會顯示 content:''::before
,定位於左上角 abs::before top:0::before left:0::before
,寬度 4px 高度 100% w:4::before h:full::before
, 背景白色 bg:white::before
,右上及右下的圓角 4px rr:4::before
。
<h2 class="
rel pl:16 f:24 f:regular f:white
content:''::before
abs::before
top:0::before
left:0::before
w:4::before
h:full::before
bg:white::before
rr:4::before"
>
搜尋結果,共有 <span class="f:primary">64</span> 筆
</h2>
可以看到上方的 ::before
語法重複很多次,使用群組功能簡化 {content:'';abs;top:0;left:0;w:4;h:full;bg:white;rr:4}::before
。
<h2
class="rel pl:16 f:24 f:regular f:white {content:'';abs;top:0;left:0;w:4;h:full;bg:white;rr:4}::before"
>
搜尋結果,共有 <span class="f:primary">64</span> 筆
</h2>
接著是網格的區塊,預設一個一列,視窗寬度 600px 以上時兩個一列,視窗寬度 1024px 以上時三個一列,視窗寬度 1600px 以上時四個一列,視窗寬度 1920px 以上時五個一列 grid-cols:1 grid-cols:2@xs grid-cols:3@md grid-cols:4@2xl grid-cols:5@3xl
,網格間距為 20px gap:20
,距離上方標題 20px mt:20
。
<div
class="grid-cols:1 gap:20 mt:20 grid-cols:2@xs grid-cols:3@md grid-cols:4@2xl grid-cols:5@3xl"
>
...
</div>
右上角加入最愛的按鈕會根據卡片做絕對定位,因此卡片給予相對定位 rel
,背景色 #393c43 bg:fade-30
,圓角 6px r:6
,超出的地方隱藏 overflow:hidden
。
<div class="rel bg:fade-30 r:6 overflow:hidden">
...
</div>
按鈕定位於上 16px、右 16px abs top:16 right:16
,z-index 給高一點的數值避免被下方元素覆蓋 z:10
,icon 位於正中間 flex center-content
,寬高 40px w:40 h:40
,背景白色且為圓形 bg:white round
,icon 的部分使用 svg 原始碼,將顏色設定為 #b9bbbe fill:fade-40
,給予 0.2 秒的 transition 過渡 ~fill|.2s
,互動的部分按鈕 hover 的時候 icon 變成主色 fill:primary:hover_svg
。
<div class="rel bg:fade-30 r:6 overflow:hidden">
<button
class="abs top:16 right:16 z:10 flex center-content w:40 h:40 bg:white round fill:primary:hover_svg"
type="button"
>
<svg
class="fill:fade-40 ~fill|.2s"
width="16"
height="16"
viewBox="0 0 16 16"
>
<path
d="M14.7,2.8c-0.4-0.4-0.9-0.7-1.4-0.9c-0.6-0.2-1.1-0.3-1.8-0.3c-0.6,0-1.2,0.1-1.8,0.4C9.2,2.2,8.7,2.6,8.3,3C8.2,3.2,8.1,3.3,8,3.4C7.9,3.3,7.8,3.2,7.7,3C7.3,2.6,6.8,2.2,6.2,1.9C5.7,1.7,5.1,1.5,4.5,1.5c-0.6,0-1.2,0.1-1.8,0.3c-0.5,0.2-1,0.5-1.4,0.9C0.5,3.6,0,4.7,0,5.8C0,6.4,0.1,7,0.3,7.5c0.2,0.5,0.6,1,0.9,1.4c0.4,0.4,6.2,5.4,6.7,5.6c0.6-0.2,6.2-5.2,6.7-5.6C15.5,8.1,16,7,16,5.8c0-0.6-0.1-1.1-0.3-1.7C15.4,3.6,15.1,3.2,14.7,2.8z"
/>
</svg>
</button>
</div>
圖片為連結區塊,高度 200px h:200
,背景色 #202225 bg:fade-10
,超出的地方隱藏 overflow:hidden
,圖片稱滿外層 a 連結且維持原比例 full obj:cover
,給予 0.3 秒的 transition 過渡 ~transform|.3s
,互動的部分 hover 連結的時候裡面的圖片放大 1.1 倍 scale(1.1):hover_img
。
<div class="rel bg:fade-30 r:6 overflow:hidden">
<button>...</button>
<a
class="block h:200 bg:fade-10 overflow:hidden scale(1.1):hover_img"
>
<img
class="full obj:cover ~transform|.3s"
src="img/attractions/attraction-1.jpg"
alt=""
/>
</a>
</div>
內容區塊的內距為上 24px、左右 24px、下 40px p:24|24|40
。
<div class="rel bg:fade-30 r:6 overflow:hidden">
<button>...</button>
<a>...</a>
<div class="p:24|24|40">
...
</div>
</div>
標題 20px f:20
,字重 400 f:regular
,白色 f:white
。
<div class="rel bg:fade-30 r:6 overflow:hidden">
<button>...</button>
<a>...</a>
<div class="p:24|24|40">
<h3 class="f:20 f:regular f:white">帆船鼻大草原</h3>
</div>
</div>
內文距離上方標題 12px mt:12
,顏色 #b9bbbe f:fade-40
,行高 1.75 lh:1.75
,行數最多顯示三行,當超過的時候顯示 … 文字 lines:3
。
<div class="rel bg:fade-30 r:6 overflow:hidden">
<button>...</button>
<a>...</a>
<div class="p:24|24|40">
<h3 class="f:20 f:regular f:white">帆船鼻大草原</h3>
<p class="mt:12 f:fade-40 lh:1.75 lines:3">
帆船鼻位於綠島東南角,有「綠島地毯」之稱,可由朝日溫泉售票口旁邊的小徑沿步道而上。由於地形突出,地勢又高出四周,屬東北季季風可長驅直入的衝風帶;再加...
</p>
</div>
</div>
地點及開放時間左右排列,超過自動換行 flex flex:wrap
,間距為左右 30px、上下 12px gap-x:30 gap-y:12
,距離上方內文 24px mt:24
,icon 及文字左右排列靠上對齊 flex ai:flex-start
,文字稍微往上 -2px、往左 10px mt:-2 ml:10
,白色 f:white
,行高 1.75 lh:1.75
。
<div class="rel bg:fade-30 r:6 overflow:hidden">
<button>...</button>
<a>...</a>
<div class="p:24|24|40">
<h3 class="f:20 f:regular f:white">帆船鼻大草原</h3>
<p class="mt:12 f:fade-40 lh:1.75">
帆船鼻位於綠島東南角,有「綠島地毯」之稱,可由朝日溫泉售票口旁邊的小徑沿步道而上。由於地形突出,地勢又高出四周,屬東北季季風可長驅直入的衝風帶;再加...
</p>
<div class="flex flex:wrap gap-x:30 gap-y:12 mt:24">
<div class="flex ai:flex-start">
<img src="img/icon/icon-location.svg" alt="" />
<span class="mt:-2 ml:10 f:white lh:1.75">臺東縣</span>
</div>
<div class="flex ai:flex-start">
<img src="img/icon/icon-clock.svg" alt="" />
<span class="mt:-2 ml:10 f:white lh:1.75">全天候開放</span>
</div>
</div>
</div>
</div>
分頁區塊左右排列、水平置中 flex jc:center
,距離上方卡片列表 40px mt:40
。
<div class="flex jc:center mt:40">
<a>...</a>
<div>...</div>
<a>...</a>
</div>
按鈕內的 icon 位於正中間 flex center-content
,寬高 48px w:48 h:48
,背景色 #393c43 bg:fade-30
,圓角 6px
,給予 0.2 秒的 transition 過渡 ~background-color|.2s
,互動的部分 hover 的時候背景色變成 #202225 bg:fade-10:hover
,
<a
class="flex center-content w:48 h:48 bg:fade-30 r:6 ~background-color|.2s bg:fade-10:hover"
>
<svg>...</svg>
</a>
icon 的部分使用 svg 原始碼,將顏色設定為白色 fill:white
。
<!-- 左側箭頭 svg 原始碼 -->
<svg class="fill:white" width="8" height="14" viewBox="0 0 8 14">
<path
d="M7,14c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4l6-6c0.4-0.4,1-0.4,1.4,0c0.4,0.4,0.4,1,0,1.4L2.4,7l5.3,5.3c0.4,0.4,0.4,1,0,1.4C7.5,13.9,7.3,14,7,14L7,14z"
/>
</svg>
<!-- 右側箭頭 svg 原始碼 -->
<svg class="fill:white" width="8" height="14" viewBox="0 0 8 14">
<path
d="M1,0c0.3,0,0.5,0.1,0.7,0.3l6,6c0.4,0.4,0.4,1,0,1.4l-6,6c-0.4,0.4-1,0.4-1.4,0c-0.4-0.4-0.4-1,0-1.4L5.6,7L0.3,1.7c-0.4-0.4-0.4-1,0-1.4C0.5,0.1,0.7,0,1,0L1,0z"
/>
</svg>
中間區塊的元素左右排列、垂直置中 flex ai:center
,高度 48px h:48
,內距為右 24px、左 8px pr:24 pl:8
,與左右兩顆按鈕的距離為 10px mx:10
,白色文字 f:white
,背景色 #393c43 bg:fade-30
,圓角 6px r:6
。
<div
class="flex ai:center h:48 pr:24 pl:8 mx:10 f:white bg:fade-30 r:6"
>
<div>...</div>
<span>...</span>
<a>...</a>
</div>
下拉選單的寫法跟昨天的「Day 26 -【實戰演練】台灣旅遊景點 - 搜尋功能」單元介紹的非常類似,這邊就不再贅述,斜線距離左右 10px mx:10
,右側的連結給予 0.2 秒的 transition 過渡 ~color|.2s
,最後互動的部分 hover 的時候顏色改為 #b9bbbe f:fade-40:hover
。
<div
class="flex ai:center h:48 pr:24 pl:8 mx:10 f:white bg:fade-30 r:6"
>
<div
class="rel {content:'';abs;top:1/2;right:12;translateY(-50%);w:0;h:0;border-width:4|2.5|0;border-style:solid;border-color:white|transparent|transparent}::before"
>
<select
class="w:80 h:32 px:12 bg:fade-10 r:4 appearance:none outline:2|solid|primary:focus"
>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
<span class="mx:10">/</span>
<a class="~color|.2s f:fade-40:hover">6</a>
</div>
最終我們使用 Master CSS 完成了景點列表的撰寫,完整架構如下:
<section class="p:40|20|60">
<!-- 標題區塊 -->
<h2
class="rel pl:16 f:24 f:regular f:white {content:'';abs;top:0;left:0;w:4;h:full;bg:white;rr:4}::before"
>
搜尋結果,共有 <span class="f:primary">64</span> 筆
</h2>
<!-- 卡片列表 -->
<div
class="grid-cols:1 gap:20 mt:20 grid-cols:2@xs grid-cols:3@md grid-cols:4@2xl grid-cols:5@3xl"
>
<div class="rel bg:fade-30 r:6 overflow:hidden">
<button
class="abs top:16 right:16 z:10 flex center-content w:40 h:40 bg:white round"
type="button"
>
<svg
class="fill:fade-40"
width="16"
height="16"
viewBox="0 0 16 16"
>
<path
d="M14.7,2.8c-0.4-0.4-0.9-0.7-1.4-0.9c-0.6-0.2-1.1-0.3-1.8-0.3c-0.6,0-1.2,0.1-1.8,0.4C9.2,2.2,8.7,2.6,8.3,3C8.2,3.2,8.1,3.3,8,3.4C7.9,3.3,7.8,3.2,7.7,3C7.3,2.6,6.8,2.2,6.2,1.9C5.7,1.7,5.1,1.5,4.5,1.5c-0.6,0-1.2,0.1-1.8,0.3c-0.5,0.2-1,0.5-1.4,0.9C0.5,3.6,0,4.7,0,5.8C0,6.4,0.1,7,0.3,7.5c0.2,0.5,0.6,1,0.9,1.4c0.4,0.4,6.2,5.4,6.7,5.6c0.6-0.2,6.2-5.2,6.7-5.6C15.5,8.1,16,7,16,5.8c0-0.6-0.1-1.1-0.3-1.7C15.4,3.6,15.1,3.2,14.7,2.8z"
/>
</svg>
</button>
<a
class="block h:200 bg:fade-10 overflow:hidden scale(1.1):hover_img"
>
<img
class="full obj:cover ~transform|.3s"
src="img/attractions/attraction-1.jpg"
alt=""
/>
</a>
<div class="p:24|24|40">
<h3 class="f:20 f:regular f:white">帆船鼻大草原</h3>
<p class="mt:12 f:fade-40 lh:1.75 lines:3">
帆船鼻位於綠島東南角,有「綠島地毯」之稱,可由朝日溫泉售票口旁邊的小徑沿步道而上。由於地形突出,地勢又高出四周,屬東北季季風可長驅直入的衝風帶;再加帆船鼻位於綠島東南角,有「綠島地毯」之稱,可由朝日溫泉售票口旁邊的小徑沿步道而上。由於地形突出,地勢又高出四周,屬東北季季風可長驅直入的衝風帶;再加
</p>
<div class="flex flex:wrap gap-x:30 gap-y:12 mt:24">
<div class="flex ai:flex-start">
<img src="img/icon/icon-location.svg" alt="" />
<span class="mt:-2 ml:10 f:white lh:1.75">臺東縣</span>
</div>
<div class="flex ai:flex-start">
<img src="img/icon/icon-clock.svg" alt="" />
<span class="mt:-2 ml:10 f:white lh:1.75">全天候開放</span>
</div>
</div>
</div>
</div>
</div>
<!-- 分頁區塊 -->
<div class="flex jc:center mt:40">
<a
class="flex center-content w:48 h:48 bg:fade-30 r:6 ~background-color|.2s bg:fade-10:hover"
>
<svg class="fill:white" width="8" height="14" viewBox="0 0 8 14">
<path
d="M7,14c-0.3,0-0.5-0.1-0.7-0.3l-6-6c-0.4-0.4-0.4-1,0-1.4l6-6c0.4-0.4,1-0.4,1.4,0c0.4,0.4,0.4,1,0,1.4L2.4,7l5.3,5.3c0.4,0.4,0.4,1,0,1.4C7.5,13.9,7.3,14,7,14L7,14z"
/>
</svg>
</a>
<div
class="flex ai:center h:48 pr:24 pl:8 mx:10 f:white bg:fade-30 r:6"
>
<div
class="rel {content:'';abs;top:1/2;right:12;translateY(-50%);w:0;h:0;border-width:4|2.5|0;border-style:solid;border-color:white|transparent|transparent}::before"
>
<select
class="w:80 h:32 px:12 bg:fade-10 r:4 appearance:none outline:2|solid|primary:focus"
>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</div>
<span class="mx:10">/</span>
<a class="~color|.2s f:fade-40:hover">6</a>
</div>
<a
class="flex center-content w:48 h:48 bg:fade-30 r:6 ~background-color|.2s bg:fade-10:hover"
>
<svg class="fill:white" width="8" height="14" viewBox="0 0 8 14">
<path
d="M1,0c0.3,0,0.5,0.1,0.7,0.3l6,6c0.4,0.4,0.4,1,0,1.4l-6,6c-0.4,0.4-1,0.4-1.4,0c-0.4-0.4-0.4-1,0-1.4L5.6,7L0.3,1.7c-0.4-0.4-0.4-1,0-1.4C0.5,0.1,0.7,0,1,0L1,0z"
/>
</svg>
</a>
</div>
</section>
今天是實戰演練的第四天,相信大家已經逐漸熟悉 Master CSS 的語法了,Master CSS 能夠讓開發者全程專注在 HTML 上面,只要稍微熟悉它的語法,就能快速建構出用戶介面。