動手練一練,使用 Flexbox 創建一個響應式的表單

  • 2020 年 2 月 26 日
  • 筆記

大家好,今天我將和大家一起動手做個練習,使用 Flexbox 布局創建一個響應式的表單,本篇文章不會和大家生硬的去介紹 Flexbox 知識點,而是通過實踐的形式去理解 Flexbox 布局。剛學前端時,大家會不會覺得CSS太容易了,沒有過多實踐,就開始上手實踐JS和相關的前端框架了,一遇到一些樣式的問題,就開始慌了,無從下手。CSS學好用好,也是需要花功夫的,不要因為CSS簡單了,就輕視了,畢竟作為一個專業的前端,要給大家呈現產品美感,更多考驗的是 CSS 的功底。

表單項目長啥樣?

好了,給大家嘮叨多了,讓我們回到本節的案例,雖然例子簡單,但是要做漂亮了,是需要花功夫的,這裡我們不使用媒介查詢屬性,完全使用 Flexbox 布局就能創建一個完美的響應式表單,在動手之前,我們來看看,我們例子長什麼樣?

創建表單 HTML 結構

好了,基於上面的長相,我們開始動手創建表單的 HTML 結構:

  • 創建 .flex-outer 無序列表包裹整個表單元素。
  • 接著在內部創建 .flex-inner 無序列包裹複選表單元素。
  • 幾乎所有的表單都有其對應的 label 元素,方便擴大表單元素的點擊區域。

僅此而已,我們通過定義了兩個無序列表創建了一個簡單表單結構,示例程式碼如下:

<div class="container">   <form>    <ul class="flex-outer">      <li>        <label for="first-name">First Name</label>        <input type="text" id="first-name" placeholder="Enter your first name here">      </li>      <li>        <label for="last-name">Last Name</label>        <input type="text" id="last-name" placeholder="Enter your last name here">      </li>      <li>        <label for="email">Email</label>        <input type="email" id="email" placeholder="Enter your email here">      </li>      <li>        <label for="phone">Phone</label>        <input type="tel" id="phone" placeholder="Enter your phone here">      </li>      <li>        <label for="message">Message</label>        <textarea rows="6" id="message" placeholder="Enter your message here"></textarea>      </li>      <li>        <p>Age</p>        <ul class="flex-inner">          <!-- list items here -->        </ul>      </li>      <li>        <button type="submit">Submit</button>      </li>    </ul>   </form>  </div>

接下來我們創建 .flex-inner 元素及年齡選擇部分,示例程式碼如下:

<ul class="flex-inner">    <li>      <input type="checkbox" id="twenty-to-twentynine">      <label for="twenty-to-twentynine">20-29</label>    </li>    <li>      <input type="checkbox" id="thirty-to-thirtynine">      <label for="thirty-to-thirtynine">30-39</label>    </li>    <!-- more list items here -->  </ul>

完成以上結構後,我們的頁面長這樣:

基本的模樣有了,我們需要藉助CSS進行美化,長這樣,我們怎麼好意思拿的出手。

定義表單樣式

1、接下來,我們來定義 flex 容器,在這個例子中,我們在以下元素進行應用:

  • .flex-outer 列表中的元素
  • 在 .flex-inner 的 checkboxes 元素

此外,我們需要讓這些彈性元素在 cross-axis 軸方向垂直居中,並支援溢出換行:

.flex-outer li,  .flex-inner {    display: flex;    flex-wrap: wrap;    align-items: center;  }

2、接下來我們來定義彈性盒子的寬度,我們先從定義 .flex-outer 列表的元素開始 。

我們的需求是這樣的:

  • 每個 labels 的寬度至少為120px, 最多為220px。
  • 每個表單元素的寬度至少為220px

通過這個需求,我們應該明確表單寬度至少為340px, lable 與對應的表單元素水平並排顯示。

上述的值,你可以根據自己的需求自行修改

最終我們完成後的程式碼如下所示:

.flex-outer > li > label,  .flex-outer li p {    flex: 1 0 120px;    max-width: 220px;  }    .flex-outer > li > label + *,  .flex-inner {    flex: 1 0 220px;  }

完成後的效果如下圖所示:

定義提交按鈕樣式

我們繼續來定義提交按鈕的樣式,其也是彈性元素,基本的樣式程式碼如下:

.flex-outer li button {    margin-left: auto;    padding: 8px 16px;    border: none;    background: #333;    color: #f2f2f2;    text-transform: uppercase;    letter-spacing: .09em;    border-radius: 2px;  }

處理 Checkboxes 的樣式

接著我們繼續處理複選框 Checkboxes 的樣式,在定義基礎表單樣式時,我們設置了.flex-inner 容器的最小寬度為220px。

1、首先我們來處理下每個 Checkbox 的寬度,設置其父元素 li 標籤的寬度為100px:

.flex-inner li {    width: 100px;  }

2、接著我們來使用 justify-content 屬性來定義元素在 main-axis 的顯示方式,這裡我使用了 space-between 對齊方式。

.flex-inner {    justify-content: space-between;  }

使用這個屬性,能讓我們很好的均勻的對齊元素,唯一不足時,每行項目不相等時,最後一行的對齊方式也許不是你期望看到的。

如上圖所示,也許你希望最後兩個元素相鄰顯示,不是分的這麼開,我么該如何做呢?

  • 首先移除 justify-content 的對齊屬性
  • 修正每個彈性盒子的寬度,比如寬度為50%
  • 使用媒介查詢器,當螢幕寬度大於 992px 時,我們添加彈性盒子的寬度,讓其寬度為25%。

通過以上學習,我們有兩點需要明確的是:

  • flex 布局為我們提供了極大的靈活性,讓我們可以快速的構建漂亮表格。
  • 上述CSS具體的值只是適用本示例,你可以根據自己的需求進行調整。例如,我們這裡的年齡複選框定義的寬度很小,才100px, 如果他們的寬度不同的話,你可以使用 flex: 1 100px 來定義寬度,彈性盒子能足夠智慧化的處理對齊問題。

最終完成的樣式

完成上述基本的架子後,我們需要讓表單更加漂亮些,比如添加樣式,定義文字大小、盒子的內間距、寬度等,由於文章篇幅有限,這裡就不過多介紹了,最終完成的 CSS 程式碼如下所示:

body {    font: normal 18px/1.5 "Fira Sans", "Helvetica Neue", sans-serif;    background: #3AAFAB;    color: #fff;    padding: 50px 0;  }    .container {    width: 80%;    max-width: 1200px;    margin: 0 auto;  }    .container * {    box-sizing: border-box;  }    .flex-outer,  .flex-inner {    list-style-type: none;    padding: 0;  }    .flex-outer {    max-width: 800px;    margin: 0 auto;  }    .flex-outer li,  .flex-inner {    display: flex;    flex-wrap: wrap;    align-items: center;  }    .flex-inner {    padding: 0 8px;    justify-content: space-between;  }    .flex-outer > li:not(:last-child) {    margin-bottom: 20px;  }    .flex-outer li label,  .flex-outer li p {    padding: 8px;    font-weight: 300;    letter-spacing: .09em;    text-transform: uppercase;  }    .flex-outer > li > label,  .flex-outer li p {    flex: 1 0 120px;    max-width: 220px;  }    .flex-outer > li > label + *,  .flex-inner {    flex: 1 0 220px;  }    .flex-outer li p {    margin: 0;  }    .flex-outer li input:not([type='checkbox']),  .flex-outer li textarea {    padding: 15px;    border: none;  }    .flex-outer li button {    margin-left: auto;    padding: 8px 16px;    border: none;    background: #333;    color: #f2f2f2;    text-transform: uppercase;    letter-spacing: .09em;    border-radius: 2px;  }    .flex-inner li {    width: 100px;  }

小節

到這裡,本示例就完成了,我們用最少最簡單的方式使用 flexbox 布局完成了響應式表單的創建,大家可以訪問以下網址,在線體驗效果:

https://www.qianduandaren.com/demo/flexform/

最後分享給大家一張圖,方便大家記憶和學習彈性盒子布局。