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.
Step 3: Add the footer
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.
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.