iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0
自我挑戰組

掌握 Master CSS 優化開發體驗系列 第 26

Day 26 -【實戰演練】台灣旅遊景點 - 搜尋功能

  • 分享至 

  • xImage
  •  

實戰演練 - Day 03

設計稿 - 台灣旅遊景點導覽,今天要實作的區塊是搜尋功能。

https://ithelp.ithome.com.tw/upload/images/20221008/20103817COpZ2wg1T4.jpg

GitHub 專案檔

有興趣的朋友可以下載 GitHub 專案檔 一起來練習,今天是 Day 26 這個資料夾,example 為完成的範例,exercise 為練習檔,之後會陸續更新每天的進度。

外層區塊

https://ithelp.ithome.com.tw/upload/images/20221008/20103817EmHkesnr3E.jpg

外層區塊與左右兩邊的距離為 20px px:20

<section class="px:20"></section>

主要區塊

https://ithelp.ithome.com.tw/upload/images/20221009/20103817aYOU0wz37g.jpg

內部的圖片會使用絕對定位的方式稱滿整個區塊,因此給予相對定位 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>

背景圖區塊

https://ithelp.ithome.com.tw/upload/images/20221009/20103817hzaQELHnuD.jpg

背景圖的部分總共有三張,這邊使用 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%;
}

搜尋區塊

https://ithelp.ithome.com.tw/upload/images/20221009/20103817Otaf6AulD3.jpg

搜尋區塊預設寬度稱滿,視窗寬度 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>

輸入框區塊

https://ithelp.ithome.com.tw/upload/images/20221009/20103817XGpxpa6Wqx.jpg

輸入框的按鈕會使用絕對定位,因此外層給予相對定位 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>

下拉選單區塊

https://ithelp.ithome.com.tw/upload/images/20221009/20103817RweZU5pbz8.jpg

下拉選單的箭頭會使用偽元素定位,因此外層給予相對定位 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>

總結

GitHub Repo
GitHub Pages

今天是實戰演練的第三天,有使用到偽元素的語法 ::placeholder::before,不熟悉的朋友可以回到這幾個單元複習一下。

參考


上一篇
Day 25 -【實戰演練】台灣旅遊景點 - 分類按鈕
下一篇
Day 27 -【實戰演練】台灣旅遊景點 - 景點列表
系列文
掌握 Master CSS 優化開發體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言