Powering every modern website or web application are, at a minimum, three technologies: HTML, Cascading Style Sheets (CSS), and JavaScript. They are the "best friends" of the frontend, and are illustrated in the following screenshot:
Figure 1.1 - The best friends: HTML, CSS, and JavaScript
At the intersection of the three technologies is where our modern website lives. Let's take a look at these in the following sections.
HTML, the overlooked hero
When we think about the web, the basic structure of a site—the skeleton, if you will—is HTML. However, with its (purposeful) simplicity, it's often ignored as being a simple technology. One way to think about a website is thinking about a body: HTML is the skeleton; CSS is the skin; our friend JavaScript is the muscle.
HTML's history is inextricably tied to that of the web itself, as it continues to evolve with advancing specifications, features, and syntax as the web itself grows. But what is HTML? It's not a full-fledged programming language: it can't do logic or manipulate data. However, as a markup language, it's incredibly important to our use of the web. We won't spend too much time talking about HTML, but some basics will get us on the right track.
The HTML specification is controlled by the World Wide Web Consortium (W3C), and its current version is HTML5. HTML's grammar consists of elements, called tags, that have specific definitions and are surrounded by angle brackets. When used in JavaScript, these tags describe nodes of data that JavaScript can read and manipulate.
Why is HTML important to us in JavaScript? JavaScript can touch HTML using the browser's internal Application Programming Interface (API) called the Document Object Model (DOM). The DOM is the programmatic representation of all the HTML on the page, and it dictates how JavaScript can manipulate elements on a rendered page. Unlike Python, JavaScript can react to user inputs without communicating back to the server; its execution logic can happen on the frontend. Think about when you enter information in a form on a website. Sometimes, there are required fields, and if you attempt to submit the form, JavaScript can halt the submission to the server and give visual cues—such as red outlines on required boxes and a warning message—and convey to the user that information is missing. This is an example of JavaScript using the DOM for interactivity. We'll dive further into this later on, in Chapter 7, Events, Event-Driven Design, and APIs.
Here's an example of a simple HTML5 boilerplate:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<h1>Welcome to my page!</h1>
<p>Here’s where you can learn all about me</p>
</body>
</html>
It's pretty legible in and of itself: contained within tags titled title is a string containing a simple title for this page. In the meta tag, we have one more element besides the name of the tag: the charset attribute. HTML5 also introduced semantic tags, which not only provide a visual structure to the page but also describe the purpose of the tag. For example, nav and footer are used to denote navigation and footer sections on a page. If you'd like to experiment with HTML, CSS, and JavaScript as we progress, you can use a tool such as Codepen.io or JSFiddle.net. Since we're so far only working with client-side work, you don't need a compiler or any other software on your computer. You can also work locally with your favorite text editor and then load your HTML in a browser.
One more set of attributes that are important to our needs with JavaScript are class and id. These attributes provide an efficient conduit by which JavaScript can access HTML. Let's take a look in the following code block at a more fleshed-out example of HTML:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<h1 id="header">Welcome to my page!</h1>
<label for="name">Please enter your name:</label>
<form>
<input type="text" placeholder="Name here" name="name" id="name" />
<p class="error hidden" id="error">Please enter your name.</p>
<button type="submit" id="submit">Submit</button>
</form>
</body>
</html>
The output of this will give us a very simple page, as follows:
Figure 1.2 - A simple HTML page
Very basic, right? Why is Please enter your name repeated? If you notice the second p tag on the page, one of its classes is hidden. However, we can still see it. We'll need CSS to help us out here.
CSS
If HTML is the bone structure of our page, then CSS is the skin of it, giving it a look and feel. Working with JavaScript on the frontend inherently takes into consideration CSS as well. In the example of our website form, the red outlines and warning messages are often triggered by toggling CSS classes. Here's a short example of CSS:
.error {
color: red;
font-weight: bold;
}
In this example, we have one CSS declaration (the error class, denoted as a class by the period preceding its name), and two CSS rules inside the curly braces for font color and font weight. It won't be important for now to be fully versed in CSS structure and rules, but as a JavaScript developer for the frontend, you will likely interact with CSS. For example, toggling our error class to make the text in our form red and bold is one way that JavaScript can trigger a message to the user, informing them that there's a problem with the form submission.
Let's add the preceding CSS into our previous HTML work. We can see this results in the following change:
Figure 1.3 - Adding a bit of CSS
Now, we can see that the rules of red and bold are being reflected, but we can still see the paragraph. Our next two CSS rules are the following ones:
.hidden {
display: none;
}
.show {
display: block;
}
This is a little closer to what we expect to see. But why make a paragraph just to hide it with CSS?
JavaScript
Enter our friend, JavaScript. If JavaScript is going to be the muscles of the body, it's then responsible for manipulating the bones (HTML) and the skin (CSS). Our human muscles can't do all that much to change our physical appearance, but they can certainly put us in different positions, expanding and contracting our elastic skin and manipulating the positions of our bones. With JavaScript, it's possible to rearrange content on a page, change colors, create animations, and much more. We'll be diving deeply into how JavaScript interacts with HTML and CSS because, after all, JavaScript is why we're here now, reading this book!
One of the most notable points to make about JavaScript versus Python is that, in order to make changes to a page, a Pythonic program would have to respond to input from the client side from the server, and then the browser would re-render the HTML. JavaScript avoids this by executing in the browser.
For example, in our page shown previously, if the user tries to submit the form without entering a name, JavaScript can remove the hidden class and add the show class, at which point the error message shows. This is a very simple example, but it underscores the idea that JavaScript can execute changes in the browser without calling back to the server. Let's put the pieces together.
The HTML is shown in the following example:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Page</title>
</head>
<body>
<h1 id="header">Welcome to my page!</h1>
<form>
<label for="name">Please enter your name:</label>
<input type="text" placeholder="Name here" name="name" id="name" />
<p class="error hidden" id="error">Please enter your name.</p>
<button type="submit" id="submit">Submit</button>
</form>
</body>
</html>
The CSS is shown in the following example:
.error {
color: red;
font-weight: bold;
}
.hidden {
display: none;
}
.show {
display: block;
}
Now, let's write some JavaScript. This likely won't make sense yet, but if you're working along in an editor such as JSFiddle, try to place the following JavaScript in the JS pane and hit Run:
document.getElementById('submit').onclick = e => {
e.preventDefault()
if (document.getElementById('name').value === '') {
document.getElementById('error').classList.toggle('hidden')
document.getElementById('error').classList.toggle('show')
}
}
Now, if you run this and click Submit without entering any data into the box, our error message will display. Very simple so far, but congratulations! You just wrote some JavaScript! Now, how would we do this with Python? We'd have to submit the form to our backend, evaluate the inputs provided, and re-render the page with our error message.
Instead, welcome to working with the frontend.