HTML Handbook
HTML Handbook
1. Introduction
2. Preface
3. HTML Basics
4. The document heading
5. The document body
6. Tags that interact with text
7. Links
8. Container tags and page structure HTML
9. Forms
10. Tables
11. Multimedia tags: audio and video
12. iframes
13. Images
14. Accessibility
Introduction
Welcome!
I wrote this book to help you quickly learn HTML and get familiar with the
advanced HTML topics.
HTML, a shorthand for Hyper Text Markup Language, is one of the most
fundamental building blocks of the Web.
HTML was officially born in 1993 and since then it evolved into its current
state, moving from simple text documents to powering rich Web
Applications.
This handbook is aimed at a vast audience.
First, the beginner. I explain HTML from zero in a succinct but
comprehensive way, so you can use this book to learn HTML from the
basics.
Then, the professional. HTML is often considered like a secondary thing to
learn. It might be given for granted.
Yet lots of things are obscure to many people. Me included. I wrote this
handbook to help my understanding of the topic, because when I need to
explain something, I better make sure I first know the thing inside out.
Even if you don't write HTML in your day to day work, knowing how
HTML works can help save you some headaches when you need to
understand it from time to time, for example while tweaking a web page.
Flavio
You can reach me via email at [email protected], on Twitter
@flaviocopes.
My website is flaviocopes.com.
Preface
Preface
Let's dive into this last case. Although in practice it's probably the least
popular way to generate HTML, it's still essential to know the basic
building blocks.
By convention, an HTML file is saved with a .html or .htm extension.
Inside this file, we organize the content using tags.
Tags wrap the content, and each tag gives a special meaning to the text it
wraps.
Let's make a few examples.
This HTML snippet creates a paragraph using the p tag:
This HTML snippet creates a list of items using the ul tag, which means
unordered list, and the li tags, which mean list item:
<ul>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
</ul>
When an HTML page is served by the browser, the tags are interpreted, and
the browser renders the elements according to the rules that define their
visual appearance.
Some of those rules are built-in, such as how a list renders or how a link is
underlined in blue.
Some other rules are set by you with CSS.
HTML is not presentational. It's not concerned with how things look.
Instead, it's concerned with what things mean.
It's up to the browser to determine how things look, with the directives
defined by who builds the page, with the CSS language.
Now, those two examples I made are HTML snippets taken outside of a
page context.
HTML page structure
Let's make an example of a proper HTML page.
Things start with the Document Type Declaration (aka doctype), a way to
tell the browser this is an HTML page, and which version of HTML we are
using.
Modern HTML uses this doctype:
<!DOCTYPE html>
Then we have the html element, which has an opening and closing tag:
<!DOCTYPE html>
<html>
...
</html>
Most tags come in pairs with an opening tag and a closing tag. The closing
tag is written the same as the opening tag, but with a / :
<sometag>some content</sometag>
There are a few self-closing tags, which means they don't need a separate
closing tag as they don't contain anything in them.
The html starting tag is used at the beginning of the document, right after
the document type declaration.
The html ending tag is the last thing present in an HTML document.
Inside the html element we have 2 elements: head and body :
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
</body>
</html>
Inside head we will have tags that are essential to creating a web page, like
the title, the metadata, and internal or external CSS and JavaScript. Mostly
things that do not directly appear on the page, but only help the browser (or
bots like the Google search bot) display it properly.
Inside body we will have the content of the page. The visible stuff.
Tags vs elements
I mentioned tags and elements. What's the difference?
Elements have a starting tag and a closing tag. In this example, we use the
p starting and closing tags to create a p element:
starting tag
text content (and possibly other elements)
closing tag
If an element has doesn't have a closing tag, it is only written with the
starting tag, and it cannot contain any text content.
That said, I might use the tag or element term in the book meaning the same
thing, except if I explicitly mention starting tag or ending tag.
Attributes
The starting tag of an element can have special snippets of information we
can attach, called attributes.
Attributes have the key="value" syntax:
You can also use single quotes, but using double quotes in HTML is a
nice convention.
We can have many of them:
and some attributes are boolean, meaning you only need the key:
The class and id attributes are two of the most common you will find
used.
They have a special meaning, and they are useful both in CSS and
JavaScript.
The difference between the two is that an id is unique in the context of a
web page; it cannot be duplicated.
Classes, on the other hand, can appear multiple times on multiple elements.
Plus, an id is just one value. class can hold multiple values, separated by
a space:
Case insensitive
HTML is case insensitive. Tags can be written in all caps, or lowercase. In
the early days, caps were the norm. Today lowercase is the norm. It is a
convention.
You usually write like this:
White space
Pretty important. In HTML, even if you add multiple white spaces into a
line, it's collapsed by the browser's CSS engine.
For example the rendering of this paragraph
<p>A paragraph
of
text </p>
Using the white-space CSS property you can change how things behave.
You can find more information on how CSS processes white space in
the CSS Spec
I'd say use the syntax that makes things visually more organized and easier
to read, but you can use any syntax you like.
I typically favor
or
<p>
A paragraph of text
</p>
<body>
<p>
A paragraph of text
</p>
<ul>
<li>A list item</li>
</ul>
</body>
Note: this "white space is not relevant" feature means that if you want
to add additional space, it can make you pretty mad. I suggest you use
CSS to make more space when needed.
Note: in special cases, you can use the HTML entity (an
acronym that means non-breaking space) - more on HTML entities
later on. I think this should not be abused. CSS is always preferred to
alter the visual presentation.
The document heading
The document heading
The head tag contains special tags that define the document properties.
It's always written before the body tag, right after the opening html tag:
<!DOCTYPE html>
<html>
<head>
...
</head>
...
</html>
We never use attributes on this tag. And we don't write content in it.
It's just a container for other tags. Inside it we can have a wide variety of
tags, depending on what you need to do:
title
script
noscript
link
style
base
meta
<script>
..some JS
</script>
Or you can load an external JavaScript file by using the src attribute:
<script src="file.js"></script>
Loading scripts by default blocks the rendering of the page until the script is
parsed and loaded.
By putting it at the bottom of the page, the script is loaded and executed
after the whole page is already parsed and loaded, giving a better
experience to the user over keeping it in the head tag.
My opinion is that this is now bad practice. Let script live in the head tag.
In modern JavaScript we have an alternative this is more performant than
keeping the script at the bottom of the page -- the defer attribute. This is an
example that loads a file.js file, relative to the current URL:
link tags
style tags
meta tags
to alter the resources served by the page, or the meta information, if scripts
are disabled.
In this example I set an element with the no-script-alert class to display if
scripts are disabled, as it was display: none by default:
<!DOCTYPE html>
<html>
<head>
...
<noscript>
<style>
.no-script-alert {
display: block;
}
</style>
</noscript>
...
</head>
...
</html>
Let's solve the other case: if put in the body, it can contain content, like
paragraphs and other tags, which are rendered in the UI.
<!DOCTYPE html>
<html>
<head>
...
<link href="file.css" rel="stylesheet">
...
</head>
...
</html>
This tag was also used for multi-page content, to indicate the previous and
next page using rel="prev" and rel="next" . Mostly for Google. As of 2019,
Google announced it does not use this tag any more because it can find the
correct page structure without it.
<style>
.some-css {}
</style>
As with the link tag, you can use the media attribute to use that CSS only
on the specified medium:
<style media="print">
.some-css {}
</style>
The base tag
This tag is used to set a base URL for all relative URLs contained in the
page.
<!DOCTYPE html>
<html>
<head>
...
<base href="https://flaviocopes.com/">
...
</head>
...
</html>
This might be used by Google to generate the page description in its result
pages, if it finds it better describes the page than the on-page content (don't
ask me how).
The charset meta tag is used to set the page character encoding. utf-8 in
most cases:
<meta charset="utf-8">
The robots meta tag instructs the Search Engine bots whether to index a
page or not:
You can set nofollow on individual links, too. This is how you can set
nofollow globally.
and more.
You can also just tell Google instead of targeting all search engines:
And other search engines might have their own meta tag, too.
Speaking of which, we can tell Google to disable some features. This
prevents the translate functionality in the search engine results:
After the closing head tag, we can only have one thing in an HTML
document: the body element.
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
</body>
</html>
Just like the head and html tags, we can only have one body tag in one
page.
Inside the body tag we have all the tags that define the content of the page.
Technically, the start and ending tags are optional. But I consider it a good
practice to add them. Just for clarity.
In the next chapters we'll define the variety of tags you can use inside the
page body.
But before, we must introduce a difference between block elements and
inline elements.
Block elements vs inline elements
Visual elements, the ones defined in the page body, can be generally
classified in 2 categories:
block elements ( p , div , heading elements, lists and list items, ...)
inline elements ( a , span , img , ...)
The p tag
This tag defines a paragraph of text.
<p>Some text</p>
code {
font-family: monospace;
}
This tag is typically wrapped in a pre tag, because the code element
ignores whitespace and line breaks. Like the p tag.
Chrome gives pre this default styling:
pre {
display: block;
font-family: monospace;
white-space: pre;
margin: 1em 0px;
}
unordered lists
ordered lists
definition lists
Unordered lists are created using the ul tag. Each item in the list is created
with the li tag:
<ul>
<li>First</li>
<li>Second</li>
</ul>
<ol>
<li>First</li>
<li>Second</li>
</ol>
The difference between the two is that ordered lists have a number before
each item:
Definition lists are a bit different. You have a term, and its definition:
<dl>
<dt>Flavio</dt>
<dd>The name</dd>
<dt>Copes</dt>
<dd>The surname</dd>
</dl>
Links are defined using the a tag. The link destination is set via its href
attribute.
Example:
Between the starting and closing tag we have the link text.
The above example is an absolute URL. Links also work with relative
URLs:
In this case, when clicking the link the user is moved to the /test URL on
the current origin.
Be careful with the / character. If omitted, instead of starting from the
origin, the browser will just add the test string to the current URL.
Example, I'm on the page https://flaviocopes.com/axios/ and I have these
links:
Link tags can include other things inside them, not just text. For example,
images:
<a href="https://flaviocopes.com">
<img src="test.jpg">
</a>
Container tags
HTML provides a set of container tags. Those tags can contain an
unspecified set of other tags.
We have:
article
section
div
article
The article tag identifies a thing that can be independent from other things
in a page.
For example a list of blog posts in the homepage.
Or a list of links.
<div>
<article>
<h2>A blog post</h2>
<a ...>Read more</a>
</article>
<article>
<h2>Another blog post</h2>
<a ...>Read more</a>
</article>
</div>
We're not limited to lists: an article can be the main element in a page.
<article>
<h2>A blog post</h2>
<p>Here is the content...</p>
</article>
section
<section>
<h2>A section of the page</h2>
<p>...</p>
<img ...>
</section>
div
<div>
...
</div>
nav
This tag is used to create the markup that defines the page navigation. Into
this we typically add an ul or ol list:
<nav>
<ol>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
</ol>
</nav>
aside
The aside tag is used to add a piece of content that is related to the main
content.
A box where to add a quote, for example. Or a sidebar.
Example:
<div>
<p>some text..</p>
<aside>
<p>A quote..</p>
</aside>
<p>other text...</p>
</div>
Using aside is a signal that the things it contains are not part of the regular
flow of the section it lives into.
header
The header tag represents a part of the page that is the introduction. It can
for example contain one or more heading tag ( h1 - h6 ), the tagline for the
article, an image.
<article>
<header>
<h1>Article title</h1>
</header>
...
</div>
main
<body>
....
<main>
<p>....</p>
</main>
</body>
footer
The footer tag is used to determine the footer of an article, or the footer of
the page:
<article>
....
<footer>
<p>Footer notes..</p>
</footer>
</div>
Forms
Forms
Forms are the way you can interact with a page, or an app, built with Web
technologies.
You have a set of controls, and when you submit the form, either with a
click to a "submit" button or programmatically, the browser will send the
data to the server.
By default this data sending causes the page to reload after the data is sent,
but using JavaScript you can alter this behavior (not going to explain how
in this book).
A form is created using the form tag:
<form>
...
</form>
By default forms are submitted using the GET HTTP method. Which has its
drawbacks, and usually you want to use POST.
You can set the form to use POST when submitted by using the method
attribute:
<form method="POST">
...
</form>
The form is submitted, either using GET or POST, to the same URL where
it resides.
So if the form is in the https://flaviocopes.com/contacts page, pressing the
"submit" button will make a request to that same URL.
Which might result in nothing happening.
You need something server-side to handle the request, and typically you
"listen" for those form submit events on a dedicated URL.
You can specify the URL via the action parameter:
This will cause the browser to submit the form data using POST to the
/new-contact URL on the same origin.
Let's introduce each one of them in the following form fields overview.
The input tag
The input field is one of the most widely used form elements. It's also a
very versatile element, and it can completely change behavior based on the
type attribute.
<input>
Equivalent to using:
<input type="text">
As with all the other fields that follow, you need to give the field a name in
order for its content to be sent to the server when the form is submitted:
The placeholder attribute is used to have some text showing up, in light
gray, when the field is empty. Useful to add a hint to the user for what to
type in:
Email
Using type="email" will validate client-side (in the browser) an email for
correctness (semantic correctness, not ensuring the email address is
existing) before submitting.
Password
Using type="password" will make every key entered appear as an asterisk (*)
or dot, useful for fields that host a password.
Numbers
You can have an input element accept only numbers:
The step attribute helps identify the steps between different values. For
example this accepts a value between 10 and 50, at steps of 5:
This is commonly used to store values like a CSRF token, used for security
and user identification, or even to detect robots sending spam, using special
techniques.
It can also just be used to identify a form and its action.
If you set a placeholder, that value will appear if the user clears the input
field value:
<input type="submit">
The value attribute sets the text on the button, which if missing shows the
"Submit" text:
File uploads
You can load files from your local computer and send them to the server
using a type="file" input element:
You can specify one or more file types allowed using the accept attribute.
This accepts images:
You can use a specific MIME type, like application/json or set a file
extension like .pdf . Or set multiple file extensions, like this:
Buttons
The type="button" input fields can be used to add additional buttons to the
form, that are not submit buttons:
<input type="reset">
Radio buttons
Radio buttons are used to create a set of choices, of which one is pressed
and all the others are disabled.
The name comes from old car radios that had this kind of interface.
You define a set of type="radio" inputs, all with the same name attribute,
and different value attribute:
Once the form is submitted, the color data property will have one single
value.
There's always one element checked. The first item is the one checked by
default.
You can set the value that's pre-selected using the checked attribute. You
can use it only once per radio inputs group.
Checkboxes
Similar to radio boxes, but they allow multiple values to be chosen, or none
at all.
You define a set of type="checkbox" inputs, all with the same name attribute,
and different value attribute:
The type="time" input field allows the user to enter a time, and shows a time
picker if needed:
The type="month" input field allows the user to enter a month and a year:
<input type="month" name="choose-release-month">
The type="week" input field allows the user to enter a week and a year:
All those fields allow to limit the range and the step between each value. I
recommend checking MDN for the little details on their usage.
The type="datetime-local" field lets you choose a date and a time.
Color picker
You can let users pick a color using the type="color" element:
The browser will take care of showing a color picker to the user.
Range
This input element shows a slider element. People can use it to move from a
starting value to an ending value:
Telephone
The type="tel" input field is used to enter a phone number:
The main selling point for using tel over text is on mobile, where the
device can choose to show a numeric keyboard.
Specify a pattern attribute for additional validation:
URL
The type="url" field is used to enter a URL.
<textarea></textarea>
You can set the dimensions using CSS, but also using the rows and cols
attributes:
As with the other form tags, the name attribute determines the name in the
data sent to the server:
<textarea name="article"></textarea>
The select tag
This tag is used to create a drop-down menu.
The user can choose one of the options available.
Each option is created using the option tag. You add a name to the select,
and a value to each option:
<select name="color">
<option value="red">Red</option>
<option value="yellow">Yellow</option>
</select>
<select name="color">
<option value="red" disabled>Red</option>
<option value="yellow">Yellow</option>
</select>
<select name="color">
<option value="">None</option>
<option value="red">Red</option>
<option value="yellow">Yellow</option>
</select>
Options can be grouped using the optgroup tag. Each option group has a
label attribute:
<select name="color">
<optgroup label="Primary">
<option value="red">Red</option>
<option value="yellow">Yellow</option>
<option value="blue">Blue</option>
</optgroup>
<optgroup label="Others">
<option value="green">Green</option>
<option value="pink">Pink</option>
</optgroup>
</select>
Tables
Tables
In the early days of the web tables were a very important part of building
layouts.
Later on they were replaced by CSS and its layout capabilities, and today we
have powerful tools like CSS Flexbox and CSS Grid to build layouts. Tables
are now used just for, guess what, building tables!
<table>
</table>
Inside the table we'll define the data. We reason in terms of rows, which
means we add rows into a table (not columns). We'll define columns inside a
row.
Rows
A row is added using the tr tag, and that's the only thing we can add into a
table element:
<table>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
This is a table with 3 rows.
The first row can take the role of the header.
Column headers
The table header contains the name of a column, typically in a bold font.
Think about an Excel / Google Sheets document. The top A-B-C-D... header.
<table>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
<tr></tr>
<tr></tr>
</table>
elements:
<table>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
<tr>
<td>Row 1 Column 1</td>
<td>Row 1 Column 2</td>
<td>Row 1 Column 3</td>
</tr>
<tr>
<td>Row 2 Column 1</td>
<td>Row 2 Column 2</td>
<td>Row 2 Column 3</td>
</tr>
</table>
This is how browsers render it, if you don't add any CSS styling:
Adding this CSS:
th, td {
padding: 10px;
border: 1px solid #333;
}
<table>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
<tr>
<td colspan="2">Row 1 Columns 1-2</td>
<td>Row 1 Column 3</td>
</tr>
<tr>
<td colspan="3">Row 2 Columns 1-3</td>
</tr>
</table>
Row headings
Before I explained how you can have column headings, using the th tag
inside the first tr tag of the table.
You can add a th tag as the first element inside a tr that's not the first tr
of the table, to have row headings:
<table>
<tr>
<th></th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
<tr>
<th>Row 1</th>
<td>Col 2</td>
<td>Col 3</td>
</tr>
<tr>
<th>Row 2</th>
<td>Col 2</td>
<td>Col 3</td>
</tr>
</table>
thead
tbody
tfoot
They wrap the tr tags to clearly define the different sections of the table.
Here's an example:
<table>
<thead>
<tr>
<th></th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<th>Row 1</th>
<td>Col 2</td>
<td>Col 3</td>
</tr>
<tr>
<th>Row 2</th>
<td>Col 2</td>
<td>Col 3</td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
<td>Footer of Col 1</td>
<td>Footer of Col 2</td>
</tr>
</tfoot>
</table>
Table caption
A table should have a caption tag that describes its content. That tag should
be put immediately after the opening table tag:
<table>
<caption>Dogs age</caption>
<tr>
<th>Dog</th>
<th>Age</th>
</tr>
<tr>
<td>Roger</td>
<td>7</td>
</tr>
</table>
Multimedia tags: audio and video
Multimedia tags: audio and video
In this section I want to show you the audio and video tags.
The audio tag
This tag allows you to embed audio content in your HTML pages.
This element can stream audio, maybe using a microphone via
getUserMedia() , or it can play an audio source which you reference using the
src attribute:
<audio src="file.mp3">
By default the browser does not show any controls for this element. Which
means the audio will play only if set to autoplay (more on this later) and the
user can't see how to stop it or control the volume or move through the
track.
To show the built-in controls, you can add the controls attribute:
An audio file by default does not play automatically. Add the autoplay
You can also play an audio file muted using the muted attribute (not really
sure what's the usefulness of this):
Using JavaScript you can listen for various events happening on an audio
element, the most basic of which are:
attribute:
<video src="file.mp4">
By default the browser does not show any controls for this element, just the
video.
Which means the video will play only if set to autoplay (more on this later)
and the user can't see how to stop it, pause it, control the volume or skip to a
specific position in the video.
To show the built-in controls, you can add the controls attribute:
A video file by default does not play automatically. Add the autoplay
attribute to play the video automatically:
The loop attribute restarts the video playing at 0:00 if set; otherwise, if not
present, the video stops at the end of the file:
If not present, the browser will display the first frame of the video as soon
as it's available.
You can set the width and height attributes to set the space that the
element will take so that the browser can account for it and it does not
change the layout when it's finally loaded. It takes a numeric value,
expressed in pixels.
Using JavaScript you can listen for various events happening on an video
element, the most basic of which are:
The iframe tag allows us to embed content coming from other origins
(other sites) into our web page.
Technically, an iframe creates a new nested browsing context. This means
that anything in the iframe does not interfere with the parent page, and vice
versa. JavaScript and CSS do not "leak" to/from iframes.
Many sites use iframes to perform various things. You might be familiar
with Codepen, Glitch or other sites that allow you to code in one part of the
page, and you see the result in a box. That's an iframe.
You create one this way:
<iframe src="page.html"></iframe>
<iframe src="https://site.com/page.html"></iframe>
You can set a set of width and height parameters (or set them using CSS)
otherwise the iframe will use the defaults, a 300x150 pixels box:
<iframe src="page.html"></iframe>
We can select what to allow by adding options in the sandbox attribute. You
can allow multiple ones by adding a space in between. Here's an incomplete
list of the options you can use:
no-referrer-when-downgrade it's the default, and does not send the referrer
when the current page is loaded over HTTPS and the iframe loads on
the HTTP protocol
no-referrer does not send the referrer header
origin the referrer is sent, and only contains the origin (port, protocol,
domain), not the origin + path which is the default
origin-when-cross-origin when loading from the same origin (port,
protocol, domain) in the iframe, the referrer is sent in its complete
form (origin + path). Otherwise only the origin is sent
same-origin the referrer is sent only when loading from the same origin
(port, protocol, domain) in the iframe
strict-origin sends the origin as the referrer if the current page is
loaded over HTTPS and the iframe also loads on the HTTPS protocol.
Sends nothing if the iframe is loaded over HTTP
strict-origin-when-cross-origin sends the origin + path as the referrer
when working on the same origin. Sends the origin as the referrer if
the current page is loaded over HTTPS and the iframe also loads on
the HTTPS protocol. Sends nothing if the iframe is loaded over HTTP
unsafe-url: sends the origin + path as the referrer even when loading
resources from HTTP and the current page is loaded over HTTPS
Images
Images
<img src="image.png">
We can use a wide set of images. The most common ones are PNG, JPEG,
GIF, SVG and more recently WebP.
The HTML standard requires an alt attribute to be present, to describe the
image. This is used by screen readers and also by search engine bots:
You can set the width and height attributes to set the space that the
element will take, so that the browser can account for it and it does not
change the layout when it's fully loaded. It takes a numeric value, expressed
in pixels.
<figure>
<img src="dog.png"
alt="A nice dog">
<figcaption>A nice dog</figcaption>
</figure>
The srcset attribute allows you to set responsive images that the browser
can use depending on the pixel density or window width, according to your
preferences. This way, it can only download the resources it needs to render
the page, without downloading a bigger image if it's on a mobile device, for
example.
Here's an example, where we give 4 additional images for 4 different screen
sizes:
<img src="dog.png"
alt="A picture of a dog"
srcset="dog-500.png 500w,
dog-800.png 800w,
dog-1000.png 1000w,
dog-1400.png 1400w">
<img src="dog.png"
alt="A picture of a dog"
sizes="(max-width: 500px) 100vw, (max-width: 900px) 50vw, 800px"
srcset="dog-500.png 500w,
dog-800.png 800w,
dog-1000.png 1000w,
dog-1400.png 1400w">
In this example the (max-width: 500px) 100vw, (max-width: 900px) 50vw, 800px
string in the sizes attribute describes the size of the image in relation to the
viewport, with multiple conditions separated by a semicolon.
The media condition max-width: 500px sets the size of the image in
correlation to the viewport width. In short, if the window size is < 500px, it
renders the image at 100% of the window size.
If the window size is bigger but < 900px , it renders the image at 50% of the
window size.
And if even bigger, it renders the image at 800px.
The vw unit of measure can be new to you, and in short we can say that 1
vw is 1% of the window width, so 100vw is 100% of the window width.
A useful website to generate the srcset and progressively smaller images is
https://responsivebreakpoints.com/.
The picture tag
HTML also gives us the picture tag, which does a very similar job to
srcset , and the differences are very subtle.
You use picture when instead of just serving a smaller version of a file,
you completely want to change it. Or serve a different image format.
The best use case I found is when serving a WebP image, which is a format
still not widely supported. In the picture tag you specify a list of images,
and they will be used in order, so in the next example, browsers that support
WebP will use the first image, and fallback to JPG if not:
<picture>
<source type="image/webp" srcset="image.webp">
<img src="image.jpg" alt="An image">
</picture>
The source tag defines one (or more) formats for the images. The img
tag is the fallback in case the browser is very old and does not support
the picture tag.
In the source tag inside picture you can add a media attribute to set media
queries.
The example that follows kind of works like the above example with
srcset :
<picture>
<source media="(min-width: 500w)" srcset="dog-500.png" sizes="100vw">
<source media="(min-width: 800w)" srcset="dog-800.png" sizes="100vw">
<source media="(min-width: 1000w)" srcset="dog-1000.png" sizes="800px">
<source media="(min-width: 1400w)" srcset="dog-1400.png" sizes="800px">
<img src="dog.png" alt="A dog image">
</picture>
But that's not its use case, because as you can see it's much more verbose.
The picture tag is recent but is now supported by all the major browsers
except Opera Mini and IE (all versions).
Accessibility
Accessibility
h1
h2
h3
h2
h2
h3
h4
Use strong and em instead of b and i . Visually they look the same, but
the first 2 have more meaning associated with them. b and i are more
visual elements.
Lists are important. A screen reader can detect a list and provide an
overview, then let the user choose to get into the list or not.
A table should have a caption tag that describes its content:
<table>
<caption>Dogs age</caption>
<tr>
<th>Dog</th>
<th>Age</th>
</tr>
<tr>
<td>Roger</td>
<td>7</td>
</tr>
</table>
Use alt attributes for images
All images must have an alt tag describing the image content. It's not just
a good practice, it's required by the HTML standard and your HTML
without it is not validated.
It's also good for search engines, if that's an incentive for you to add it.
Use the role attribute
The role attribute lets you assign specific roles to the various elements in
your page.
You can assign lots of different roles: complementary, list, listitem, main,
navigation, region, tab, alert, application, article, banner, button, cell,
checkbox, contentinfo, dialog, document, feed, figure, form, grid, gridcell,
heading, img, listbox, row, rowgroup, search, switch, table, tabpanel,
textbox, timer.
It's a lot and for the full reference of each of them I give you this MDN link.
But you don't need to assign a role to every element in the page. Screen
readers can infer from the HTML tag in most cases. For example you don't
need to add a role tag to semantic tags like nav , button , form .
Let's take the nav tag example. You can use it to define the page navigation
like this:
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</nav>
If you were forced to use a div tag instead of nav , you'd use the
navigation role:
<div role="navigation">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</div>
So here you got a practical example: role is used to assign a meaningful
value when the tag does not convey the meaning already.
Use the tabindex attribute
The tabindex attribute allows you to change the order of how pressing the
Tab key selects "selectable" elements. By defaults only links and form
elements are "selectable" by navigation using the Tab key (and you don't
need to set tabindex on them).
Adding tabindex="0" makes an element selectable:
<div tabindex="0">
...
</div>
aria-label
I use this attribute on my blog sidebar, where I have an input box for search
without an explicit label, as it has a placeholder attribute.
aria-labelledby
This attribute sets a correlation between the current element and the one
that labels it.
If you know how an input element can be associated to a label element,
that's similar.
We pass the item id that describes the current element.
Example:
<p aria-labelledby="description">
...
</p>
aria-describedby
This attribute lets us associate an element with another element that serves
as description.
Example:
<div id="payNowDescription">Clicking the button will send you to our Stripe for
m!</div>
https://www.w3.org/TR/WCAG20/
https://webaim.org
https://developers.google.com/web/fundamentals/accessibility/
Table of Contents
Introduction
Preface
HTML Basics
The document heading
The document body
Tags that interact with text
Links
Container tags and page structure HTML
Forms
Tables
Multimedia tags: audio and video
iframes
Images
Accessibility