ToDoList Blog banner

Exciting Web Development Journey – To Do List

Hi there! Let’s continue our Web Development Journey we started in the previous post when we learned HTML, CSS, and JavaScript concepts. We had the opportunity to build a proof-of-concept web page to work with Sharing is The Key Website light and dark themes. I will assume you know some of the conventions, tricks, concepts, and tools we taught in the previous post for better productivity.

SITK To Do List

Scenario

We will make a web app for a to-do list. We’ll be able to use this app to track whatever we want: cool programming tricks that you want to learn, places to go, songs to listen to or learn to play, or something as basic as things to pick up at the stores. It will be possible to add and remove to-do items from the list and save them so they reload for you later.

Learning goals

  1. Getting to know more HTML elements such as Form and input text fields
  2. Styling using global variables, Flexbox module, and many other CSS resources
  3. Creating your own JavaScript functions
  4. Listening for different user actions on a web page
  5. Using functions together to write code more professionally.
  6. Saving user information between visits to your web page

What you will need

  1. VS Code, the cross-platform code editor. Or one of your preference.
  2. Docker Desktop latest stable version. You can see how to set it up here.
  3. Familiarity with at least one programming language. You don’t need to be an expert.
  4. A computer running one of the following:
    • Windows: Windows 10 Home or Professional
    • Mac: macOS 10.9 or later
    • Linux: Ubuntu, Debian, Red Hat, Fedora, or SUSE

Project structure

Let’s clone the previous post project to save some time and learn more about git CLI.

In your terminal, type the following command and hit Enter.

git clone https://github.com/sitknewnormal/SITK-themes.git "SITK-ToDoList"

This command will pull SITK-themes source code from our Git Hub repository and copy it into the SITK-ToDoList new folder.

SITK-TodoList project structure

Move into the SITK-ToDoList project folder, remove git source control, and open the VS Code by running the following commands.

cd .\SITK-ToDoList\; Remove-Item -LiteralPath ".git" -Force -Recurse; code .

opening SITK-ToDoList in VS code

It will open SITK-ToDoList in VS Code. If you remember from the previous post, it will ask you to reopen the project into a Dev Container, but for now, let’s not do this because I want to introduce you to an exciting VS Code extension.

SITK-ToDoList in VS Code

Let’s open the devcontainer.json file, make some changes and save them:

  • In the extensions values, replace "tht13.html-preview-vscode" by "ritwickdey.liveserver" (Live Server). Live Server extension launches a local development server with live reload feature for static and dynamic pages;
  • Change the name to “SITK – ToDo List.”
making changes to dev container config file

Now that we have everything in place, close VS Code and reopen it, but at this time, choose to reopen the project into the Docker Dev Container when asked to do so.

Let’s code HTML

When the Dev Container is up and running, and the project is ready to be edited, let’s go to the index.html and make some changes.

First, click on Go Live in the status bar to start our Live Server.

opening Live Server

It will open the web page in your default browser. Let’s put the VS Code and the browser windows side-by-side to see the reflection of what we are coding in the browser as soon as we save the changes, and let’s close the VS Code Explorer to get more room to code.

VS Code and browser side by side

Let’s get rid of everything between the opening <body> and closing </body> body element except for the theme switcher button element and save it.

SITK-ToDoList clearing out everything in the body

Let’s give our app an important header To-do List using <h1> element at the beginning of the body and save it.

SITK-ToDoList adding H1

We will need a paragraph <p> right after the header to inform the user to mark an item as completed by double-clicking on it. Please save it to see it in the browser.

SITK-ToDoList adding a paragraph with some instruction

To add items to our To-do List, we will need a Form with an input text element and a button. An HTML Form is used to collect user input. The user input is most often sent to a server for processing, but this is not our case for this post. Therefore copy the code below to a new line right after the paragraph we’ve just added.

        <form name="todo-adder">
            <input type="text" id="todo-entry-box" />
        </form>
        <button id="add-btn" class="pretty-button">Add</button>

Notice that we  named our Form name="todo-adder", we’ve given an identification id="todo-entry-box" to our input text, we did it to the button id="add-btn" as well, and we also created a class class="pretty-button" for future CSS styling. It is essential to keep in mind that naming, giving identification to HTML elements is always a good practice and will help you style them uniquely. Classes are often used to style a group of elements. Furthermore, the naming convention for CSS attributes such as name, id, and class suggests using lowercase and the hyphen for composed names.

SITK-ToDoList adding a form input text and a button

Now let’s break a line to separate the Form from the items, and let’s create an ordered list container so the user can see the item they will add to the list. Please copy the code below to a new line after the Add button.


        <br />
        <ol id="todo-list">
        </ol>

We gave an ID id="todo-list" to the To-do List for future CSS styling.

SITK-ToDoList adding ordered list

Next, we will create three buttons and wrap them in a div element. When it comes to productivity, VS Code is one of the best editors. The Emmet feature can help you with repetitive and boring coding tasks, and no extension is needed. Take a look at the video below to have a taste of VS Code editor’s power.

Let’s give them some IDs and texts accordingly to the chunk of code below.


    <div id="control-wrapper">
        <button id="clear-completed-btn" class="pretty-button">Clear Completed</button>
        <button id="empty-btn" class="pretty-button">Empty List</button>
        <button id="save-btn" class="pretty-button">Save List</button>
    </div>
SITK-ToDoList adding three buttons

Let’s do one more cool thing! To make our To-do List look better, we will wrap the elements from line 12 (Header 1) to 25 (three buttons div) in a div to style it. We will select lines 12 to 25, type the shortcut Ctrl+Shift+P to access the command palette, type Emmet: Wrap with Abbreviation, when it opens to enter the abbreviation, type div.todo-wrapper and hit Enter.

The final HTML code should look like this.

SITK-ToDoList final HTML code

As we could notice, we didn’t touch the head section where we still can see the style sheet linked, and we didn’t change the script tag where we still keep our JavaScript also linked.

Styling HTML with CSS

We already have our CSS from the previous post set up, which already supports light and dark themes, and we will keep and extend it. By the way, spending some time styling an application is very important and allows a better user experience.

Let’s do some cleaning before we style the new HTML elements we added.

First, let’s get rid of li, ul and .list selectors since we don’t have them anymore in the HTML file. Plus, let’s add three more colour variables in the root element. Please copy the code below at the end of the root element and save it.


    --laser1-light: #e5d9b6;
    --light-gray: #3a3a3a;
    --completed: #666666
SITK-ToDoList adding variables to the root element

We will use --laser1-light and --light-gray to style the to-do wrapper div’s background colour when we switch between light and dark themes, respectively. Place each variable inside light and dark themes selectors.

SITK-ToDoList placing new variables in dark and light themes

Let’s change the theme switcher button absolute position to the web page’s right top corner by changing the top key to 0px, replacing left by right key and set it also to 0px, in the .btn selector.

SITK-ToDoList setting theme switcher button to top right corner

Next, we will style the to-do wrapper div setting the background colour, border-radius, top, left and right margin and padding. Please copy the code below to the end of the CSS file. Notice that we are already using the --todo-wrapper-bg variable so the background will assume --laser1-light or --light-gray for the light and dark themes, respectively.


.todo-wrapper {
    margin-top: 60px;
    background-color: var(--todo-wrapper-bg);
    border-radius: 30px;
    margin-left: auto;
    margin-right: auto;
    padding: 30px;
}

Let’s check our work so far, but first, create four items in the ordered list using Emmet, remember? Inside the <ol> element, start typing li*4 and hit Enter.

SITK-ToDoList styling ToDo wrapper div

Now let’s style the only paragraph inside the to-do wrapper using the --completed variable we defined previously to set the colour; let’s set it up to italic and define margins. Please copy the code below to the end of the CSS file.


.todo-wrapper p {
    font-style: italic;
    color: var(--completed);
    margin: 5px 0;
}

The variable --completed will also be used to style the finished tasks’ font and colour.

Next, we will style the ordered list and its items, setting margin and some padding to the items to allow a little bit of space between them. Please copy the code below to the end of the CSS file.


.todo-wrapper ol {
    margin: 20px 0;
}

.todo-wrapper ol li {
    margin: 5px 0;
    padding: 3px;
}

Now let’s highlight the even items in our list for easy reading. Please copy the code below to the end of the CSS file.


.todo-wrapper ol li:nth-child(even) {
    background: #999999;
}

Let’s check our work so far.

SITK-ToDoList styling list items in the ordered list

Next, we will style the completed list items. First, let’s go to the HTML file and set the two first items as completed using class="completed" attribute.

SITK-ToDoList setting completed list items in the HTML file

Now, we will style those completed list items. Please copy the code below to the end of the CSS file.


.todo-wrapper .completed {
    text-decoration: line-through;
    color: var(--completed)
}
SITK-ToDoList styling completed list items

Time to style all buttons inside to-do wrapper div to look pretty. Remember that we used class="pretty-button" all buttons except the theme switcher? We are now changing their margin, padding, border-radius, background colour, border, text alignment, and more at once. Please copy the code below to the end of the CSS file.


.todo-wrapper .pretty-button {
    margin: 10px 2px;
    padding: 5px 20px;
    border-radius: 15px;
    background-color: var(--bg);
    border: none;
    color: var(--fontColor);
    text-align: center;
    display: inline-block;
    outline-style: none;
}
SITK-ToDoList styling all buttons inside To-do wrapper div

If you hover the mouse over the buttons, you will see no indication they are clickable. Let’s fix it by changing the cursor to a pointer and add a little bit of opacity as we hover over them. Please copy the code below to the end of the CSS file.


.todo-wrapper .pretty-button:hover {
    cursor: pointer;
    opacity: 0.75;
}

If we type in the text input field in the Form, we will notice the text look tight inside the text field. Let’s fix it by adding some padding. Please copy the code below to the end of the CSS file.


.todo-wrapper input {
    padding: 6px 6px;
}
SITK-ToDoList styling input text field

Next, we will fix the Add button, placing it on the input text field’s right side, which looks better.

SITK-ToDoList styling form children display

Display using inline-block makes the element generate a block box that’s laid out as if it were an inline box. According to QuirksMode: An inline-block is placed inline (i.e. on the same line as adjacent content), but it behaves as a block.

We will now align the buttons in the control-wrapper div using the display flexible box module, a relatively new and easy way to arrange elements on the page.  There is rich content here, so you can dig deep and learn more. For now, let’s say that the setup below finds a way to arrange the buttons at the center of the div and provides even spaces between them and the margins, which fits in most of the scenarios. Please copy the code below to the end of the CSS file.

#control-wrapper {
    text-align: center;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;
}

For the matter of responsiveness, the following code uses media query CSS resource to resize the .to-do wrapper width and .to-do wrapper input width. For devices with screen resolutions of at least 1400 pixels, the .to-do wrapper width will be set to 75%, and the .to-do wrapper input width will be 600 pixels. For devices with screen resolutions between 750 pixels and 1399 pixels, the .to-do wrapper width will be set to 50%, and the .to-do wrapper input width will be 400 pixels. Please copy the code below to the end of the CSS file.

@media only screen and (min-width: 1400px) {
    .todo-wrapper {
        width: 50%;
    }

    .todo-wrapper input {
        width: 600px;
    }
    
}

@media only screen and (max-width: 1399px) and (min-width: 750px) {
    .todo-wrapper {
        width: 75%;
    }

    .todo-wrapper input {
        width: 400px;
    }
}
SITK-ToDoList adding responsiveness

We can better see the responsiveness explained before in the following video where the .to-do wrapper width and .to-do wrapper input width resizes as soon as they reach the resolution limits defined in the media queries.

It is crucial to think of the behaviour you want your application to have in different devices and resolutions to catch and keep the user’s attention.

Let’s see the viewport metadata behaviour and how the elements arrange themselves in desktop, tablets, smartphones when properly styled using Flexbox, media queries, display inline-block and so on. Go back to the browser and click on the Toggle device toolbar button and play with the options.

Now that we have an awesome To-do List app well structured and styled, we will give it some action with JavaScript.

JavaScript

If you look at the page, you’ll see it has four buttons:

  • An Add button for adding new to-do items
  • A Clear Completed button for clearing items that you’ve marked as finished
  • An Empty List button for completely emptying the to-do list
  • A Save List button for saving what’s on the list

Of course, since you haven’t written any code yet, right now, none of them do anything!

Let’s add some code to our JavaScript file.

Add button

It is essential to tell JavaScript which parts of the HTML page are relevant and how user interactions with these parts should react. In this case, you want to tell it about the Add button and tell it to react when the user clicks this button.

Getting the Add button

Start by creating a button variable and telling JavaScript to get the id="add-btn" button element from the HTML document. Please type or copy the following code to the end of our JavaScript file and save it.

const addBtn = document.getElementById("add-btn");

Listening for the click

Now connect your button to an event handler so that JavaScript listens to a particular type of event and then runs a function when it hears it. The event is a click in our case. Do this with the function addEventListener. Please type or copy the following code to the end of our JavaScript file and save it.

addBtn.addEventListener("click", addToDoItem);

This listener will wait for the addBtn click, and when the click is heard, it will respond by running the addToDoItem function. Of course, because you haven’t written the addToDoItem function yet, it just won’t work yet!

Creating the function

Later in this post,  you will be writing code for your functions to add to-do items, clear the list, save it, etc. But for now, you want to check that you’ve connected your event listeners properly.

Create the addToDoItem function so that it will pop up an alert message informing the user which button they have clicked. Please type or copy the following code to the end of our JavaScript file and save it.


function addToDoItem() {
    alert("Add button clicked!");
}

Let’s check our work so far. Put the VS Code and the browser side by side again, and click on the Add button.

SITK-ToDoList checking Add button alert message

Write code for the remaining buttons.

Try it on your own, following the Add button steps to make sure you got the idea.

Connect the Clear Completed button, which has the Id clear-completed-btn, to an alerting function called emptyList.

Connect the Empty List button, which has the Id empty-btn, to an alerting function called clearCompletedToDoItems.

Connect the Save List button, which has the Id save-btn, to an alerting function called saveList.

Let’s see if you got it right! Check the code below and make some adjustments if needed or copy the following code to the end of our JavaScript file and save it.

let clearCompletedBtn = document.getElementById("clear-completed-btn");
clearCompletedBtn.addEventListener("click", clearCompletedToDoItems);
function clearCompletedToDoItems() {
    alert("Clear completed button clicked!");
}

let emptyBtn = document.getElementById("empty-btn");
emptyBtn.addEventListener("click", emptyList);
function emptyList() {
    alert("Empty button clicked!");
}
let saveBtn = document.getElementById("save-btn");
saveBtn.addEventListener("click", saveList);
function saveList() {
    alert("Save List button clicked!");
}

Don’t forget to save it! So far, the code should look like this.

SITK-ToDoList remaining buttons code so far

Click on all buttons to make sure they are working.

Add to-do items

Time to make the first of those buttons work correctly! This step will show you how to add a to-do item to the list.

First, go to the HTML file and delete all four list items <li> inside the ordered list <ol> and save it.

SITK-ToDoList clearing all list items from the ordered list

We are going to use a tiny bit of HTML in this step. Therefore you need to write some JavaScript to add <li> elements for each new to-do item. The user should enter text and then click the Add button to see it appear on the list as a numbered item.

First, just like you did with the buttons, create variables to select the text box and the ordered list. They already have the Ids todo-entry-box and todo-list. Please type or copy the following code to the end of our JavaScript file and save it.

let toDoEntryBox = document.getElementById("todo-entry-box");
let toDoList = document.getElementById("todo-list");

Now the text box and the ordered list can be easily reached from within your JavaScript.

Let’s create a function called newToDoItem to add an item to the list. This function will need to have two inputs:

  • The text of the item
  • The item completed or not

Of course, no new to-do item will ever be complete, but we are preparing ahead of time here: we will use the same function again when we load a saved list with some finished items. Please type or copy the following code to the end of our JavaScript file and save it.


function newToDoItem(itemText, completed) {
    let toDoItem = document.createElement("li");
    let toDoText = document.createTextNode(itemText);
    toDoItem.appendChild(toDoText);

    if (completed) {
        toDoItem.classList.add("completed");
    }

    toDoList.appendChild(toDoItem);
    toDoItem.addEventListener("dblclick", toggleToDoItemState);
}

This newToDoItem  does a few things.

let toDoItem = document.createElement("li");

Creates an li element to use as your new list item.

let toDoText = document.createTextNode(itemText);

Creates a text node, a special container for a text that we want to put inside an HTML element using JavaScript, and fills it with the contents of the itemText variable that is passed into the function.

toDoItem.appendChild(toDoText);

The function appendChild takes the element, or text node, that you pass to it (in this case toDoText), and puts it inside toDoItem. If there are already elements inside that one, the one we are adding now will be last.

if (completed) { toDoItem.classList.add("completed"); }

Checks if the value for the completed variable that was passed to newToDoItem is true. If it is true, it will add the class completed to the li element, changing how it looks on the page. In our CSS file, there are special styling rules text-decoration: line-through; for li elements.

toDoList.appendChild(toDoItem);

The function appendChild puts toDoItem, the <li> element inside of toDoList, the <ol> element.

toDoItem.addEventListener("dblclick", toggleToDoItemState);

Attaches an event listener for double-click to the toDoItem And tells it to call a function named toggleToDoItemState in response.

Next, connect to the function to the Add button. Change your existing addToDoItem function to get the text from the box and pass it to the function newToDoItem we’ve just created.


function addToDoItem() {
    let itemText = toDoEntryBox.value;
    newToDoItem(itemText, false);
}

Since a new to-do item is never finished, you can always pass false to the completed parameter of the newToDoItem function.

Let’s test it to see if it works!

SITK-ToDoList testing Add button

Completing items

When you can’t mark items as done, there’s not much point to a to-do list! It’s time to add that feature.

For a double-click on a to-do item, we have already set up the listener. All we need to do now is write a function that, when that double-click occurs, will toggle the item between complete and not complete.

Note that to mark items as complete, we are using the completed class. Not having that class implies that they aren’t complete. All our function needs to do is add or remove the class from the item’s class list, either add it if it is not yet on the list or delete it.

The this keyword

The trick is to know which item the class can turn on. You’ll need to use a new JavaScript keyword to describe the object that was clicked: this.

It’s a little bit complicated how exactly the this keyword works, but all we need to know here is that when used with a function called by an event listener, it means ‘the element to which the listener was bound.’ But you can use this to find the particular list item <li> we clicked on.

Add the toggleToDoItemState function to the end of our JavaScript like so:

function toggleToDoItemState() {
    this.classList.contains("completed") ? this.classList.remove("completed") : this.classList.add("completed");
}

Let’s test it to see if it works!

SITK-ToDoList marking items as completed

Remove items

If we have marked the items as complete, we will want to delete all of the completed items. Also, we may want to clear off everything on it if we come back to your list after a long time or if we just want to focus on something entirely different. To do this, we just need to update two functions that have already been connected to the buttons: clearCompletedToDoItems and emptyList.

Clearing completed items

Just as you can select all the elements in an HTML document, you can select the elements within any other element. The children of that element are called the elements inside another element. Likewise, just as you can select the Id elements, you can also select them by class.

Let’s update the existing clearCompletedToDoItems function with code to select the toDoList children who have the completed class to clear the completed items. Then loop over the selected items to remove one by one.

function clearCompletedToDoItems() {
    let completedItems = toDoList.getElementsByClassName("completed");

    while (completedItems.length > 0) {
        completedItems.item(0).remove();
    }
}

You will see that the code will always delete the item at position 0 of the list, the first item on the list. To do this, you need to use 0 since JavaScript starts counting at 0 and not 1. You delete this item to replace the first item every time the loop runs, so the list gets shorter and shorter. In this way, the loop will finally delete them all, no matter how many incomplete items are listed.

Let’s test it to see if it works!

SITK-ToDoList clearing items completed step1
SITK-ToDoList clearing items completed step2

Clearing everything

Let’s focus on the existing function emptyList. To delete all from the list, do the same thing as above, but pick all the children from the toDoList.


function emptyList() {
    let toDoItems = toDoList.children;
    while (toDoItems.length > 0) {
        toDoItems.item(0).remove();
    }
}

 It is always recommended to check your work as soon as you advance on it.

Save the list

You can save the to-do list to a local storage location on the user’s computer to make it even more useful. Then, as long as they open it in the same browser next time, it will remember their to-do list.

There are two important steps for this task: saving the list and loading it again when the page is reloaded if the list is there.

This gets a little tricky: HTML can’t be saved in the local storage, so we need to take the HTML code and convert it to pure JavaScript. To do that, you will need an array.

An array is a variable of a special kind, which is a list of variables. You can build one with square brackets and use the push method to add objects to it. You can remind yourself what a specific array item is, using alert and the item’s position in the array. Remember that JavaScript starts counting at 0. Take a look at the code below to understand it better.

const myArray = [];
myArray.push("array item 1");
myArray.push("array item 2");
alert(myArray[0]);
//This will alert "array item 1"

Next, we need to loop over the list toDoList and add each item to the array. Remember that we need to store the task and whether or not it has been completed. The best way to do this is to use JavaScript objects.

JavaScript objects

A JavaScript object is a set of properties and values. You create one like this:

const toDoInfo = {
    "task": "Learn HTML",
    "completed": false
};

You just need to save all the to-do items to local storage once you have converted them into objects. Local Storage can only store strings, but fortunately, JavaScript turns arrays into strings for you when you use the stringify function.

Saving in a Local Storage – Step 1

Enough said, let’s put it all together!

Let’s update the existing saveList function to:

  • Make an array
  • Use a for loop to put every item in toDoList into the array as an object
  • Stringify the array and store it in local storage with the key toDos

Here is the code for the saveList function.

function saveList() {
    const toDos = [];
    for (let i = 0; i < toDoList.children.length; i++) {
        let toDo = toDoList.children.item(i);
        let toDoInfo = {
            "task": toDo.innerText,
            "completed": toDo.classList.contains("completed")
        };
        toDos.push(toDoInfo);
    }
    localStorage.setItem("toDos", JSON.stringify(toDos));
}

Load the saved list – Step 2

We need to reverse everything we have done to save it, to load the list. But first, we need to check if anything needs to be loaded. You do this by checking whether there is no null value on the key you used to store the list. ‘Null’ is yet another ’empty’ word or ‘nothing’ word.

Let’s create a loadList function to:

  • Check if the toDos key exists in local storage
  • If it does, load it into a variable as an array
  • Loop over the array, and use newToDoItem to create new to-do items for everything in it

Add the code below to the end of our JavaScript file.

function loadList() {
    if (localStorage.getItem("toDos") != null) {
        let toDos = JSON.parse(localStorage.getItem("toDos"));

        for (let i = 0; i < toDos.length; i++) {
            let toDo = toDos[i];
            newToDoItem(toDo.task, toDo.completed);
        }
    }
}

Let’s call the loadList function after we have created it. Add the code below to the end of our JavaScript file and save it.

loadList();

To close it with a golden key, let’s save it to the local storage every time we add a new item, mark an item as completed, clear completed items, and empty the list.  All we need to do is adding the code below at the very end of addToDoItem, clearCompletedToDoItems, toggleToDoItemState and emptyList functions.

saveList();
SITK-ToDoList adding saveList to addToDoItem
SITK-ToDoList adding saveList to clearCompletedToDoItems
SITK-ToDoList adding saveList to toggleToDoItemState
SITK-ToDoList adding saveList to emptyList

Let’s test it to see if it works!

Congratulations, we have done a great job! I know it is a lot to take in, but you will get used to it with time and practice.

Let’s use Git to commit our work. We taught how to do it in our previous post; check it out here.

If you don’t know what Git is, take a look here and find out. The SITK-ToDo List source code can be found on our GitHub account.

We’ve got more of the basics of front-end web development. Certainly, there is much more to learn about HTML, CSS and JavaScript, and there are some free and excellent references for this: w3schools.com and MDN Web Docs.

If you need any help or something is going wrong, let me know. It will be my pleasure to help you. If you want to extend some point, we have discussed, contact me so we can cover in the next posts.

We also have pro bono projects just in case you are interested in learning more about them.

Be aware of why we started this project by clicking here.

Learn more about other posts here.

Contact us for any suggestions. And follow us on FacebookInstagram and Twitter.

If you are a good reader like myself, I recommend the following readings:

  • Docker Quick Start Guide: Learn Docker like a boss, and finally own your applications
  • Docker for Developers: Develop and run your application with Docker containers using DevOps tools for continuous delivery
  • Responsive Web Design with HTML5 and CSS: Develop future-proof responsive websites using the latest HTML5 and CSS techniques, 3rd Edition
  • JavaScript: The Definitive Guide: Master the World’s Most-Used Programming Language 7th Edition

See you in the next post!

Exciting Web Development Journey – The basics

Now that we have a cool development environment to brag about, why don’t we really use it? If you have no clue what I’m talking about, take a look at the series where we teach some concepts and prepare an exquisite, flexible, versatile software development environment with Docker.

My motivation

It is tough to please everyone when it comes to using the right tools, frameworks and technologies to become a good web developer, but we all concur that HTML, CSS and JavaScript are the nuts and bolts of web development. Therefore let’s get to know them and try to have fun on our journey!

HTML, CSS and Javascriptjs

I don’t want to reinvent the wheel; we all know there are many free interesting courses about this theme; there are many good CSS frameworks and JavaScript frameworks you should use or continue using. Nevertheless, during my long walk developing software, I can see many traps that people fall into due to a lack of understanding of those three guys’ basics. Still, if you stick with me, you will have a practical approach while learning a little bit of them.

What are HTML, CSS and JavaScript?

Those three are the foundational coding languages of the internet. They all work together to produce a web page. I would say that HTML adds meaning to raw content by marking it up, CSS formats that marked-up content and JavaScript is for making that content and formatting interactive, but it would sound boring, and most of the people newbie in this web development world wouldn’t still really understand or even get the big picture of it.

Therefore I always come up with the 3 friends analogy that I rescued from my childhood playing with Lego to make it clearer.

Let’s say that HTML is the first friend called The Builder responsible for the structure and content of a web page.

HTML - The builder

CSS is the second friend called The Artist, responsible for styling the web page’s content to give it a more appealing look and feel.

CSS - The artist

JavaScript is the third friend called The Wizard responsible for giving an interactive approach to the web page, allowing users to change the web page’s content and style providing such sensation that the page is alive.

JavaScript - The wizard

All of them, The Builder, The Artist and The Wizard, are essential for a web page to work seamlessly and beautifully.

For sure, I am pretty much talking about the Front-end Developer role kind of thing. We will cover some of the Backend Developer roles later, most likely in the next posts.

Let’s see how it works!

Scenario

Imagine that you are a front-end web developer. You are asked to cater to a wider variety of visitors on the Sharing Is The Key website, and you decide to incorporate support for light and dark themes keeping the brand identity. To demonstrate support for themes using CSS, you create a simple, proof-of-concept web page, and you write a JavaScript function to toggle the theme.

Learning goals

  • Develop a simple web page using HTML.
  • Style the page elements using CSS.
  • Define and create themes using CSS.
  • Add functionality for switching the theme using JavaScript.
  • Use browser developer tools to inspect the web page.

What you will need

  1. VS Code, the cross-platform code editor. Or one of your preference.
  2. Docker Desktop latest stable version. You can see how to set it up here.
  3. Familiarity with at least one programming language. You don’t need to be an expert.
  4. A computer running one of the following:
    • Windows: Windows 10 Home or Professional
    • Mac: macOS 10.9 or later
    • Linux: Ubuntu, Debian, Red Hat, Fedora, or SUSE

Project structure

Create a simple project structure that includes five files: an HTML file, a CSS file, a JavaScript file, a development container configuration file, and a Docker image file. You also add two VS Code extensions to simplify preview the web page in VSCode.


C:\SITK\WEBDEVJOURNEY\SITK-THEMES
¦   app.js
¦   index.html
¦   main.css
¦   
+---.devcontainer
        devcontainer.json
        Dockerfile

Let’s do this together!

If you prefer the CLI interface like myself, follow the Powershell or Windows Terminal section’s instructions below. If you prefer the VS Code interface, click here and follow the instructions under Create a new folder and Create some files sections.

Powershell or Windows Terminal

Getting to know Powershell or Windows Terminal if you use Windows or Shell if you use Linux is mighty, and you will need them sooner or later in your software development career. Therefore, I strongly recommend starting to use them as soon as possible. I prefer to use Windows Terminal, and from now on, I’ll call it “terminal” for short.

Open the terminal and run the following command:

New-Item -path "c:\sitk\WebDevJourney\SITK-themes\.devcontainer" -type directory

You should see something like this.

creating SITK-themes project folder structure

I created the SITK-themes project folder under the WebDevJourney folder just because this is the first of many projects in our Web Development Journey, but you can choose the folder you want.

Next, let’s create the HTML, CSS and JavaScript files under the SITK-themes folder running the command below.


New-Item -ItemType "file" -Path "c:\sitk\WebDevJourney\SITK-themes\index.html", `
                                "c:\sitk\WebDevJourney\SITK-themes\main.css", `
                                "c:\sitk\WebDevJourney\SITK-themes\app.js"

You should see something like this.

creating HTML CSS and JavaScript files under SITK-themes folder

Next, let’s create the Development Container configuration file and the Docker file that contains the Linux Alpine tiny distro.


New-Item -ItemType "file" -Path "c:\sitk\WebDevJourney\SITK-themes\.devcontainer\devcontainer.json", `
                                "c:\sitk\WebDevJourney\SITK-themes\.devcontainer\Dockerfile"
creating SITK-themes Development Container config file and Dockerfile

It is not really necessary to have this Development Container since we will not do anything complex here, but let’s get used to creating containers for all projects to keep our Software Development Environment well organized. Another remarkable advantage is that you will not need to install all software dependencies, VS Code extensions, and so on in the host to work with the project whether you format your machine later or work on it in another machine right away. If you are confused, take a look at a series of four posts where we depict this matter in more detail.

To make sure that you accomplished this task, run the following command.

Tree "C:\sitk\WebDevJourney\" /F | Select-Object -Skip 2

You should see something like this.

checking SITK-themes project tree

Now we have the SITK-themes project folder structure and files ready, let’s code!

In your terminal, make sure you are under the c:\sitk folder or in the folder you chose previously and run the following command.

cd .\WebDevJourney\SITK-themes\; code .

In your terminal, you should see something like this. Plus, it will open the VS Code in the SITK-themes project folder.

open VSCode via powershell command line

When VS Code is open, it will detect there is a Development Container configuration file devcontainer.json and will ask you to reopen the project into a Dev Container, but for now, ignore this notification because we don’t have anything in there yet.

SITK-themes project in VS Code

Press Ctrl + Shift + E to open VS Code Explorer to access the files or go to the menu View > Explorer.

Developing inside a Container

In your project, the devcontainer.json file tells VS Code how to access or create a development container with a well-defined runtime stack and tool. This container can run an application or run the required sandbox tools, libraries, or runtimes for a codebase to operate.

Workspace files are placed or copied, or cloned from the local file system into the container. Extensions are mounted and run within the container, where the tools, platform, and file system are completely accessible. This means that only by connecting to a separate container can you seamlessly switch your entire development environment. In summary, it is handy when you work on projects that require different development frameworks, libraries and platforms.

Copy the content below to the devcontainer.json file.


{
	"name": "SITK - Themes",
    "build": {
        "dockerfile": "Dockerfile",
    },
	"settings": {
		"terminal.integrated.shell.linux": "/bin/bash"
	},
	"extensions": [
		"eamodio.gitlens",
		"tht13.html-preview-vscode"
	],
}
JSON

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language Standard ECMA-262 3rd Edition – December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.

From top to bottom, this JSON file contains the name of this Dev Container,  the docker file name, which contains the instructions for Docker to build the image for the container, the settings for an integrated Linux shell in the VS Code, and the two extensions you are going to need for this project.

Copy the content below to the Dockerfile file.


FROM alpine

RUN apk --update add git less openssh && \
rm -rf /var/lib/apt/lists/* && \
rm /var/cache/apk/*

As I said previously, we will use Alpine, one of the most lightweight Linux distribution, and that is all we need for this project. Always bear in mind that the lesser we need to accomplish a task, the better.

Let’s code HTML

Now let’s call our friend The Builder to start building our web page.

All HTML documents must start with a document type declaration: <!DOCTYPE html>.

The HTML document itself begins with <html> and ends with </html>.

The visible part of the HTML document is between <body> and </body>.

VS Code provides basic support for HTML programming out of the box. Syntax highlighting, intelligent completions with IntelliSense, and customizable formatting are available.

  • Open index.html by selecting the index.html file, type html:5, then hit Enter.

HTML5 template code is added to the file.

  • Edit your code so that it looks like the following, then save the file with Control + S or go to the menu File > Save.
html5 code template

The tag document type <!DOCTYPE html> indicates this is HTML5 code. If possible, always stick with the latest HTML version. Why? Well, because it is becoming a new standard, it is faster and reduces development time. It is modern because it works along with CSS3. It lets you do things previously impossible and supports mobile devices.

While we are not going to dig deeply into the definition of all the HTML elements, we will point out a few important stuff. The meta tag, which sits inside the head tag <head> shows metadata information that would not normally be available to the user unless the source code is shown in their browser. Meta elements or tags provide detailed and important information about the webpage. For instance, they help search engines display results to people.

The UTF-8 character set (charset) may seem trivial, but it is important for deciding how computers perceive characters. If the charset is missing, it might result in a security issue. Behind Charset, there is quite a bit of history and technical knowledge.

Viewport

HTML5 introduced a method to let front-end developers take control over the viewport through the <meta> tag. The viewport is the user’s visible area of a web page. You should include the following <meta> viewport element in all your web pages:

This gives the browser instructions on how to control the page’s dimensions and to scale.

The width=device-width part sets the page’s width to follow the device’s screen-width, which will vary depending on the device.

<meta name="viewport" content="width=device-width, initial-scale=1.0">

The initial-scale=1.0 part sets the initial zoom level when the browser first loads the page.

Head

The webpage’s title appears at the top of a browser window and is useful in a few ways. The title is used by and displayed in search engines, for instance. Let’s get a title added. Please change it to Sharing Is The Key, as shown below.

html page title

You can directly write the CSS code into the head of the web page, called internal CSS, to style the page’s HTML elements. It is best practice, however, to keep HTML structure and CSS styling apart.

It is called external CSS to have a distinct CSS file. When it is succinct and compartmentalized, the code appears to be simpler to read and understand.

You may use one or more external style sheets to serve several web pages. Instead of updating each HTML page with duplicated CSS, changes can be made once, and updates can be sent to all dependent pages.

  • In Visual Studio Code, add a blank line after the <title> element, type link and hit Enter.
  • Update the href to main.css and save the file with Control + S or go to the menu File > Save.
Link CSS to HTML

Body

  • Adding a heading <h1>, paragraph <p>and create a list item <li>.
  • Edit your code, or copy the code below and paste it between the opening <body> and closing </body> body tags.

    <h1>SITK - Themes</h1>
    <p id="tasks">Following Tasks:</p>
    <ul>
        <li class="list">Adding visual styles </li>
        <li class="list">Adding light and dark themes </li>
        <li>Switching the theme button </li>
    </ul>

An ID attribute id="tasks" used in the <p> will be used for styling this specific element as soon as we have code in the CSS file. The class attribute class="list" used in the <li> will be used for styling all elements of the same class.

Each list item <li> element is grouped into an unordered list <ul>.

Now that we have our simple web page properly structured, close VS Code and reopen it, but at this time, choose to reopen the project into the Dev Container when asked to do so.

Reopen SITK-themes project in a Dev Container

Click on Starting Dev Container (show log) as shown below.

VS Code Starting Dev Container show log

Please wait for VS Code to recognize a Dev Container configuration file, build the Alpine Linux container based on the image specified in the Dockerfile, set up the integrated Linux shell terminal, install the two VS Code extensions and be ready. The whole process takes one minute or so.

Once it is done, roll up the integrated terminal and see the HTML preview properly installed.

VS Code HTML preview extension

Now you have everything ready, resize the integrated terminal to see the whole HTML code and press Ctrl + Shift + V, which is the shortcut to the HTML preview, and here we go.

SITK-themes HTML page preview

To make it even better, grab the HTML preview and drag it to the right, as shown in the video below.

This is really handy when you want the coding to reflect immediately in the preview, as you can see below.

Sometimes things happen around us, and we don’t even notice. Please take a breath and realize that you are coding a simple HTML page into an Alpine Linux container with all you need to do so. So, congratulations on this accomplishment, but we are not done yet.

Many times you will need to troubleshooting to find some issues on the page. Let’s look at some useful developer tools in the browser where the page will actually run.

Developer tools

By opening the HTML file in a browser, you can preview your web page locally. Your browser points to the local file path instead of a website address that starts with https://. In my case, they will look like this: file:///C:/sitk/WebDevJourney/SITK-themes/index.html. If you saved the project in a different directory, don’t forget to change the path. Copy file:///C:/sitk/WebDevJourney/SITK-themes/index.html in your preferred browser. I’ll use Google Chrome.

You should see something like this.

SITK-themes running on Google Chrome
  • Open developer tools by pressing F12.
Developer tools - Google Chrome
  • Select the Elements tab
Developer tools - Google Chrome - Element tab
  • Rollover, select the HTML elements and open the disclosure triangles and explore them all.
Developer tools - Google Chrome - Element tab - exploring elements

In Developer Tools, the Elements tab shows you the DOM as rendered by the browser. It is also important to see when debugging how the browser interprets the source code.

DOM

DOM is a cross-platform and language-independent interface that treats an XML or HTML document as a tree structure wherein each node is an object representing a part of the document. The DOM represents a document with a logical tree.

Inspecting the page in a browser provides all sorts of useful information and can help you troubleshoot problems. You can also view CSS details with the inspector, as you’ll see soon.

It is not a big deal, but here is our first web page! It seems that although it is simple, we can put a little style to make it look better. Let’s call The Artist to decorate it.

Styling HTML with CSS

You may decide how your page should look by using CSS. The fundamental principle is to target HTML code and then define what the style should be.

Let’s apply CSS styles to page elements, add CSS code to support light and dark themes, and check the developer tools’ results.

External CSS

One advantage of external CSS is that several HTML pages can be connected to the same CSS file. If you make a change to the CSS, the style will be applied to each page. Designating an HTML file for page structure, a CSS file for styling, and a JavaScript file for event or interaction is called Separation of Concerns. We already have connected the CSS to HTML by adding this code <link rel="stylesheet" href="main.css"> to the index.html previously in this post.

CSS rules

Let’s imagine that The Builder built a house, and you’ve got the keys to all doors, and you are going decorate all of them. First, pick a door, then unlock it with the proper key. Once you have access to a room, you can decorate whatever you want. You could paint the walls blue, or you could set the floor to be hardwood. You pick a room and define the rules for how it should look. You may add the same style to multiple rooms. That is what CSS does.

In VSCode, open the main.css file and type this.


body {
    font-family: monospace;
}

ul {
    font-family: helvetica;
}

It is good practice to use CSS rules to style HTML. The unordered list element ul {} is a selector, which styles the <ul> HTML element. The declaration is font-family: helvetica and says what the font style should be. The property name is font-family , and the value is helvetica.

As you can see, the whole body font should be monospace, but only the Header1 element <h1> and the Paragraph element <p> were styled with this font. We use to say that the style cascaded from the body element to the Header1 and Paragraph elements because they are the body’s children and therefore inherit from their parent, but this only happens if no other style was defined for them. On the other hand, the Helvetica font took precedence over the monospace for the unordered list <ul> because it was explicitly defined.

CSS Rules

Selectors

ID and class selectors allow you to apply styles to custom attribute names in the HTML. An ID is used to style one element, and it should be unique, whereas classes can style multiple elements.

Type or copy the following code into your CSS file after the ul selector previously added.


li {
  list-style: circle;
}

.list {
  list-style: square;
}

#tasks {
  font-family: monospace;
}

The custom attributes are called .list and #tasks. The class selector list is prefixed by a period, while the ID selector is tasks and has a hashtag sign prefix. You choose their names as long as they match what you have defined in the HTML.

Save the changes and press Ctrl+Shift+V to open the HTML preview.

CSS Selector

Notice that all list items li were styled to have a circle for the bullets, but all list items with class="list" were defined to have squared bullets.

SITK light theme

Next, let’s add support for a colour theme for the SITK-themes web page. For the light theme, let’s use hex colour codes for the font colour (#0b0b0b, Cod Gray 1) and the background (#c8b568, Laser 1).

  • In the main.css file, add the following code at the end.
.light-theme {
color: #0b0b0b;
background: #c8b568;
}
  • In the index.html file, update the <body> element with a class name, light-theme, so the class selector for the light theme will apply the styles correctly.

<body class="light-theme">

apply light-theme to SITK-themes

View applied CSS using developer tools.

  • Copy file:///C:/sitk/WebDevJourney/SITK-themes/index.htmlin Google Chrome or Edge.
  • Open developer tools by pressing F12.
  • Select the Styles tab.
  • Select the Elements tab.
  • Rollover and select the HTML elements.
  • Select the <body> element. Notice the light-theme applied.
checking CSS applied in the developer tools
  • Open the disclosure triangles.
  • Select the <ul> element. Notice the custom style font-family: helvetica;, which overrides the style for the <body> element.
CSS overriding example

SITK dark theme

Now let’s set up plumbing for the dark theme in preparation for the last part in which we will allow theme switching on the web page.

  • Let’s add some constants to the page root in the main.css file.
:root {
--laser1: #c8b568;
--white: #ffffff;
--black: #0b0b0b;
}

The :root selector represents the <html> element in the HTML page. There are some situations where the best practice is to define a set of global CSS variables in the :root element. Here, we are defining three colour variables attached to the page root.

  • At the end of the main.css file, add the dark-theme selector and update the light-theme selector.

.light-theme {
--bg: var(--green);
--fontColor: var(--black);
}

.dark-theme {
--bg: var(--black);
--fontColor: var(--green);
}

In the code above, we defined some new variables, bg and fontColor, to specify the background colour and font colour. We used the var keyword to specify variables to use as the property values. We already set the values previously in the :root selector.

  • Next, in the main.css file, let’s add the following code after the :root selector, replacing the current body selector.
* {
color: var(--fontColor);
font-family: helvetica;
}

body {
background: var(--bg);
}

The * selector is a universal selector that applies to all page elements, except where a more specific element selector overrides it. Here, we use it to set the default color property for all page elements. For the color and background properties, you specify the variables defined in the light and dark theme selectors.

  • Remove the selector #tasks in the main.css, so that we can apply the same font to all elements.
  • To view the dark theme, manually let’s edit the default theme in the <body> element to dark-theme, and then press Ctrl+Shift+V to see HTML preview.
SITK-themes dark-theme preview
  • Let’s edit the <body> element to switch the default back to the light theme.

Javascript

JavaScript or ECMAScript is a programming language that allows you to add web page interactivity. Actually, JavaScript is the most commonly used programming language in the Software Development industry, according to Stack Overflow 2020 survey. It is nearly used by 70% of professional developers.

Stack Overflow is the largest, most trusted online community for developers to learn, share​ ​their programming ​knowledge, and build their careers for those who don’t know.

Now let’s call our friend The Wizard to give some functionality to our page!

When you click a button, JavaScript is the code that determines the event or action that will occur, such as opening a pop-up window. Using JavaScript, without reloading the web page, you can add or delete content like text. You can always use the browser to test and get feedback about your scripts as a web developer.

We will build a button to switch between light and dark themes and then wire the JavaScript code button to make the actual theme switch. When this is done, we will review our work using the developer tools.

Link HTML to JavaScript

Following the Separation of Concerns pattern recommendation, let’s use the separate JavaScript file previously created and link it to the index.html.

  • Right after the unordered list closing tag </ul> start a new line and type script:src, fill the double quotes with our JavaScript filename app.js  press Enter and save.
Link JavaScript to HTML

The script element could be placed in the <head> or elsewhere in the <body>. However, as best practice, putting <script> at the end of the <body>, allows all the page content to display on the screen first, then load the script after. This best practice will provide a better user experience when the project has huge JavaScripts to load on the page.

  • Let’s add fault tolerance so we can detect when a feature is not supported or available. After the script link you’ve just added, add a new line with the <noscript> element, which can be used to show a message if JavaScript is deactivated. Copy or type the code below and save the changes.

<noscript>You need to enable JavaScript to view the full site.</noscript>

Add JavaScript fault tolerance

Strict mode

When we start using JavaScript, our initial focus is often working with numbers, math, text manipulation, dates, and information storage. Sometimes JavaScript makes assumptions about the type of data we enter; assignment, math, or logical equality can give you unexpected results. Even if the result is an error, JavaScript tries to make the code run smoothly and provide you with a solution. To fix this behaviour, we can enable a strict mode that reduces silent errors, improves performance, provides more alerts, and reduces the number of unsafe features.

Let’s open app.js and type this code 'use strict'.

JavaScript strict mode

Toggle the theme button

We will need a button to switch themes.

  • In the index.html page, let’s add a button element <button>. Let’s put this at the end of the list inside of the <div> element. Copy or type this code below in a new line right after the unordered list closing tag </ul>.
<div>
  <button class="btn">Dark</button>
</div>
adding button to toggle the theme
  • In the main.css file, add a selector for the button. To make the button colours different from the general light or dark theme colours, set the color and background-color properties in the button selector. This selector, specific to the button, overrides the universal selector * used to apply font colours in our CSS file. Type or copy and paste the code below to the end of our CSS file.
.btn {
  color: var(--btnFontColor);
  background-color: var(--btnBg);
}
styling button to toggle theme
  • Next, let’s add some rules for the size, shape, appearance, and button absolute position. The following CSS creates a round button to the right of the page heading. Type or copy and paste the code below, replacing the existing button selector.
.btn {
  position: absolute;
  top: 20px;
  left: 250px;
  height: 50px;
  width: 50px;
  border-radius: 50%;
  border: none;
  color: var(--btnFontColor);
  background-color: var(--btnBg);
}
styling button to toggle theme
  • To improve the button’s appearance, let’s add a pseudo-class selector btn:focus after the button selector. By setting the outline-style rule to none, you eliminate a rectangular outline when the button is selected or receives focus. Type or copy and paste the code below to the end of our CSS file.
.btn:focus { 
    outline-style: none;
}
eliminating button outline when clicked or focused
  • Next, let’s update the CSS for the light and dark themes. Let’s define some new variables, btnBg and btnFontColor, to specify the button-specific background colour and font colour. Update the light-theme and dark-theme selectors with the code below.
.light-theme {
  --bg: var(--laser1);
  --fontColor: var(--black);
  --btnBg: var(--black);
  --btnFontColor: var(--white);
}

.dark-theme {
  --bg: var(--black);
  --fontColor: var(--laser1);
  --btnBg: var(--white);
  --btnFontColor: var(--black);
}
updating ligh-theme and dark-theme selectors

Event Handler

You need an event handler in your JavaScript file to make the button do something when you click it. Therefore we need to listen to the button click event. But, before you add the event handler, you will need a reference to this button.

  • In the app.js file, use document.querySelector to get the button reference. The document is a global variable representing the actual web page, and the querySelector method returns the first element that matches a specified CSS selector in the page.

const switcher = document.querySelector('.btn');

  • Let’s add the event listener and the event handler for the click event. In the following code, we are adding a listener for the click event. The function passed into the event listener is the actual event handler.
switcher.addEventListener('click', function() {
    document.body.classList.toggle('dark-theme');
});

We used the toggle method in the previous code to move the element to the dark-theme class. This will immediately add the dark theme styles instead of the light theme. To view the correct theme, however, the button label also needs to be changed, so you need to add a condition to verify the current theme and update the button label. Please add this command inside the event listener, right after the toggle command.

  let className = document.body.className;
  this.textContent = className == "light-theme" ? "Dark" : "Light";

In the code above, we created a variable className and assigned the body element class name to it, and we assigned a ternary operator result to this.textContent. The this is the switcher variable that points to the button element. In summary, this is the button. The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark (?), then an expression to execute if the condition is truthy followed by a colon (:), and finally the expression to execute if the condition is false. This operator is frequently used as a shortcut for the if statement.

Press Ctrl+Shit+V to reload the HTML preview page.

adding JavaScript to the SITK-themes project

Now you can click on the button to contemplate our friend The Wizard‘s job done!! Congratulations, we made it; we built our first beautiful web page and gave it life.

Console message

Sometimes to better understand the page behaviour running on the browser, we can use console messages. It is a hidden message that will not appear on the web page but will show up in the browser developer tools.

In app.js, add a call to console.log after the ternary operator statement, but still inside the event listener.

  console.log('current class name: ' + className);
console logging in SITK-themes project

Check console messages in the browser.

  • Copy file:///C:/sitk/WebDevJourney/SITK-themes/index.htmlin Google Chrome or Edge.
  • Open developer tools by pressing F12.
  • Select the Styles tab.
  • Select the Elements tab.
SIT-themes project light-theme selected
  • Select the <body> element. In the Styles tab, look at the applied theme. If the current theme is dark, the dark-theme styles are applied.

Make sure the dark theme is selected.

SITK-themes project dark-theme selected
  • Select the Console tab to see the console.log message, “current <body> class name: light-theme dark-theme”.
SIT-themes project light-theme selected - check console log

Using the console log, we can better understand how the CSS theme switching is handled. Both class names are applied to the <body> element when we switch to the dark theme. However, the last class name applied, the dark theme, takes precedence. In the Styles tab, you can see that the dark theme rules override the light theme rules, shown using strikethrough text.

SIT-themes project light-theme selected - check console log details
  • To see the viewport metadata behaviour explained previously, which is very important to build a responsive web page that also fits mobile devices, click on the Toggle device toolbar button and open <head> HTML element.
SITK-themes project light-theme selected - mobile
  • Toggle to the dark theme.
SITK-themes project dark-theme selected -mobile
  • To understand the importance of the viewport metadata, comment the line 6 in index.html. Go to line 6 and press Ctrl+;  and save.
comment viewport metadata in SITK-themes project
  • Reload the page by pressing F5 to apply the browser’s changes and click on the Toggle device toolbar button to change to Desktop device and toggle back to mobile.
checking the results of commenting viewport metadata in SITK-themes project
  • Now, it’s time to save our work. Uncomment line 6 in index.html by pressing Ctrl+; again and save it.
  • Commit everything with the git extension we installed in our Docker Dev Container in the beginning. This way, you will have control of the source code and track all changes from now on. Go to Source Control extension by pressing Ctrl+Shift+G.
  • Click on the Initialize Repository button to create a new git repository for source control.
  • Type the message “Adding files” to the field and click on the commit button, as shown below.
git commit changes SITK-themes

It is always a good practice to commit all changes you make to your project frequently.

If you don’t know what Git is, take a look here and find out. The SITK-themes source code can be found on our GitHub account.

Congratulations!! We’ve got the basics of front-end web development. Certainly, there is much more to learn about HTML, CSS and JavaScript, and there are some free and excellent references for this: w3schools.com and MDN Web Docs.

If you need any help or something is going wrong, let me know. It will be my pleasure to help you. If you want to extend some point, we have discussed, tell me so we can cover in the next posts.

We also have pro bono projects just in case you are interested in learning more about them.

Be aware of why we started this project by clicking here.

Learn more about other posts here.

Contact us for any suggestions. And follow us on FacebookInstagram and Twitter.

If you are a good reader like myself, I recommend the following readings:

  • Docker Quick Start Guide: Learn Docker like a boss, and finally own your applications
  • Docker for Developers: Develop and run your application with Docker containers using DevOps tools for continuous delivery
  • Responsive Web Design with HTML5 and CSS: Develop future-proof responsive websites using the latest HTML5 and CSS techniques, 3rd Edition
  • JavaScript: The Definitive Guide: Master the World’s Most-Used Programming Language 7th Edition

See you in the next post!

%d bloggers like this: