CycleTracker: Base HTML and CSS
===============================

* Previous
* Overview: CycleTracker
* Next

To build a PWA, a progressive web application, we need to create a fully-functioning web application. In this section, we will markup the HTML for a static web page and enhance the appearance with CSS.

 Our project is to create CycleTracker, a menstrual cycle tracker.
 The first step in this introductory PWA tutorial is to write the HTML and CSS. The top section of the page is a form for the user to enter the start and end dates of each period. The bottom is a list of previous menstrual cycles.

We create an HTML file, with meta data in the head and a static web page containing a form and a placeholder to display user inputted data. We'll then add an external CSS stylesheet to improve the site's appearance.

To complete this tutorial, it is helpful to have a basic level of understanding of HTML, CSS, and JavaScript. If you're not familiar with these, MDN is the home of Getting Started, an introduction to web development series.

In the next sections, we'll set up a local development environment and take a look at our progress before adding JavaScript functionality to convert the static content created in this section into a functional web application. Once we have a functioning app we will have something that we can progressively enhance into a PWA that is installable and works offline.

Static web content
------------------

Our static site HTML, with placeholder `<link>` and `<script>` elements for yet-to-be-created external CSS and JavaScript files, is:


```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>
```


Copy this HTML and save it in a file called `index.html`.

HTML content
------------

Even if the HTML in `index.html` is familiar to you, we recommend reading through this section before adding some temporary hard-coded data, adding CSS to a `style.css` external stylesheet, and creating `app.js`, the application's JavaScript that makes this web page function.

The HTML's first line is a doctype preamble, which ensures the content behaves correctly.


```html
<!doctype html>
```


The root `<html>` tags wrap all the content with the `lang` attribute defining the primary language of the page.


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

### Document head

The `<head>` contains machine-readable information about the web application that's not visible to readers except for the `<title>`, which is displayed as the heading of the browser tab.

The `<head>` includes all the meta data. The first two bits of information in your `<head>` should always be the character set definition, which defines the character encoding, and the viewport `<meta>` tag, which ensures the page renders at the width of the viewport and isn't shrunken down when loaded on very small screens.


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


We set the title of the page to "Cycle Tracker" with the `<title>` element. While the contents of the `<head>` are not displayed within the page, the contents of the `<title>` are seen! The `<title>` element's inner text appears in the browser tab when the page is loaded, in search engine results, and is the default title used when a user bookmarks a web page. The title also provides an accessible name for screen reader users who depend on it to know which tab they're currently on.

While the title could be "Menstrual cycle tracking application", we opted for a shortened name that is more discreet.


```html
<title>Cycle Tracker</title>
```


While officially optional, for better user experience, these two `<meta>` tags and the `<title>` are the three components of the `<head>` that should be considered required components of any HTML document.

For right now, the last component we include in the `<head>` is a `<link>` element linking `style.css`, our yet-to-be-written stylesheet, to our HTML.


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


The HTML `<link>` element is used to specify a relationship between the current document and an external resource. There are more than 25 defined values for the `rel` attribute—and many more values that are not in any specification. The most common value, `rel="stylesheet"`, imports an external resource as a stylesheet.

We will revisit the `<link>` element and its `rel` attribute in a future section when we include the link to the manifest file.

### Document body

The `<body>` element contains all the content we want displayed when users visit the site on the Internet.

Within the `<body>`, we include the name of the app as a level-1 heading using an `<h1>` and a `<form>`.


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


The form will contain instructions, form controls, a label for each form control, and a submit button. In terms of form controls, we need the user to enter both a start date and an end date for each menstrual cycle submitted.

Within the `<form>`, we include a `<fieldset>` with a `<legend>` labeling the purpose of that set of form fields.


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


The date pickers are `<input>` elements of type date. We include the `required` attribute to reduce user errors by preventing the user from accidentally submitting an incomplete form.

To associate a `<label>` with a form control, each `<input>` has an `id` attribute matching the `for` attribute of the associated `<label>`. The associated label provides each `<input>` with an accessible name.


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


Putting it altogether, within the `<fieldset>`, we include two paragraphs (`<p>` elements), each with a date picker for the start and end dates of the menstrual cycle currently being entered, along with the date pickers' associated `<label>`s. We also include a `<button>` element which submits the form; we label it "Add period" by including that text between the opening and closing tags. The `type="submit"` is optional, as `submit` is the default type for `<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>
```


We encourage you to learn more about making accessible web forms.

### Temporary hard-coded results text

We then include an empty `<section>`. This container will be populated using JavaScript.


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


When the user submits the form, we will use JavaScript to capture the data and present a list of past periods along with a header for the section.

For the time being, we temporarily hardcode some content within this `<section>`, including an `<h2>` header and a few past periods, to have something to style as we write the page's 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>
```


This content, other than the container `<section id="past-periods"></section>`, is temporary. We will remove or comment-out this temporary data once we complete the CSS and are satisfied with the app's appearance.

### JavaScript link

Before closing the `</body>`, we include a link to the yet-to-be-written `app.js` JavaScript file. We include the `defer` attribute to defer the loading of this script and ensure the JavaScript is executed after the document's HTML has been parsed.


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


The `app.js` file will include all the workings of our application, including the event handlers for the `<button>`, saving the data submitted to local storage, and displaying cycles within the content of the body.

The HTML file for this step is now complete! You can open the file in your browser at this point, but you'll notice that it's quite plain. We'll fix that in the next section.

CSS content
-----------

We can now style the static HTML using CSS. Our final CSS is:


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


If every line is familiar to you, you can copy the above CSS, or write your own CSS, and save the file as `style.css`, then finish up the static HTML and CSS. If anything in the above CSS is new to you, keep reading for an explanation.

![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.](/en-US/docs/Web/Progressive_web_apps/Tutorials/CycleTracker/HTML_and_CSS/html.jpg)

### CSS explained

We use the `background-color` property to set a light green (`#efe`) background color on the `body`. Then on the unordered list, fieldset, and legend, we use a white (`#fff`) background color, along with a thin solid border added with the `border` property. We override the `background-color` for the legend, making the legend and the list items a darker green (`#cfc`).

We use the `:nth-of-type(even)` pseudo-class selector to set every even-numbered list item to `inherit` the background color from its parent; in this case, inheriting the `#fff` background color from the unordered list.


```css
body {
  background-color: #efe;
}
ul,
fieldset,
legend {
  border: 1px solid;
  background-color: #fff;
}
li,
legend {
  background-color: #cfc;
}
li:nth-of-type(even) {
  background-color: inherit;
}
```


To make the unordered list and list items not look like a list, we remove the padding by setting `padding: 0` on the `ul` and remove the list markers by setting `list-style-type: none` on the list items themselves.


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


We add a little white space by setting the `body`'s `margin` using the `vw` and `vh` viewport units, making white space on the outside of our app be proportional to the viewport's size. We also add a little padding to the `li` and `legend`. Finally, to improve, but not fix, the alignment of the past-periods data, we set the `font-family` of the `ul` results section to be `monospace`, making each glyph have the same fixed width.


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


We can combine the above, putting multiple properties in each selector declaration block. We can even put the styles for the `li` and `legend` together; irrelevant styles, like the `list-style-type` declaration on `legend`, are ignored.


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


If any of the above CSS still looks unfamiliar to you, you can look up the CSS properties and selectors, or work through the getting started with CSS learning path.

Whether you use the above CSS verbatim, edit the above styles to your preference, or write your own CSS from scratch, include all the CSS in a new file and save it as `style.css` in the same directory as your `index.html` file.

### Finishing the static HTML and CSS for our PWA

Before moving on, comment out or delete the fake past period data and header:


```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>
```

Up next
-------

Before adding the JavaScript functionality to convert this static content into a web app and then enhancing it into a progressive web app with a manifest file and service worker, we'll create a local development environment to view our progress.

Until then, you can view the static CycleTracker shell and download the CycleTracker HTML and CSS source code from GitHub.

* Previous
* Overview: CycleTracker
* Next