Task 2: Set up the layout and styling

For this task, our main focus will be on the layout and styling of our ToDo app. We require a space to enter todos, a space to display them, and some basic navigation and controls.

Step 1: Reset the HTML structure

Open the index.html file. Notice the basic HTML structure with a head and body section. We also have the title tag and the meta tags for character encoding and viewport settings.

Please remove the <div id="app"></div> from the body section. The HTML should look like the following:

<!doctype html>
<html lang="en">
	<head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/x-icon" href="/favicon.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ToDo App</title>
  </head>
  <body>
    <!-- Content will go here -->

    <!-- Scripts here. Don't remove ↓ -->
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

Furthermore, remove the code from main.js that was added to display "Hello World!" in the browser. Your main.js file should only contain the following import statement:

import "../style.css";

Step 2: Add the header

Next, we'll add the header section. This will include a h1 tag for the title of our app.

<body class="bg-stone-100">
	<header class="max-w-lg py-4 mx-auto mt-5 font-thin text-center">
    <h1 class="font-sans text-7xl text-rose-700">~ todos ~</h1>
  </header>

	<!-- Scripts here. Don't remove ↓ -->
	<script type="module" src="/src/main.js"></script>
</body>

Notice that we have also added a background color to the body section.

Right before the script tag, we'll add the footer section. This will include some basic instructions on how to use the app.

<footer
  class="flex flex-col items-center justify-center max-w-lg mx-auto mt-10 text-xs text-gray-500 font-extralight"
>
  <div>Click to complete a todo</div>
  <div>Double-click to edit a todo</div>
</footer>

Step 4: Add the navigation tag

We'll add a nav tag between the header and footer sections to filter our todos and switch between completed and active ones, or show all todos. Later, we will use JavaScript to hide this nav bar by default and show it only when todos exist.

<nav
  id="todo-nav"
  class="flex items-center justify-center gap-3 py-2 filters"
  role="navigation"
>
  <a
    href="#/"
    class="p-1 underline underline-offset-4 decoration-rose-800 decoration-2"
    role="button"
    >All</a
  >
  <a
    href="#/active"
    class="p-1 border-0 rounded-sm border-rose-700"
    role="button"
    >Active</a
  >
  <a
    href="#/completed"
    class="p-1 border-0 rounded-sm border-rose-700"
    role="button"
    >Completed</a
  >
</nav>

Notice that the nav element has three child anchor elements, each with a different href value. These anchor elements are used to filter between all, active, and completed todos. The first child anchor element is selected by default, which is reflected in its unique style (underlined decoration). We will use JavaScript later to apply similar styling when a user clicks and selects a different anchor element.

Step 5: Add the main section

We'll add the main section between the nav and footer elements. This will be the container for our todo list. For now, we'll leave it empty.

<main class="max-w-lg mx-auto font-thin bg-white divide-y shadow-md">
  <!-- Todo list will go here -->
</main>

We need to add three sections to the main element: an input for new todos, a list of todos, and a section for todo actions (such as clearing completed todos).

Step 6: Add the input for new todos

Inside the main section, we'll add an input field. This is where users will be able to enter new todos.

<input
  id="new-todo"
  placeholder="What needs to be done?"
  autofocus
  class="w-full p-4 text-2xl italic outline-none focus:outline-offset-0 focus:outline-rose-700"
/>

Step 7: Add the section for the todo list

Next, we'll add a section for the todo list. This will be a container for all the todos. For now, we'll leave it empty.

<section
  id="todo-list"
  class="flex flex-col w-full text-xl font-normal divide-y"
>
  <!-- Todos will go here -->
</section>

Later, we will use JavaScript to hide this section by default and only show it when todos exist.

Step 8: Add sample todos

Let’s add two sample todos within the section that has id="todo-list". Each todo will be contained within a div with the class "todo-item". The todo text will be displayed within a div with the class "todo-text". Additionally, there will be an input element with the class "hidden todo-edit", which will be initially hidden. This input element will be used to edit the todo text.

<div class="p-4 todo-item">
  <div class="todo-text">Buy milk</div>
  <input class="hidden todo-edit" value="Buy milk" />
</div>
<div class="p-4 todo-item">
  <div class="todo-text">Buy bread</div>
  <input class="hidden todo-edit" value="Buy bread" />
</div>

Step 9: Add the section for todo actions

Finally, we'll add a section for todo actions. This will include a count of the remaining todos, a button to mark all todos as completed, and a button to clear completed todos.

<section
  id="todo-actions"
  class="flex justify-between p-4 text-sm text-gray-600"
>
  <span id="todo-count">2 items left</span>
  <button id="mark-all-completed" aria-label="Mark all tasks as completed">
    Mark all as complete
  </button>
  <button id="clear-completed" aria-label="Clear completed tasks">
    Clear completed
  </button>
</section>

Later, we will use JavaScript to hide this section by default and only show it when todos exist.

Step 10: Run the App locally

Run the application and view it in the browser. You should see the following view.

Untitled

For your reference, this is the complete HTML file:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ToDo App</title>
  </head>
  <body class="bg-stone-100">
    <!-- Header here ↓ -->
    <header class="max-w-lg py-4 mx-auto mt-5 font-thin text-center">
      <h1 class="font-sans text-7xl text-rose-700">~ todos ~</h1>
    </header>

    <!-- This nav should be hidden by default and shown when there are todos ↓ -->
    <nav
      id="todo-nav"
      class="flex items-center justify-center gap-3 py-2 filters"
      role="navigation"
    >
      <!-- This nav item is selected by default ↓ -->
      <a
        href="#/"
        class="p-1 underline underline-offset-4 decoration-rose-800 decoration-2"
        role="button"
        >All</a
      >
      <a
        href="#/active"
        class="p-1 border-0 rounded-sm border-rose-700"
        role="button"
        >Active</a
      >
      <a
        href="#/completed"
        class="p-1 border-0 rounded-sm border-rose-700"
        role="button"
        >Completed</a
      >
    </nav>

    <main class="max-w-lg mx-auto font-thin bg-white divide-y shadow-md">
      <!-- This input should always be shown ↓ -->
      <input
        id="new-todo"
        placeholder="What needs to be done?"
        autofocus
        class="w-full p-4 text-2xl italic outline-none focus:outline-offset-0 focus:outline-rose-700"
      />

      <!-- This section should be hidden by default and shown when there are todos ↓ -->
      <section
        id="todo-list"
        class="flex flex-col w-full text-xl font-normal divide-y"
      >
        <div class="p-4 todo-item">
          <div class="todo-text">Buy milk</div>
          <input class="hidden todo-edit" value="Buy milk" />
        </div>
        <div class="p-4 todo-item">
          <div class="todo-text">Buy bread</div>
          <input class="hidden todo-edit" value="Buy bread" />
        </div>
      </section>

      <!-- This section should be hidden by default and shown when there are todos ↓ -->
      <section
        id="todo-actions"
        class="flex justify-between p-4 text-sm text-gray-600"
      >
        <!-- This should be `0 items left` by default -->
        <span id="todo-count">2 items left</span>
        <!-- Hidden if no active items are left ↓ -->
        <button
          id="mark-all-completed"
          aria-label="Mark all tasks as completed"
        >
          Mark all as complete
        </button>
        <!-- Hidden if no completed items are left ↓ -->
        <button id="clear-completed" aria-label="Clear completed tasks">
          Clear completed
        </button>
      </section>
    </main>

    <!-- This footer shows minimal instructions on how to use the app ↓ -->
    <footer
      class="flex flex-col items-center justify-center max-w-lg mx-auto mt-10 text-xs text-gray-500 font-extralight"
    >
      <div>Click to complete a todo</div>
      <div>Double-click to edit a todo</div>
    </footer>

    <!-- Scripts here. Don't remove ↓ -->
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

This is a well-structured and clean HTML document. The use of semantic HTML elements, along with meaningful and consistent class and ID names, makes it easy to understand the purpose of each section. The comments are also helpful and provide additional context for each section. Additionally, good accessibility practices, such as the use of role and aria-label attributes, were followed. Overall, this document demonstrates good HTML coding practices.

Step 11: Commit and push changes

To wrap up this section, we will stage and commit the changes using the following bash commands:

git add .
git commit -m "Set up the layout and styling"

Push your code to GitHub. It must be automatically deployed as a GitHub Page, as we have already configured it.