網頁表單樣式

在之前的幾篇文章中,我們展示瞭如何在 HTML 中建立網頁表單。現在,我們將展示如何在 CSS 中為它們設定樣式。

先決條件 HTMLCSS 的基本理解。
目標 瞭解表單樣式背後的問題,並學習一些對您有用的基本樣式技術。

表單小部件樣式方面的挑戰

歷史

1995 年,HTML 2 規範 引入了表單控制元件(也稱為“表單小部件”或“表單元素”)。但 CSS 直到 1996 年末才釋出,而且直到幾年後才被大多數瀏覽器支援;因此,在此期間,瀏覽器依賴於底層作業系統來渲染表單小部件。

即使有了 CSS,瀏覽器供應商最初也不願使表單元素可樣式化,因為使用者已經習慣了各自瀏覽器的外觀。但情況已經發生了變化,現在表單小部件大多是可樣式化的,但也有一些例外。

小部件型別

易於樣式化

  1. <form>
  2. <fieldset><legend>
  3. 單行文字 <input>(例如型別文字、url、電子郵件),除了 <input type="search">
  4. 多行 <textarea>
  5. 按鈕(<input><button> 兩種)
  6. <label>
  7. <output>

難以樣式化

文章 高階表單樣式 展示瞭如何對這些進行樣式化。

具有內部元件的元素無法僅用 CSS 進行樣式化

例如,日期選擇器日曆和 <select> 上的按鈕(單擊時顯示選項列表)無法僅使用 CSS 進行樣式化。

文章 高階表單樣式如何構建自定義表單控制元件 描述瞭如何對這些進行樣式化。

注意: 一些專有的 CSS 偽元素,例如 ::-moz-range-track,能夠對這些內部元件進行樣式化,但這些在瀏覽器之間不一致,因此不太可靠。我們稍後會提到這些。

簡單表單小部件的樣式

上一節中的“易於樣式化”小部件可以使用文章 您的第一個表單CSS 構建塊 中的技術進行樣式化。還有一些特殊的選擇器——UI 偽類——可以根據 UI 的當前狀態啟用樣式化。

我們將在本文末尾逐步介紹一個示例——但首先,這裡有一些值得了解的關於表單樣式的特殊方面。

字型和文字

CSS 字型和文字功能可以輕鬆地與任何小部件一起使用(是的,您可以在表單小部件中使用 @font-face)。但是,瀏覽器的行為通常不一致。預設情況下,一些小部件不會從其父元素繼承 font-familyfont-size。許多瀏覽器使用系統的預設外觀。為了使表單的外觀與您內容的其餘部分保持一致,您可以將以下規則新增到您的樣式表中

css
button,
input,
select,
textarea {
  font-family: inherit;
  font-size: 100%;
}

inherit 屬性值會導致屬性值與父元素屬性的計算值匹配;繼承父元素的值。

下面的螢幕截圖顯示了差異。左側是 <input type="text"><input type="date"><select><textarea><input type="submit"><button> 在 macOS 上的 Chrome 中的預設渲染,使用平臺的預設字型樣式。右側是相同的元素,應用了我們上面的樣式規則。

Form controls with default and inherited font families. By default, some types are serif and others are sans serif. Inheriting should change the fonts of all to the parent's font family - in this case a paragraph. Oddly, input of type submit does not inherit from the parent paragraph.

預設值在許多方面有所不同。繼承應該將它們的字型更改為父元素的字體系列——在本例中,是父容器的預設襯線字型。它們都這樣做了,但有一個奇怪的例外——<input type="submit"> 在 Chrome 中沒有從父段落繼承。相反,它使用 font-family: system-ui。這是使用 <button> 元素而不是等效輸入型別的另一個原因!

關於表單是否應該使用系統預設樣式或自定義樣式(旨在與您的內容匹配)存在很多爭論。這個決定由您作為網站或 Web 應用程式的設計者來決定。

盒子大小

所有文字欄位都完全支援與 CSS 盒模型相關的每個屬性,例如 widthheightpaddingmarginborder。但是,如前所述,瀏覽器在顯示這些小部件時依賴於系統預設樣式。您需要決定如何將它們與您的內容融合在一起。如果您想保留小部件的原生外觀和感覺,那麼如果您想賦予它們一致的大小,您將面臨一些困難。

這是因為每個小部件都有自己的邊框、填充和邊距規則。 要使幾個不同的視窗小部件具有相同的大小,可以使用 box-sizing 屬性以及其他屬性的一些一致值

css
input,
textarea,
select,
button {
  width: 150px;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

在下面的螢幕截圖中,左列顯示了 <input type="radio"><input type="checkbox"><input type="range"><input type="text"><input type="date"><select><textarea><input type="submit"><button> 的預設渲染。另一方面,右列顯示了應用了我們上面的規則的相同元素。注意,這使我們能夠確保所有元素都佔據相同的空間,儘管平臺為每種型別的視窗小部件設定了預設規則。

box model properties effect most input types.

螢幕截圖可能無法顯示的是,單選按鈕和複選框控制元件仍然看起來一樣,但它們在 width 屬性提供的 150 畫素的水平空間中居中。其他瀏覽器可能不會將小部件居中,但它們確實會遵守分配的空間。

圖例放置

<legend> 元素可以進行樣式化,但控制其放置可能有點棘手。預設情況下,它始終位於其 <fieldset> 父元素的頂部邊框上方,靠近左上角。要將其放置在其他位置,例如在 fieldset 中的某個位置或靠近左下角,您需要依賴於定位。

以以下示例為例

要以這種方式定點陣圖例,我們使用了以下 CSS(出於簡潔起見,刪除了其他宣告)

css
fieldset {
  position: relative;
}

legend {
  position: absolute;
  bottom: 0;
  right: 0;
}

<fieldset> 也需要定位,以便 <legend> 相對於它定位(否則 <legend> 將相對於 <body> 定位)。

<legend> 元素對於可訪問性非常重要——它將被輔助技術作為 fieldset 內每個表單元素的標籤的一部分進行朗讀——但使用像上面這樣的技術是可以的。圖例內容仍然會以相同的方式朗讀;只是視覺位置發生了變化。

注意: 您也可以使用 transform 屬性來幫助您定位 <legend>。但是,當您使用例如 transform: translateY(); 定位它時,它會移動,但在 <fieldset> 邊框中留下了難看的間隙,這很難消除。

一個具體的樣式示例

讓我們看看如何對 HTML 表單進行樣式化的具體示例。我們將構建一個外觀奇特的“明信片”聯絡表單;此處檢視完成版本.

如果您想按照此示例操作,請製作 postcard-start.html 檔案 的本地副本,並按照以下說明操作。

HTML

HTML 只是比我們在 本指南的第一篇文章 中使用的示例稍微複雜一些;它只有一些額外的 ID 和標題。

html
<form>
  <h1>to: Mozilla</h1>

  <div id="from">
    <label for="name">from:</label>
    <input type="text" id="name" name="user_name" />
  </div>

  <div id="reply">
    <label for="mail">reply:</label>
    <input type="email" id="mail" name="user_email" />
  </div>

  <div id="message">
    <label for="msg">Your message:</label>
    <textarea id="msg" name="user_message"></textarea>
  </div>

  <div class="button">
    <button type="submit">Send your message</button>
  </div>
</form>

將以上程式碼新增到 HTML 的 body 中。

組織您的資產

這就是樂趣開始的地方!在開始編碼之前,我們需要三個額外的資產

  1. 明信片背景——下載此影像並將其儲存到與您的工作 HTML 檔案相同的目錄中。
  2. 打字機字型:dafont.com 上的“Mom's Typewriter”字型——將 TTF 檔案下載到與上面相同的目錄中。
  3. 手繪字型:dafont.com 上的“Journal”字型——將 TTF 檔案下載到與上面相同的目錄中。

您的字型需要在開始之前進行更多處理

  1. 轉到 fontsquirrel.com 的 Webfont Generator
  2. 使用表單上傳您的兩個字型檔案並生成一個 Web 字型工具包。將工具包下載到您的計算機。
  3. 解壓縮提供的 zip 檔案。
  4. 在解壓縮的內容中,您會找到一些字型檔案(在撰寫本文時,兩個 .woff 檔案和兩個 .woff2 檔案;它們將來可能會有所不同。)將這些檔案複製到名為 fonts 的目錄中,與之前相同的目錄中。我們使用每個字型的兩個不同檔案來最大限度地提高瀏覽器相容性;有關更多資訊,請參閱我們的 Web 字型 文章。

CSS

現在我們可以深入研究示例的 CSS。將下面顯示的所有程式碼塊依次新增到 <style> 元素中。

整體佈局

首先,我們透過定義 @font-face 規則以及對 <body><form> 元素設定的所有基本樣式來進行準備。如果 fontsquirrel 的輸出與我們上面描述的不同,您可以在下載的 Web 字型工具包中的 stylesheet.css 檔案中找到正確的 @font-face 塊(您需要用它們替換下面的 @font-face 塊,並更新到字型檔案的路徑)

css
@font-face {
  font-family: "handwriting";
  src:
    url("fonts/journal-webfont.woff2") format("woff2"),
    url("fonts/journal-webfont.woff") format("woff");
  font-weight: normal;
  font-style: normal;
}

@font-face {
  font-family: "typewriter";
  src:
    url("fonts/momot___-webfont.woff2") format("woff2"),
    url("fonts/momot___-webfont.woff") format("woff");
  font-weight: normal;
  font-style: normal;
}

body {
  font: 1.3rem sans-serif;
  padding: 0.5em;
  margin: 0;
  background: #222;
}

form {
  position: relative;
  width: 740px;
  height: 498px;
  margin: 0 auto;
  padding: 1em;
  box-sizing: border-box;
  background: #fff url(background.jpg);

  /* we create our grid */
  display: grid;
  grid-gap: 20px;
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: 10em 1em 1em 1em;
}

注意,我們使用了一些 CSS 網格Flexbox 來佈局表單。使用它,我們可以輕鬆地定位我們的元素,包括標題和所有表單元素

css
h1 {
  font:
    1em "typewriter",
    monospace;
  align-self: end;
}

#message {
  grid-row: 1 / 5;
}

#from,
#reply {
  display: flex;
}

標籤和控制元件

現在我們可以開始處理表單元素本身。首先,讓我們確保 <label> 使用正確的字型。

css
label {
  font:
    0.8em "typewriter",
    sans-serif;
}

文字欄位需要一些通用的規則。換句話說,我們刪除它們的 bordersbackgrounds,並重新定義它們的 paddingmargin

css
input,
textarea {
  font:
    1.4em/1.5em "handwriting",
    cursive,
    sans-serif;
  border: none;
  padding: 0 10px;
  margin: 0;
  width: 80%;
  background: none;
}

當這些欄位中的一個獲得焦點時,我們使用淺灰色透明背景突出顯示它們(對於可用性和鍵盤可訪問性,始終擁有焦點樣式非常重要)

css
input:focus,
textarea:focus {
  background: rgb(0 0 0 / 10%);
  border-radius: 5px;
}

現在我們的文字欄位已經完成,我們需要調整單行和多行文字欄位的顯示以匹配,因為它們使用預設值通常看起來不一樣。

調整文字區域

<textarea> 元素預設渲染為內聯塊元素。這裡有兩個重要的屬性:resizeoverflow。雖然我們的設計是固定大小的,我們可以使用 resize 屬性來阻止使用者調整多行文字欄位的大小,但最好不要阻止使用者調整 textarea 的大小,如果他們願意的話。使用 overflow 屬性可以使欄位在不同瀏覽器中的渲染更加一致。一些瀏覽器預設值為 auto,而另一些則預設值為 scroll。在我們的例子中,最好確保每個人都使用 auto

css
textarea {
  display: block;

  padding: 10px;
  margin: 10px 0 0 -10px;
  width: 100%;
  height: 90%;

  border-right: 1px solid;

  /* resize  : none; */
  overflow: auto;
}

設定提交按鈕樣式

<button> 元素用 CSS 設定樣式非常方便,您可以隨意操作,甚至可以使用 偽元素

css
button {
  padding: 5px;
  font: bold 0.6em sans-serif;
  border: 2px solid #333;
  border-radius: 5px;
  background: none;
  cursor: pointer;
  transform: rotate(-1.5deg);
}

button:after {
  content: " >>>";
}

button:hover,
button:focus {
  background: #000;
  color: #fff;
}

最終結果

瞧!您的表單現在應該看起來像這樣

The final look and layout of the form after applying all styling and tweaking to it as described above

注意:如果您的示例沒有按照您的預期工作,並且您想將其與我們的版本進行比較,您可以在 GitHub 上找到它 - 檢視它 執行中(也可以檢視 原始碼)。

測試您的技能

您已閱讀完本文,但您能記住最重要的資訊嗎?在您繼續之前,您可以進行一些進一步的測試,以驗證您是否保留了這些資訊 - 請檢視 測試您的技能:樣式基礎

總結

如您所見,只要我們想使用文字欄位和按鈕構建表單,就可以輕鬆地使用 CSS 對其進行樣式設定。在 下一篇文章 中,我們將看到如何處理屬於“糟糕”和“醜陋”類別的表單小部件。

高階主題