設計稿 - 台灣旅遊景點導覽,今天要實作的區塊是搜尋功能。
有興趣的朋友可以下載 GitHub 專案檔 一起來練習,今天是 Day 26 這個資料夾,example 為完成的範例,exercise 為練習檔,之後會陸續更新每天的進度。
外層區塊與左右兩邊的距離為 20px px:20
。
<section class="px:20"></section>
內部的圖片會使用絕對定位的方式稱滿整個區塊,因此給予相對定位 rel
,高度預設為 400px,視窗寬度 1024px 以上時 300px h:400 h:300@md
,內距上 60px、左右 20px,視窗寬度 1024px 以上時左右 0px p:60|20|0 px:0@md
,圓角 6px r:6
,超出的地方要隱藏 overflow:hidden
,最後將 h:300@md
以及 px:0@md
使用群組功能分組 {h:300;px:0}@md
。
<section class="px:20">
<div class="rel h:400 p:60|20|0 r:6 overflow:hidden {h:300;px:0}@md">
...
</div>
</section>
背景圖的部分總共有三張,這邊使用 picture 元素,根據寬度顯示對應的圖片。
<section class="px:20">
<div class="rel h:400 p:60|20|0 r:6 overflow:hidden {h:300;px:0}@md">
<picture>
<source
srcset="img/layout/banner-desktop.svg"
media="(min-width: 1024px)"
/>
<source
srcset="img/layout/banner-tablet.svg"
media="(min-width: 600px)"
/>
<img src="img/layout/banner-mobile.svg" alt="" />
</picture>
</div>
</section>
圖片的部分使用絕對定位在左上角 abs top:0 left:0
,z-index 給予 -1 置於最底部 z:-1
,最後寬高占滿整個區塊且維持原比例 full obj:cover
。
<section class="px:20">
<div class="rel h:400 p:60|20|0 r:6 overflow:hidden {h:300;px:0}@md">
<picture>
<source
srcset="img/layout/banner-desktop.svg"
media="(min-width: 1024px)"
/>
<source
srcset="img/layout/banner-tablet.svg"
media="(min-width: 600px)"
/>
<img
class="abs top:0 left:0 z:-1 full obj:cover"
src="img/layout/banner-mobile.svg"
alt=""
/>
</picture>
</div>
</section>
full
這個類名包含了 width: 100%;
以及 height: 100%;
這兩個屬性。
.full {
width: 100%;
height: 100%;
}
搜尋區塊預設寬度稱滿,視窗寬度 600px 以上時最大寬度 360px max-w:360@xs
,視窗寬度 1024px 以上時最大寬度 50% max-w:1/2@md
,區塊左右置中 mx:auto
。
<div class="mx:auto max-w:360@xs max-w:1/2@md">
...
</div>
標題大小預設 32px,視窗寬度 1024px 以上時 40px f:32 f:40@md
,文字字重 500 f:medium
,文字顏色為白色 f:white
,文字置中 t:center
,標題的 "探索" 兩字為主色,使用 span 標籤包起來給予 f:primary
。
<div class="mx:auto max-w:360@xs max-w:1/2@md">
<h1 class="f:32 f:medium f:white t:center f:40@md">
<span class="f:primary">探索</span> 想去的地方
</h1>
</div>
接著是網格的區塊,預設一個一列,視窗寬度 1024px 以上時兩個一列 grid-cols:1 grid-cols:2@md
,網格間距為 20px gap:20
,距離上方標題 20px mt:20
。
<div class="mx:auto max-w:360@xs max-w:1/2@md">
<h1 class="f:32 f:medium f:white t:center f:40@md">
<span class="f:primary">探索</span> 想去的地方
</h1>
<div class="grid-cols:1 gap:20 mt:20 grid-cols:2@md">
...
</div>
</div>
輸入框的按鈕會使用絕對定位,因此外層給予相對定位 rel
。
<div class="rel">
<input type="text" placeholder="搜尋關鍵字" />
<button type="button"></button>
</div>
輸入框稱滿網格 block w:full
,高度 48px h:48
,內距右 48px、左 16px pr:48 pl:16
,文字顏色 #393c43 f:fade-30
,白色背景 bg:white
,圓角 4px r:4
,陰影 shadow:0|10|20|black/.1
,互動的部分 focus 的時候給予 4px 的主色 outline outline:4|solid|primary:focus
,最後提示文字的顏色 #b9bbbe f:fade-40::placeholder
,::placeholder
語法在「Day 09 - 在元素上應用偽元素」這個單元有介紹過。
<input
class="block w:full h:48 pr:48 pl:16 f:fade-30 bg:white r:4 shadow:0|10|20|black/.1 outline:4|solid|primary:focus f:fade-40::placeholder"
type="text"
placeholder="搜尋關鍵字"
/>
按鈕的部分定位在右 8px、垂直置中 abs top:1/2 right:8 translateY(-50%)
,按鈕內的 icon 位於正中間 flex center-content
,寬高 32px w:32 h:32
,背景色為漸層色 primary 到 secondary bg:linear-gradient(primary,secondary)
,圓角 4px r:4
,互動的部分 hover 的時候給予 2px 的主色 outline outline:2|solid|primary:hover
。
<button
class="abs top:1/2 right:8 translateY(-50%) flex center-content w:32 h:32 bg:linear-gradient(primary,secondary) r:4 outline:2|solid|secondary:hover"
type="button"
>
<svg>...</svg>
</button>
icon 的部分使用 svg 原始碼,將顏色設定為白色 fill:white
。
<svg
class="fill:white"
width="16"
height="16"
viewBox="0 0 16 16"
>
<path
d="M10.3,11.7C9.2,12.6,7.9,13,6.5,13C2.9,13,0,10.1,0,6.5S2.9,0,6.5,0S13,2.9,13,6.5c0,1.4-0.4,2.7-1.3,3.8l4,4l-1.4,1.4L10.3,11.7z M2,6.5C2,9,4,11,6.5,11l0,0C9,11,11,9,11,6.5C11,4,9,2,6.5,2C4,2,2,4,2,6.5z"
/>
</svg>
輸入框區塊完整程式碼如下:
<div class="rel">
<input
class="block w:full h:48 pr:48 pl:16 f:fade-30 bg:white r:4 shadow:0|10|20|black/.1 outline:4|solid|primary:focus f:fade-40::placeholder"
type="text"
placeholder="搜尋關鍵字"
/>
<button
class="abs top:1/2 right:8 translateY(-50%) flex center-content w:32 h:32 bg:linear-gradient(primary,secondary) r:4 outline:2|solid|secondary:hover"
type="button"
>
<svg
class="fill:white"
width="16"
height="16"
viewBox="0 0 16 16"
>
<path
d="M10.3,11.7C9.2,12.6,7.9,13,6.5,13C2.9,13,0,10.1,0,6.5S2.9,0,6.5,0S13,2.9,13,6.5c0,1.4-0.4,2.7-1.3,3.8l4,4l-1.4,1.4L10.3,11.7z M2,6.5C2,9,4,11,6.5,11l0,0C9,11,11,9,11,6.5C11,4,9,2,6.5,2C4,2,2,4,2,6.5z"
/>
</svg>
</button>
</div>
下拉選單的箭頭會使用偽元素定位,因此外層給予相對定位 rel
。
<div class="rel">
<select>...</select>
</div>
下拉選單的樣式與輸入框大同小異 block w:full h:48 pr:48 pl:16 bg:white r:4 shadow:0|10|20|black/.1 outline:4|solid|primary:focus
,將下拉選單預設的箭頭隱藏因為要客製化箭頭樣式 appearance:none
。
<select
class="block w:full h:48 pr:48 pl:16 f:fade-30 bg:white r:4 shadow:0|10|20|black/.1 appearance:none outline:4|solid|primary:focus"
>
<option value="all">不分縣市</option>
<option value="taipei">臺北市</option>
<option value="taichung">臺中市</option>
<option value="kaohsiung">高雄市</option>
</select>
箭頭的部分為向下,寬 10px 高 8px 的三角形,透過 CSS 三角形產生器 這個網站產生下列 CSS 程式碼,轉換為 Master CSS 語法 w:0 h:0 border-width:8|5|0 border-style:solid border-color:fade-30|transparent|transparent
。
width: 0;
height: 0;
border-style: solid;
border-width: 8px 5px 0 5px;
border-color: #393c43 transparent transparent transparent;
這邊使用偽元素 ::before
來製作箭頭,偽元素若需要顯示需要給予 content content:''::before
,定位在右 16px,垂直置中 abs::before top:1/2::before right:16::before translateY(-50%)::before
,最後寫上箭頭的 CSS w:0::before h:0::before border-width:8|5|0::before border-style:solid::before border-color:fade-30|transparent|transparent::before
。
<div class="
rel
content:''::before
abs::before
top:1/2::before
right:16::before
translateY(-50%)::before
w:0::before
h:0::before
border-width:8|5|0::before
border-style:solid::before
border-color:fade-30|transparent|transparent::before
">
<select
class="block w:full h:48 pr:48 pl:16 f:fade-30 bg:white r:4 shadow:0|10|20|black/.1 appearance:none outline:4|solid|primary:focus"
>
<option value="all">不分縣市</option>
<option value="taipei">臺北市</option>
<option value="taichung">臺中市</option>
<option value="kaohsiung">高雄市</option>
</select>
</div>
可以看到上方的 ::before
語法重複很多次,因此使用 Master CSS 的群組功能來簡化 {content:'';abs;top:1/2;right:16;translateY(-50%);w:0;h:0;border-width:8|5|0;border-style:solid;border-color:fade-30|transparent|transparent}::before
。
<div
class="rel {content:'';abs;top:1/2;right:16;translateY(-50%);w:0;h:0;border-width:8|5|0;border-style:solid;border-color:fade-30|transparent|transparent}::before"
>
<select
class="block w:full h:48 pr:48 pl:16 f:fade-30 bg:white r:4 shadow:0|10|20|black/.1 appearance:none outline:4|solid|primary:focus"
>
<option value="all">不分縣市</option>
<option value="taipei">臺北市</option>
<option value="taichung">臺中市</option>
<option value="kaohsiung">高雄市</option>
</select>
</div>
編譯出來的 CSS 規則如下:
.\{content\:\'\'\;abs\;top\:1\/2\;right\:16\;translateY\(-50\%\)\;w\:0\;h\:0\;border-width\:8\|5\|0\;border-style\:solid\;border-color\:fade-30\|transparent\|transparent\}\:\:before::before {
content: "";
position: absolute;
top: 50%;
right: 1rem;
transform: translateY(-50%);
width: 0rem;
height: 0rem;
border-width: 0.5rem 0.3125rem 0rem;
border-style: solid;
border-color: rgb(57, 60, 67) transparent transparent;
}
最終我們使用 Master CSS 完成了搜尋功能的撰寫,完整架構如下:
<section class="px:20">
<div class="rel h:400 p:60|20|0 r:6 overflow:hidden {h:300;px:0}@md">
<picture>
<source
srcset="img/layout/banner-desktop.svg"
media="(min-width: 1024px)"
/>
<source
srcset="img/layout/banner-tablet.svg"
media="(min-width: 600px)"
/>
<img
class="abs top:0 left:0 z:-1 full obj:cover"
src="img/layout/banner-mobile.svg"
alt=""
/>
</picture>
<div class="mx:auto max-w:360@xs max-w:1/2@md">
<h1 class="f:32 f:medium f:white t:center f:40@md">
<span class="f:primary">探索</span> 想去的地方
</h1>
<div class="grid-cols:1 gap:20 mt:20 grid-cols:2@md">
<div class="rel">
<input
class="block w:full h:48 pr:48 pl:16 f:fade-30 bg:white r:4 shadow:0|10|20|black/.1 outline:4|solid|primary:focus f:fade-40::placeholder"
type="text"
placeholder="搜尋關鍵字"
/>
<button
class="abs top:1/2 right:8 translateY(-50%) flex center-content w:32 h:32 bg:linear-gradient(primary,secondary) r:4 outline:2|solid|secondary:hover"
type="button"
>
<svg
class="fill:white"
width="16"
height="16"
viewBox="0 0 16 16"
>
<path
d="M10.3,11.7C9.2,12.6,7.9,13,6.5,13C2.9,13,0,10.1,0,6.5S2.9,0,6.5,0S13,2.9,13,6.5c0,1.4-0.4,2.7-1.3,3.8l4,4l-1.4,1.4L10.3,11.7z M2,6.5C2,9,4,11,6.5,11l0,0C9,11,11,9,11,6.5C11,4,9,2,6.5,2C4,2,2,4,2,6.5z"
/>
</svg>
</button>
</div>
<div
class="rel {content:'';abs;top:1/2;right:16;translateY(-50%);w:0;h:0;border-width:8|5|0;border-style:solid;border-color:fade-30|transparent|transparent}::before"
>
<select
class="block w:full h:48 pr:48 pl:16 f:fade-30 bg:white r:4 shadow:0|10|20|black/.1 appearance:none outline:4|solid|primary:focus"
>
<option value="all">不分縣市</option>
<option value="taipei">臺北市</option>
<option value="taichung">臺中市</option>
<option value="kaohsiung">高雄市</option>
</select>
</div>
</div>
</div>
</div>
</section>
今天是實戰演練的第三天,有使用到偽元素的語法 ::placeholder
、::before
,不熟悉的朋友可以回到這幾個單元複習一下。