Today I am super proud to announce that I have finally picked up the task of finishing my book titled, "HTML: A Comprehensive Guide". It feels wonderful to write that and put it out in the public domain (there is a hidden pun here).
You all now have the job of keeping me accountable. 😃
Here is the resolution of the pun. I am writing the book in public and releasing it under the MIT license (not quite public domain but close). This means that the book is open source. Yup, you read that correctly. With that said...
Writing a book takes a lot of time and dedication. I believe I have the dedication and the curiosity, but time is hard to come by these days as I am sure you are all aware. However, if you find the work I am doing on the book helpful and would like to support the work, here are a few things you can do.
- Share it widely.
- Read it, use it, and provide feedback.
- Contribute by raising an issue or even addressing an existing issue.
- Support me financially by signing up for any of the tiers on Patreon.
In so doing I hope to be able to dedicate more and more time not only to writing the book, but to teaching others who want to learn web development, continuing to produce the podcasts, and managing the Mycelium Network community (Join on Slack or Join on Discord). Creating in the open and teaching others to build standards-compliant and accessible websites is a passion of mine that fuels everything I do. I thank you for your interest and support and look forward to teaching and learning from all of you.
With that, here is the first chapter to give you a sense of what the book will be like. If you want more, follow the link below (I just published chapter two!).
Read, HTML: A Comprehensive Guide today!
Chapter 1: Getting Started with HTML
If one has always thought of HTML as just some form elements, div and span elements, links, and paragraph tags, it seems strange that one would dedicate an entire book to the language. As you will see throughout this book, there is a lot more to the HTML language.
What is HTML?
HTML stands for Hyper Text Markup Language and has been at the core of the web since its very inception in 1989. It forms the basis of all things on the web no matter how simple or how complex. Without HTML, there are no web pages or applications. HTML also provides the semantic structure of our documents and applications and this is where knowing the language really pays off. Semantic structure is also critical when it comes to the accessibility of your documents, a topic I will cover throughout the book.
There is a lot to HTML and some aspects of the language such as canvas
can take up an entire book on their own. For some topics such as this, I will provide an overview and then provide resources for further reading.
The html
element
We will start with the first element in every HTML document, the html
element.
What about the
DOCTYPE
? That is a good question. While theDOCTYPE
is the very first entry in our HTML documents, it is in fact not an HTML element. The sole purpose of theDOCTYPE
is to ensure that the browser does not switch into what is commonly known as quirks mode, but instead, makes a best effort attempt at following the relevant specification. I say, "best effort attempt", as not all browsers have implemented the entirety of the HTML specification. This is especially true of older browsers and so, these browsers will do their best to interpret the language and use a fallback where it does not understand the specific syntax.
The DOCTYPE
is required for all HTML documents and takes the following form:
<!DOCTYPE html>
There is an extended legacy form, but the above is all that you will ever need to be concerned with.
Now that the browser knows that what follows will be HTML, we start our document with our root element.
<html>
...
</html>
lang
Being at the root of our document, there is one attribute that should always be set on the html
element. The lang
attribute on the html
element indicates the primary natural language the document is written in. It also assists speech synthesis tools in what pronunciations to use and helps translation tools select the rules they should apply. This is critical for the overall accessibility of your documents. It takes the following form:
<html lang="en">
...
</html>
Should you not want your entire document to be localizable through translation tools, you can specify the translate
property, setting its value to no
:
<html lang="en" translate="no">
...
</html>
The head
element
The head
of our HTML document contains metadata about the document. So what is metadata? In short, it is “data about data”. Not all metadata lives in the head
though, and not all metadata that lives in the head
is necessarily descriptive, more on this later.
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
...
</html>
The title
element
The first piece of metadata we will add to our web pages is the title
tag. Seems like such a simple element, and it is, but while simple, it is critical to orient a user. The title
uniquely identifies the current page in the browser's history, is the first piece of information read to users using screen readers; is the title shown to users in search results, when sharing on social media, and is crucial for SEO(search engine optimization).
With that said, keep the following guidelines in mind when writing your title:
- Be concise when writing your titles and aim to keep the total character count at around 60.
- Remember that document titles should make sense when read out of context.
See the web content accessibility guidelines (WCAG) for more information on providing descriptive titles for web pages.
For example, the title for this chapter would read:
<!DOCTYPE html>
<html lang="en">
<head>
<title>
Chapter 1: Getting Started with HTML - HTML Comprehensive Guide
</title>
</head>
...
</html>
The title
tag does not have any special attributes but supports all the global attributes, one of which is translate
. Using this attribute, you can prevent translation tools from localizing your page title.
Why would you want to do that? Your page title could be the title of a poem or a song. In those cases, you do not want the title translated. For example:
<title translate="no">Revoir Paris | Roland Dyens</title>
Here, it would also be prudent to add a lang
attribute indicating the primary language used in the title
tag. As mentioned earlier, this will assist speech synthesis tools in what pronunciations to use. For example:
<title translate="no" lang="fr">Revoir Paris | Roland Dyens</title>
The base
element
The base
element is written as a self-closing, or void, tag. This means that, while a lot of tags in HTML are written as follows:
<title>My page title</title>
A self-closing tag is written like this:
<base href="https://html-comprehensive-guide.dev/" />
The base
element allows you to set a base URL for all links on the current page, set a base browsing context, or both, for all links on the page. Let’s look at an example.
<ul>
<li>
<a href="https://www.goodreads.com/book/show/11588.The_Shining"
>The Shining</a
>
</li>
<li>
<a href="https://www.goodreads.com/book/show/149267.The_Stand">The Stand</a>
</li>
<li><a href="https://www.goodreads.com/book/show/10614.Misery">Misery</a></li>
<li><a href="https://www.goodreads.com/book/show/10592.Carrie">Carrie</a></li>
</ul>
All of those links share the same base URL. Using the base
element, you can avoid repeating the base URL in every link tag:
<!DOCTYPE html>
<html lang="en">
<head>
<title>I got your base</title>
<base href="https://www.goodreads.com/" />
</head>
<body>
<ul>
<li><a href="book/show/11588.The_Shining">The Shining</a></li>
<li><a href="book/show/149267.The_Stand">The Stand</a></li>
<li><a href="book/show/10614.Misery">Misery</a></li>
<li><a href="book/show/10592.Carrie">Carrie</a></li>
</ul>
</body>
</html>
NOTE: If the HTML above was on a page that was hosted as part of the Goodreads website, you would not include the URL as part of the link and instead, opt for using relative URLs. In other words, instead of
https://www.goodreads.com/book/show/11588.The_Shining
you will do justbook/show/11588.The_Shining
. Thebase
element would therefore not be useful in this case.
Now, you may also want those links to always open in a new tab (browsing context). One option is to do:
<ul>
<li><a href="book/show/11588.The_Shining" target="_blank">The Shining</a></li>
<li><a href="book/show/149267.The_Stand" target="_blank">The Stand</a></li>
<li><a href="book/show/10614.Misery" target="_blank">Misery</a></li>
<li><a href="book/show/10592.Carrie" target="_blank">Carrie</a></li>
</ul>
As mentioned, there is a second attribute you can set on the base
element, and that attribute is the target
attribute. We can therefore avoid repeating target
:
NOTE: Be careful here as this could negatively impact the user experience and accessibility as there is nothing indicating to the user that all links will open in a new window or tab. While not a blanket statement, I almost always prefer to leave the choice of whether a link should open in the same or a different tab or window up to the user.
<!DOCTYPE html>
<html lang="en">
<head>
<title>I got your base</title>
<base href="https://www.goodreads.com/" target="_blank" />
</head>
<body>
<ul>
<li><a href="book/show/11588.The_Shining">The Shining</a></li>
<li><a href="book/show/149267.The_Stand">The Stand</a></li>
<li><a href="book/show/10614.Misery">Misery</a></li>
<li><a href="book/show/10592.Carrie">Carrie</a></li>
</ul>
</body>
</html>
With the above in place, all links on the current page will use https://www.googreads.com
as its base URL and all links will open in a new tab. The thing is, it does mean that all "links" will have this behavior. Not only are anchor tags affected but all elements with a href
attribute are affected. For example:
<base href="https://www.goodreads.com/" />
<link rel="stylesheet" type="text/css" href="css/pink.css" media="screen" />
In the above scenario, the browser will attempt to load the stylesheet from the Goodreads website, which is probably not what you intended. Thankfully, the base
element only affects elements below it in source order, so changing the above as follows will solve the problem:
<link rel="stylesheet" type="text/css" href="css/pink.css" media="screen" />
<base href="https://www.goodreads.com/" />
Remember that _blank
is not the only possible value for the target
attribute. One other value is _top
. Using _top
as the value of target
might be useful as a means of frame busting aka, prevent your site from being displayed in an iframe
.
<base target="_top" />
While this will not prevent the site from initially being loaded in an iframe
, it will cause clicks on any links in the page to bust out of the iframe
by setting its browsing context to the topmost browsing context i.e. the browser window itself.
I will close this chapter with an example use case that might be a bit of a stretch. I am using a combination of the base
element, a specific CSS class
on certain elements, and some JavaScript. The result is something that could be useful in a web application.
<!DOCTYPE html>
<html lang="en">
<head>
<base target="_blank" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>The HTML base element</title>
<link rel="stylesheet" type="text/css" href="css/pink.css" media="screen" />
</head>
<body>
<ul>
<li><a class="native" href="add-book">Add Book</a></li>
<li><a class="native" href="view">View Bookshelf</a></li>
</ul>
<ul>
<li>
<a href="https://amzn.to/3Olm2de">Misery</a>
</li>
<li>
<a href="https://amzn.to/3OlsCQM">Carrie</a>
</li>
</ul>
</body>
<script>
document.addEventListener("click", (event) => {
if (event.target.classList.contains("native")) {
event.preventDefault();
window.location = event.target.href;
}
});
</script>
</html>
With the above, clicking on any link that has a class
attribute with the value native
will be intercepted by JavaScript and opened in the same tab/window. All other links will open in a new tab. One interesting aspect to note about the above is that, even when intercepted by JavaScript, the value of event.target.href
will use the base href
value defined on the base
element, for example, https://www.goodreads.com/add-book
. So be careful 😄
Some final notes on the base
element. There must be no more than one base
element per page. If there are multiple, all but the first will be ignored. As with href
, all elements that have a target
attribute set are affected by the value of the target
attribute of the base
element. This means that forms with a target
will also be affected.
In case you are interested, here is the URL parsing algorithm (from the W3C documentation):
<base href="https://www.example.com/news/index.html" />
...
<a href="archives.html">archives</a>
<!-- The above URL will be https://www.example.com/news/archives.html -->
<a href="/blog/archives.html">archives</a>
<!-- The above URL will be https://www.example.com/blog/archives.html -->
<a href="./blog/archives.html">archives</a>
<!-- The above URL will be https://www.example.com/news/blog/archives.html -->
<a href="https://www.otherwebsite.com/blog/archives.html">archives</a>
<!-- The above URL will be https://www.otherwebsite.com/blog/archives.html -->