Styling with CSS

CSS (Cascading Style Sheets) controls how HTML elements look. Right now our app works, but it has no styling. Let’s fix that.

Starting with Inline Styles

The simplest way to add CSS is with the style attribute directly on an element. Try updating the <h1> in index.html:

<h1 style="color: purple;">WakeUp Times</h1>

Refresh. The heading is now purple. The style attribute contains CSS written as property: value; pairs.

This works, but it has problems:

  • Styles are mixed with content
  • You would have to repeat styles on every element
  • Hard to maintain as your site grows

Remove the inline style before continuing.

Moving Styles to a Style Tag

A better approach is to put CSS in a <style> tag in the <head>. Add this to the <head> section:

<head>
  <!-- ... existing meta tags ... -->
  <style>
    h1 {
      color: purple;
    }
  </style>
</head>

Refresh. Same result, but now the style is separate from the content. The h1 before the curly braces is a selector. It targets all <h1> elements on the page.

This is better, but for larger projects, mixing CSS with HTML in the same file still gets messy.

Creating an External CSS File

The best practice is to keep CSS in a separate file. Create a CSS file:

touch index.css

Link it in index.html. Add this line in the <head> section, after the title:

    <title>WakeUp Times</title>
+   <link rel="stylesheet" href="index.css" />
  </head>

The rel attribute specifies the relationship between the current document and the linked file. In this case, it is a stylesheet.

Now remove the <style> tag we added earlier. We will put all our styles in index.css from now on.

CSS Selectors

CSS rules have a selector and property: value pairs:

selector {
  property: value;
}

There are three main types of selectors:

Selector Syntax Matches
Element body All <body> elements
Class .cycle Elements with class="cycle"
ID #calc-btn The element with id="calc-btn"

The . prefix selects by class, # selects by ID.

Styling the Body

Let’s start with some base styles. Add to index.css:

body {
  font-size: 16px;
  font-family: Arial, sans-serif;
  background-color: #f5f5f5;
  text-align: center;
  color: #333;
}

Refresh. You should see a light gray background, centered text, and dark gray text. Let’s break down these properties:

  • font-size sets the base text size
  • font-family specifies the font (with fallbacks)
  • background-color sets the page background
  • text-align centers text within elements
  • color sets the text color

Styling Elements by Tag

Add styles for the heading and paragraphs:

h1 {
  color: purple;
}

p {
  line-height: 1.5;
}

The line-height: 1.5 controls spacing between lines of text, making paragraphs easier to read.

Styling by ID

IDs are unique. Only one element can have a given ID. Use the # prefix to select by ID. Let’s style the button:

#calc-btn {
  font-size: 1.5rem;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid #333;
  background-color: #fff;
  color: #333;
  cursor: pointer;
}

Here is what these properties do:

  • font-size: 1.5rem makes the text 1.5 times the root font size
  • padding adds space inside the button (vertical horizontal)
  • border-radius rounds the corners
  • border adds a thin dark border
  • background-color and color set the button colors
  • cursor: pointer shows a hand cursor on hover

Pseudo-selectors

We can add a hover effect with the :hover pseudo-selector:

#calc-btn:hover {
  background-color: #333;
  color: #fff;
}

Hover over the button. The colors invert. Pseudo-selectors like :hover and :active apply styles in specific states.

Styling by Class

An ID belongs to one element. A class can be shared by multiple elements. That is useful when you want to style several elements the same way.

Our wake-up time divs currently only have IDs (cycle-1, cycle-2, etc.). To style them all the same way, let’s add a shared class. Update index.js to add a class attribute:

    const cycleDiv = document.createElement("div");
+   cycleDiv.setAttribute("class", "cycle");
    cycleDiv.setAttribute("id", `cycle-${i}`);

Now all six divs have class="cycle" in addition to their unique IDs. We can style them all at once using the . prefix:

.cycle {
  font-size: 1.5rem;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid #333;
  background-color: #fff;
  color: #333;
  margin: 0.5rem;
}

The margin property adds space outside the element. That creates gaps between the cycle divs.

Click Calculate — you should see 6 styled wake-up times.

The Complete CSS

Here is the full index.css:

body {
  font-size: 16px;
  font-family: Arial, sans-serif;
  background-color: #f5f5f5;
  text-align: center;
  color: #333;
}

h1 {
  color: purple;
}

p {
  line-height: 1.5;
}

#calc-btn {
  font-size: 1.5rem;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid #333;
  background-color: #fff;
  color: #333;
  cursor: pointer;
}

#calc-btn:hover {
  background-color: #333;
  color: #fff;
}

.cycle {
  font-size: 1.5rem;
  padding: 0.5rem 1rem;
  border-radius: 0.5rem;
  border: 1px solid #333;
  background-color: #fff;
  color: #333;
  margin: 0.5rem;
}

And the index.html:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>WakeUp Times</title>
    <link rel="stylesheet" href="index.css" />
  </head>
  <body>
    <h1>WakeUp Times</h1>
    <p>
      A sleep cycle lasts about 90 minutes, and a good night's sleep consists of
      5-6 sleep cycles.
    </p>
    <p>If you go to bed now, when should you wake up?</p>
    <button id="calc-btn">Calculate</button>
    <div id="wakeup-hours-div"></div>
    <script src="index.js"></script>
  </body>
</html>

The app is now styled, but still basic. In the next section, we will polish it further with better layout, images, and improved user experience.

Checkpoint: Commit your progress.

git add .
git commit -m "wakeup-04: Add CSS styling"
git push