CycleTracker:基礎 HTML 和 CSS

要構建 PWA(漸進式 Web 應用),我們需要建立一個功能完善的 Web 應用。在本節中,我們將為靜態網頁標記 HTML,並使用 CSS 增強其外觀。

我們的專案是建立 CycleTracker,一個經期跟蹤器。本PWA 入門教程的第一步是編寫 HTML 和 CSS。頁面的頂部是使用者輸入每次經期開始和結束日期的表單。底部是之前經期週期的列表。

我們建立一個 HTML 檔案,在 head 中包含元資料,以及一個包含表單和顯示使用者輸入資料的佔位符的靜態網頁。然後,我們將新增一個外部 CSS 樣式表以改善網站的外觀。

要完成本教程,對 HTMLCSSJavaScript 有基本的瞭解會有幫助。如果您不熟悉這些,MDN 是入門系列(一個 Web 開發入門系列)的所在地。

在接下來的章節中,我們將設定一個本地開發環境,並檢視我們的進度,然後新增JavaScript 功能,將本節中建立的靜態內容轉換為功能性 Web 應用。一旦我們有了一個功能性應用,我們就可以逐步將其增強為一個可安裝和離線工作的 PWA。

靜態網頁內容

我們的靜態站點 HTML,包含用於尚未建立的外部 CSS 和 JavaScript 檔案的佔位符 <link><script> 元素,如下所示:

html
<!doctype html>
<html lang="en-US">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Cycle Tracker</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <h1>Period tracker</h1>
    <form>
      <fieldset>
        <legend>Enter your period start and end date</legend>
        <p>
          <label for="start-date">Start date</label>
          <input type="date" id="start-date" required />
        </p>
        <p>
          <label for="end-date">End date</label>
          <input type="date" id="end-date" required />
        </p>
      </fieldset>
      <p>
        <button type="submit">Add Period</button>
      </p>
    </form>
    <section id="past-periods"></section>
    <script src="app.js" defer></script>
  </body>
</html>

複製此 HTML 並將其儲存到名為 index.html 的檔案中。

HTML 內容

即使 index.html 中的 HTML 對您來說很熟悉,我們仍建議您閱讀本節,然後再新增一些臨時硬編碼資料,將 CSS 新增到 style.css 外部樣式表,並建立 app.js,即使此網頁工作的應用程式的 JavaScript

HTML 的第一行是 doctype 前言,它確保內容正確執行。

html
<!doctype html>

<html> 標籤包含所有內容,並使用 lang 屬性定義頁面的主要語言。

html
<!doctype html>
<html lang="en-US">
  <!-- the <head> and <body> will go here -->
</html>

文件頭部

<head> 包含有關 Web 應用程式的機器可讀資訊,除了 <title>(顯示為瀏覽器標籤頁的標題)之外,讀者不可見。

<head> 包含所有元資料<head> 中的前兩條資訊應該始終是字元集定義,它定義了字元編碼,以及視口 <meta> 標籤,它確保頁面以視口的寬度呈現,並且在載入到非常小的螢幕上時不會縮小。

html
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width" />
</head>

我們使用 <title> 元素將頁面的標題設定為“週期跟蹤器”。雖然 <head> 的內容不顯示在頁面中,但 <title> 的內容是可見的!<title> 元素的內部文字在頁面載入時出現在瀏覽器標籤頁中,在搜尋引擎結果中,並且是使用者收藏網頁時使用的預設標題。標題還為依賴它來了解當前所在標籤頁的螢幕閱讀器使用者提供了可訪問的名稱。

雖然標題可以是“月經週期跟蹤應用程式”,但我們選擇了更簡潔、更隱蔽的名稱。

html
<title>Cycle Tracker</title>

雖然官方是可選的,但為了更好的使用者體驗,這兩個 <meta> 標籤和 <title><head> 的三個元件,應被視為任何 HTML 文件的必需元件。

目前,我們包含在 <head> 中的最後一個元件是 <link> 元素,它將我們尚未編寫的樣式表 style.css 連結到我們的 HTML。

html
<link rel="stylesheet" href="style.css" />

HTML <link> 元素用於指定當前文件與外部資源之間的關係。對於 rel 屬性有超過 25 個定義值,還有許多未在任何規範中定義的值。最常用的值 rel="stylesheet" 將外部資源作為樣式表匯入。

我們將在後續章節中重新討論 <link> 元素及其 rel 屬性,屆時我們將包含清單檔案的連結

文件主體

<body> 元素包含所有我們希望使用者在網際網路上訪問網站時顯示的內容。

<body> 中,我們使用 <h1> 標題和 <form> 包含應用程式的名稱。

html
<body>
  <h1>Period tracker</h1>
  <form></form>
</body>

該表單將包含說明、表單控制元件、每個表單控制元件的標籤和提交按鈕。在表單控制元件方面,我們需要使用者輸入提交的每個月經週期的開始日期和結束日期。

<form> 中,我們包含一個帶有 <legend><fieldset>,用於標記該組表單欄位的目的。

html
<form>
  <fieldset>
    <legend>Enter your period start and end date</legend>
  </fieldset>
</form>

日期選擇器是 <input> 元素,型別為 日期。我們包含 required 屬性,透過防止使用者意外提交不完整的表單來減少使用者錯誤。

要將 <label> 與表單控制元件關聯,每個 <input> 都有一個 id 屬性,該屬性與關聯的 <label>for 屬性匹配。關聯的標籤為每個 <input> 提供一個可訪問的名稱

html
<label for="start-date">Start date</label>
<input type="date" id="start-date" required />

總而言之,在 <fieldset> 中,我們包含兩個段落(<p> 元素),每個段落都包含當前正在輸入的月經週期的開始和結束日期的日期選擇器,以及日期選擇器關聯的 <label>。我們還包含一個 <button> 元素,用於提交表單;我們透過在開始和結束標籤之間包含文字“新增經期”來標記它。type="submit" 是可選的,因為 submit<button> 的預設型別。

html
<form>
  <fieldset>
    <legend>Enter your period start and end date</legend>
    <p>
      <label for="start-date">Start date</label>
      <input type="date" id="start-date" required />
    </p>
    <p>
      <label for="end-date">End date</label>
      <input type="date" id="end-date" required />
    </p>
  </fieldset>
  <p>
    <button type="submit">Add Period</button>
  </p>
</form>

我們鼓勵您瞭解更多關於建立可訪問 Web 表單的資訊

臨時硬編碼結果文字

然後,我們包含一個空的 <section>。此容器將使用 JavaScript 填充。

html
<section id="past-periods"></section>

當用戶提交表單時,我們將使用 JavaScript 捕獲資料並顯示過去的經期列表以及該部分的標題。

目前,我們暫時在此 <section> 中硬編碼一些內容,包括一個 <h2> 標題和幾個過去的經期,以便在編寫頁面 CSS 時有一些樣式可以設定。

html
<section id="past-periods">
  <h2>Past periods</h2>
  <ul>
    <li>From 01/01/2024 to 01/06/2024</li>
    <li>From 01/29/2024 to 02/04/2024</li>
  </ul>
</section>

除了容器 <section id="past-periods"></section> 之外,此內容是臨時的。一旦我們完成 CSS 並對應用程式的外觀感到滿意,我們將刪除或註釋掉這些臨時資料。

在關閉 </body> 之前,我們包含一個指向尚未編寫的 app.js JavaScript 檔案的連結。我們包含 defer 屬性以延遲此指令碼的載入,並確保在解析文件的 HTML 之後執行 JavaScript。

html
<script src="app.js" defer></script>

app.js 檔案將包含我們應用程式的所有功能,包括 <button> 的事件處理程式,將提交的資料儲存到本地儲存,並在主體內容中顯示週期。

此步驟的 HTML 檔案現已完成!您此時可以在瀏覽器中開啟該檔案,但您會注意到它非常樸素。我們將在下一節中解決這個問題。

CSS 內容

我們現在可以使用 CSS 為靜態 HTML 設定樣式。我們最終的 CSS 是

css
body {
  margin: 1vh 1vw;
  background-color: #eeffee;
}
ul,
fieldset,
legend {
  border: 1px solid;
  background-color: white;
}
ul {
  padding: 0;
  font-family: monospace;
}
li,
legend {
  list-style-type: none;
  padding: 0.2em 0.5em;
  background-color: #ccffcc;
}
li:nth-of-type(even) {
  background-color: inherit;
}

如果每一行您都熟悉,您可以複製上述 CSS,或編寫您自己的 CSS,並將檔案儲存為 style.css,然後完成靜態 HTML 和 CSS。如果上述 CSS 中有任何您不熟悉的內容,請繼續閱讀解釋。

Light green web page with a large header, a form with a legend, two date pickers and a button. The bottom shows fake data for two menstrual cycles and a header.

CSS 解釋

我們使用 background-color 屬性為 body 設定淺綠色(#eeffee)背景色。然後,在無序列表、欄位集和圖例上,我們使用白色背景色,並使用 border 屬性新增細實線邊框。我們覆蓋了圖例的 background-color,使圖例和列表項變為更深的綠色(#ccffcc)。

我們使用 :nth-of-type(even) 偽類選擇器將每個偶數列表項設定為inherit其父級的背景色;在這種情況下,繼承無序列表的 white 背景色。

css
body {
  background-color: #eeffee;
}
ul,
fieldset,
legend {
  border: 1px solid;
  background-color: white;
}
li,
legend {
  background-color: #ccffcc;
}
li:nth-of-type(even) {
  background-color: inherit;
}

為了使無序列表和列表項看起來不像列表,我們透過將 ulpadding: 0 設定為 0 來移除填充,並透過將列表項本身的 list-style-type: none 設定為 none 來移除列表標記。

css
ul {
  padding: 0;
}
li {
  list-style-type: none;
}

我們透過使用 vwvh 視口單位設定 bodymargin 來新增一些空白,使應用程式外部的空白與視口的大小成比例。我們還為 lilegend 添加了一些填充。最後,為了改進但未完全修復過去經期資料的對齊方式,我們將 ul 結果部分的 font-family 設定為 monospace,使每個字形具有相同的固定寬度。

css
body {
  margin: 1vh 1vw;
}
ul {
  font-family: monospace;
}
li,
legend {
  padding: 0.2em 0.5em;
}

我們可以將上述內容結合起來,在每個選擇器宣告塊中放置多個屬性。我們甚至可以將 lilegend 的樣式放在一起;不相關的樣式,例如 legend 上的 list-style-type 宣告,將被忽略。

css
body {
  margin: 1vh 1vw;
  background-color: #eeffee;
}
ul,
fieldset,
legend {
  border: 1px solid;
  background-color: white;
}
ul {
  padding: 0;
  font-family: monospace;
}
li,
legend {
  list-style-type: none;
  padding: 0.2em 0.5em;
  background-color: #ccffcc;
}
li:nth-of-type(even) {
  background-color: inherit;
}

如果上述 CSS 中仍有您不熟悉的地方,您可以查閱 CSS 屬性選擇器,或者學習 CSS 樣式基礎模組。

無論您是原樣使用上述 CSS,根據您的喜好編輯上述樣式,還是從頭開始編寫您自己的 CSS,請將所有 CSS 包含在一個新檔案中,並將其儲存為 style.css,與您的 index.html 檔案在同一目錄中。

完成 PWA 的靜態 HTML 和 CSS

在繼續之前,註釋掉或刪除虛假的過去經期資料和標題

html
<section id="past-periods">
  <!--
  <h2>Past periods</h2>
  <ul>
    <li>From 01/01/2024 to 01/06/2024</li>
    <li>From 01/29/2024 to 02/04/2024</li>
  </ul>
  -->
</section>

接下來

在新增 JavaScript 功能將此靜態內容轉換為 Web 應用,然後使用清單檔案Service Worker將其增強為漸進式 Web 應用之前,我們將建立一個本地開發環境以檢視我們的進度。

在此之前,您可以檢視CycleTracker 靜態外殼,並從 GitHub 下載CycleTracker HTML 和 CSS 原始碼