How HTML groups related items, presents tabular data, and collects information from users — and why accessibility is built into these structures from the first line of code
Open almost any real website and you will find the same three content structures appearing again and again: a list of links in a navigation menu, a table of prices or scores or scheduled events, and a form asking for a name, an email address, or a message. These are not decorative choices. They are some of the oldest and most important structural patterns in HTML, and they exist because human information naturally groups itself into collections, grids, and questions that need answers.
This chapter teaches all three. You will learn how to group related items with ordered, unordered, and description lists. You will learn how to build tables that present data clearly, with headers that a screen reader can announce correctly. And you will learn how to build forms — the part of the web that turns a one-way page into a two-way conversation between a website and the person using it. Throughout, one idea will return again and again: HTML structures carry meaning, and that meaning is what makes a page usable by everyone, not just by people who can see a bulleted dot or a boxed-in grid.
A recipe page lists ingredients and then lists steps. A class schedule shows days, times, and rooms in a grid. A contact page asks for a name, an email address, and a message, then waits for the visitor to click a button. What do these three things have in common? Each one takes loosely related pieces of content — items, data points, or questions — and gives them a structure a browser can understand, a screen reader can announce, and CSS can style consistently. By the end of this chapter, you will know how to build all three, and you will understand why the structure matters as much as the content inside it.
By the end of this chapter, you should be able to:
<table>, <tr>, <th>, and <td>.scope attribute, <caption>, and table sectioning elements.colspan and rowspan to merge table cells correctly.<form> element and its action and method attributes.<input> type, <textarea>, or <select> element for a given kind of data.<fieldset> and <legend>.When you read a recipe, a schedule, a course syllabus, or a shopping cart, you are reading a list. Lists are one of the oldest and most natural ways human beings organize information. HTML reflects this. It gives you three different list elements depending on what kind of grouping you need, and each one carries a specific kind of meaning.
Before HTML had list elements, some developers made "lists" by typing items on separate lines and adding dashes or numbers manually as plain text. This approach looks correct to a human eye, but it tells a browser nothing about the structure. A screen reader cannot identify a manually typed dash followed by text as a list item. A search engine cannot tell that the ten lines you typed are related. CSS cannot easily target "the third item in this list" if the browser does not know a list is there.
HTML lists solve this by wrapping related items in a container element and marking each item with a consistent element. When the browser reads a list, it knows the items belong together. When a screen reader reaches a list, it announces how many items the list contains and lets the user navigate between them. When CSS applies a style to a list, it can target every item with one rule.
Each type has a different element, but they share a common idea: the list is a container, and each item inside it is marked individually. The next two sections work through each list type in detail.
An unordered list is a collection of items where the order is not meaningful. A list of ingredients, a list of features on a product page, a set of links in a navigation menu — these are all unordered because the items could be rearranged without changing what the list means.
The element for an unordered list is <ul>. Each item inside the list uses the <li> element, which stands for list item. The browser displays each item with a bullet point by default.
<ul> <li>HTML</li> <li>CSS</li> <li>JavaScript</li> </ul>
The bullet style is a browser default. CSS can change it to a different symbol, remove it entirely, or replace it with a custom icon — you will work with CSS list styling in Part III. For now, focus on the structure.
Notice the indentation. The <li> elements are indented inside the <ul> element. This indentation is a convention, not a technical requirement, but it is a strong convention for good reason: it makes the parent-child relationship visible at a glance. The <ul> element is the parent. Each <li> element is its child.
An ordered list is a collection of items where the sequence matters. A numbered set of steps, a ranking, a recipe with a specific procedure — these need order because doing step three before step one would give a different, and probably wrong, result.
The element for an ordered list is <ol>. Items still use <li>.
<ol> <li>Open your text editor.</li> <li>Create a new file called index.html.</li> <li>Type the HTML document skeleton.</li> <li>Save the file.</li> <li>Open the file in your browser.</li> </ol>
The browser generates the numbers for an ordered list automatically. You do not type them. If you later insert a new step between step two and step three, the browser renumbers every step correctly. If you had typed the numbers manually as plain text, you would have to update every number by hand.
Lists can be nested. An item in an outer list can contain its own inner list. This is useful for outlines, sub-steps, and hierarchical content. The inner list must be placed inside an <li> element of the outer list — never directly inside the outer list container.
<ol>
<li>Step one
<ul>
<li>Sub-step A</li>
<li>Sub-step B</li>
</ul>
</li>
<li>Step two</li>
</ol>
<ol>
<li>Step one</li>
<ul>
<li>Sub-step A</li>
</ul>
<li>Step two</li>
</ol>
The incorrect version places a <ul> directly inside an <ol> rather than inside an <li>. Browsers may still render it visually, but the structure is invalid HTML, and assistive technologies may misread the relationship between the steps and the sub-items.
A list item can contain plain text, but it can also contain other elements: links, images, headings at an appropriate level, paragraphs, and even other lists. The <li> element is a container.
<ul> <li><a href="about.html">About Us</a></li> <li><a href="lessons.html">Lessons</a></li> <li><a href="contact.html">Contact</a></li> </ul>
This is exactly how navigation menus are structured in real websites. The navigation bar on a finished site looks like a horizontal row of links styled with CSS — but underneath, it is almost always an unordered list of anchor elements.
A description list is a structure for pairing terms with their definitions or explanations. A glossary, a FAQ section, a specification sheet, or a product feature list with labels and values — these are all good candidates for a description list.
The element for a description list is <dl>. Inside it, each term uses <dt> (description term), and each definition uses <dd> (description detail).
<dl> <dt>HTML</dt> <dd>HyperText Markup Language. The structural language of web pages.</dd> <dt>CSS</dt> <dd>Cascading Style Sheets. The language used to control visual presentation.</dd> <dt>JavaScript</dt> <dd>A programming language that runs in the browser to add interactivity.</dd> </dl>
By default, browsers display <dt> terms on their own line and indent the <dd> definitions below them, though the exact appearance varies by browser. One term can have multiple definitions, and one definition block can follow multiple terms:
<dl> <dt>Viewport</dt> <dt>Browser viewport</dt> <dd>The visible area of a web page inside a browser window.</dd> </dl>
Description lists are used less often than <ul> and <ol>, but they carry specific semantic meaning that cannot be replicated well with other elements. When your content is truly a set of term-definition pairs, <dl> communicates that relationship to browsers and assistive technologies.
A table is a grid of rows and columns used to display data where the relationship between values across both rows and columns is meaningful. A class schedule, a comparison of pricing plans, a grade sheet, a sports standings chart, a dataset of historical measurements — these are data that belong in a table.
In the early years of the web, before CSS provided powerful layout tools, developers used tables to control where content appeared on the page. They put navigation in one table cell and main content in another. This practice was abandoned long ago. CSS handles layout. Tables carry data. Mixing these roles produces broken structure, poor accessibility, and code that is very difficult to maintain.
A table uses four core elements working together:
<table> wraps the entire table.<tr> defines a table row.<th> defines a header cell. By default, browsers bold and center the text inside it.<td> defines a data cell, also called a regular cell.<table>
<tr>
<th>Student</th>
<th>Score</th>
<th>Grade</th>
</tr>
<tr>
<td>Amara</td>
<td>94</td>
<td>A</td>
</tr>
<tr>
<td>Brendan</td>
<td>81</td>
<td>B</td>
</tr>
<tr>
<td>Chloé</td>
<td>76</td>
<td>C</td>
</tr>
</table>
Every row should have the same number of cells unless you are deliberately spanning cells, covered in the next section. A table where rows have different numbers of cells will often display incorrectly and is confusing to read.
Headers identify what a column or row means. But a browser and a screen reader cannot always determine whether a <th> cell applies to the column below it or the row beside it. The scope attribute makes this explicit.
<table>
<tr>
<th scope="col">Student</th>
<th scope="col">Score</th>
<th scope="col">Grade</th>
</tr>
<tr>
<td>Amara</td>
<td>94</td>
<td>A</td>
</tr>
</table>
Using scope="col" tells assistive technologies that this header applies to all cells in its column. You can also use scope="row" when the header applies to cells in its row, which is common in tables that have both row and column headers.
<table>
<tr>
<th scope="col">Day</th>
<th scope="col">Topic</th>
<th scope="col">Assignment</th>
</tr>
<tr>
<th scope="row">Monday</th>
<td>HTML Lists</td>
<td>Build a glossary page</td>
</tr>
<tr>
<th scope="row">Wednesday</th>
<td>HTML Tables</td>
<td>Build a schedule table</td>
</tr>
</table>
Adding scope to header cells is a simple habit that meaningfully improves how screen readers present your tables. It is one of the most direct and easy accessibility improvements you can make to tabular data.
A caption is a title for the table. It appears directly above or below the table and is visually and programmatically associated with it. The <caption> element goes immediately after the opening <table> tag, before any rows.
<table>
<caption>Final Exam Scores — Spring Semester</caption>
<tr>
<th scope="col">Student</th>
<th scope="col">Score</th>
<th scope="col">Grade</th>
</tr>
<tr>
<td>Amara</td>
<td>94</td>
<td>A</td>
</tr>
</table>
Screen readers announce the caption before reading the table, which helps users understand what they are about to hear. Captions are also valuable for sighted users — a table with a caption is faster to understand than a table with only a heading in the text above it, because the caption is part of the table itself.
For more complex tables, HTML provides three grouping elements: <thead> groups the header row or rows, <tbody> groups the main data rows, and <tfoot> groups footer rows, often used for totals or summary rows.
<table>
<caption>Course Fees</caption>
<thead>
<tr>
<th scope="col">Course</th>
<th scope="col">Credits</th>
<th scope="col">Fee</th>
</tr>
</thead>
<tbody>
<tr>
<td>Web Development</td>
<td>3</td>
<td>$420</td>
</tr>
<tr>
<td>Programming with Python</td>
<td>3</td>
<td>$420</td>
</tr>
<tr>
<td>Computer Science Foundations</td>
<td>3</td>
<td>$420</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">Total</td>
<td>$1,260</td>
</tr>
</tfoot>
</table>
The colspan="2" attribute in the footer row causes that cell to span two columns, merging the "Course" and "Credits" columns into a single "Total" label. Sectioning a table with <thead>, <tbody>, and <tfoot> improves accessibility, allows CSS to target sections separately, and enables some browsers to repeat the header row on each printed page.
Sometimes a single cell should span multiple columns or multiple rows. A merged header, a grouped category, a summary label — these all call for spanning. colspan merges cells horizontally, and rowspan merges cells vertically.
<tr> <th colspan="2" scope="colgroup">Contact Information</th> <th scope="col">Department</th> </tr> <tr> <th scope="col">Name</th> <th scope="col">Email</th> <th scope="col">Department</th> </tr>
<tr> <th rowspan="2" scope="rowgroup">Spring</th> <td>March</td> <td>Registration opens</td> </tr> <tr> <td>April</td> <td>Classes begin</td> </tr>
Spanning is powerful but can easily produce broken layouts. If you add a colspan="2" to a cell, the total number of columns in that row is reduced by one. The math must stay consistent across all rows. A common beginner mistake is adding a span without adjusting the number of cells in affected rows, which causes columns to misalign.
A form is a part of a web page that accepts input from a user and sends that input somewhere — to a server, to a script, or to some other process. Forms are fundamental to interactive web experiences. Without forms, users could not search, register, log in, comment, buy, subscribe, complete surveys, or submit work.
You encounter forms constantly: the search bar on any website, the login screen, the checkout process in an online store, the contact page on a company's site, the admission application for a school, the survey at the end of a purchase.
From the HTML side, a form is a container with input fields. Each field collects one piece of information — a name, an email address, a choice from a set of options, a block of text, a file, a date. The browser manages the appearance and behavior of each field type based on the input type you specify.
A form begins with the <form> element, which wraps all of the form's fields and controls.
<form action="submit.html" method="post"> <!-- form fields go here --> </form>
Two attributes appear on <form> most often:
| Attribute | Purpose |
|---|---|
| action | Specifies where the form data will be sent when the user submits it. In a real website, this is a server-side script that processes the data. For now, it can be a placeholder URL or omitted entirely. |
| method | Specifies how the data is sent. The value get adds data to the URL as query parameters, which is visible to the user and suitable for searches. The value post sends data in the background, which is suitable for sensitive information like passwords and form submissions. |
In this chapter, you will not write the server-side code that processes form data. You will learn to build the HTML structure of the form correctly. JavaScript-based form validation and client-side form handling come in Chapter 24.
Before learning any input element, you need to understand labels. Every visible form field needs a <label> element associated with it. This is not optional. It is one of the clearest and most important accessibility rules in web development.
A label tells the user what a field is for. Without a label, a user sees a blank text box and does not know what to type. With a label, the user sees "Email address" or "Your message" beside the field.
But a label does more than display text. When a label is properly associated with its input field:
The primary way to associate a label with an input is with the for attribute on the label and the id attribute on the input. The value of for must exactly match the value of id.
<label for="email">Email address</label> <input type="text" id="email" name="email">
The for on the label must exactly match the id on the input. If the values do not match — even by a single character — the association is broken and the benefits described above are lost. The browser will not warn you. The form will look correct visually while failing silently for assistive technology users.
The <input> element is a void element — it has no closing tag. It renders a wide variety of controls depending on its type attribute.
The name attribute on every input is important for form submission. When the form is submitted, the browser sends name-value pairs to the server. If an input has no name, its value is not sent.
<label for="username">Username</label> <input type="text" id="username" name="username">
| Type Value | Behavior |
|---|---|
| text | The default type. Renders a single-line text field. |
| Renders a text field that validates basic email format on modern browsers. Opens an email-optimized keyboard on mobile. | |
| password | Renders a text field where characters are hidden — shown as dots or asterisks — to protect sensitive input. |
| number | Renders a field that accepts numerical input, usually with small increment/decrement arrows. min, max, and step can constrain the range. |
| tel | Intended for telephone numbers. Does not enforce a specific format, but opens a numeric keyboard on mobile. |
| url | Renders a text field that validates URL format. Opens a keyboard with easy access to dots and slashes on mobile. |
| date | Renders a date picker in supporting browsers, letting users select a year, month, and day. |
| hidden | Renders nothing visible but sends a value with the form — used for information the user does not need to see, such as a form identifier. |
<label for="age">Age</label> <input type="number" id="age" name="age" min="1" max="120"> <label for="phone">Phone number</label> <input type="tel" id="phone" name="phone"> <label for="startdate">Start date</label> <input type="date" id="startdate" name="startdate"> <input type="hidden" name="form-version" value="2">
| Attribute | Purpose |
|---|---|
| placeholder | Light gray hint text shown inside the field before the user types. Not a substitute for a label. |
| required | Marks the field as required. The browser will refuse submission if it is empty. |
| value | Sets a default value that appears pre-filled in the field. |
| disabled | Makes the field visible but not interactive. Its value is not submitted. |
| readonly | Allows the user to see and select the value but not change it. Its value is submitted. |
| maxlength | Limits the number of characters the user can type. |
| autocomplete | Hints to the browser about auto-fill behavior. |
Using placeholder instead of a label. A placeholder disappears when the user starts typing. If the user pauses midway through filling out the form, they can no longer see what the field asked for. Labels remain visible at all times. Always use both: a visible <label> for the field's purpose, and an optional placeholder for an example value.
<label for="email">Email address</label> <input type="email" id="email" name="email" placeholder="[email protected]">
<input type="email" id="email" name="email" placeholder="Email address">
A button inside a form submits the form by default. The <button> element is the standard way to create a form button.
<button type="submit">Send Message</button>
The type="submit" attribute makes the button submit the form. You can also use type="button" to create a button that does not submit the form by default — useful when JavaScript will handle the click.
<button type="button">Preview</button>
There is also type="reset", which clears all fields in the form back to their default values. This is rarely used on modern sites because accidentally clicking reset can frustrate users who have filled in a long form.
The <input type="submit"> element also creates a submit button, but <button> is generally preferred because it can contain HTML content, such as an icon.
<!-- Both produce a submit button --> <button type="submit">Send</button> <input type="submit" value="Send">
"Submit" is adequate but vague. "Send Message," "Create Account," "Apply Now," or "Download Report" tell the user exactly what will happen when they click. This matters for all users, but especially for screen reader users who may navigate directly to buttons.
A text area is a multi-line text input. Use it when you expect longer text: a message, a comment, a description, a biography.
The <textarea> element has an opening and closing tag. Any content between them becomes the default value. The rows and cols attributes suggest the initial display size, though CSS is more reliable for controlling dimensions.
<label for="bio">Short biography</label> <textarea id="bio" name="bio" rows="4" placeholder="Tell us a little about yourself." maxlength="500"></textarea>
Unlike <input>, <textarea> does not have a type attribute — it is always a multi-line text field. It does accept required, placeholder, maxlength, disabled, and readonly attributes.
A select menu presents a list of options in a dropdown. The <select> element wraps <option> elements, each representing one choice.
<label for="country">Country</label> <select id="country" name="country"> <option value="">— Select your country —</option> <option value="us">United States</option> <option value="ca">Canada</option> <option value="mx">Mexico</option> <option value="gb">United Kingdom</option> </select>
Each <option> has a value attribute — this is what gets submitted with the form. The text inside the <option> tags is what the user sees. These can be different: the user sees "United States," but the form submits the value "us".
The first option in the example above has an empty value and serves as a prompt. Without a selected option, users might not notice they need to choose one. Adding a prompt option makes the field's purpose clear.
The selected attribute marks an option as the pre-selected choice:
<option value="ca" selected>Canada</option>
For long lists, <optgroup> groups related options under a label:
<select id="timezone" name="timezone">
<optgroup label="North America">
<option value="est">Eastern Time (UTC-5)</option>
<option value="cst">Central Time (UTC-6)</option>
<option value="pst">Pacific Time (UTC-8)</option>
</optgroup>
<optgroup label="Europe">
<option value="gmt">Greenwich Mean Time (UTC+0)</option>
<option value="cet">Central European Time (UTC+1)</option>
</optgroup>
</select>
Adding the multiple attribute allows users to select more than one option at once, which displays the list as a scrollable box rather than a dropdown.
Checkboxes and radio buttons are input elements for selecting options. They work similarly in HTML but communicate different kinds of choices to the user.
A checkbox represents a single on/off choice, or one item from a group of independent options where any number can be selected.
<label> <input type="checkbox" name="newsletter" value="yes"> Subscribe to our newsletter </label>
Notice the structure here: the <input> is placed inside the <label> element. This is called an implicit label association — because the input is inside the label, they are automatically associated without needing matching id and for attributes. Either approach is valid. Many developers prefer the explicit approach because it is clearer when reading the code, but both work correctly.
<input type="checkbox" id="terms" name="terms" value="agreed"> <label for="terms">I agree to the terms and conditions</label>
When a form has a group of checkboxes, each checkbox can have the same name but should have a distinct value. Only checked boxes submit their values.
<fieldset>
<legend>Which topics interest you?</legend>
<label>
<input type="checkbox" name="topics" value="html">
HTML
</label>
<label>
<input type="checkbox" name="topics" value="css">
CSS
</label>
<label>
<input type="checkbox" name="topics" value="javascript">
JavaScript
</label>
<label>
<input type="checkbox" name="topics" value="accessibility">
Accessibility
</label>
</fieldset>
The <fieldset> element groups related form controls. The <legend> element provides a caption for the group. A screen reader reads the legend before reading each option inside the fieldset, so a user hears "Which topics interest you? HTML checkbox, unchecked. CSS checkbox, unchecked." This context is essential when the group label is not otherwise connected to the individual controls. Always use <fieldset> and <legend> when grouping related checkboxes or radio buttons.
Radio buttons represent a single choice from a set of mutually exclusive options. When the user selects one radio button in a group, any previously selected radio button in the same group is automatically deselected — like the preset buttons on an old car radio, which is where the name comes from.
Radio buttons in the same group must share the same name attribute. Each button must have a distinct value.
<fieldset>
<legend>Preferred contact method</legend>
<label>
<input type="radio" name="contact" value="email">
Email
</label>
<label>
<input type="radio" name="contact" value="phone">
Phone
</label>
<label>
<input type="radio" name="contact" value="mail">
Postal mail
</label>
</fieldset>
Only one option in this group can be selected at a time. When the form is submitted, only the selected option's name and value are sent. You can add checked to pre-select one option:
<input type="radio" name="contact" value="email" checked>
The difference is in how many options can be selected simultaneously. Use checkboxes when any number of options can be selected, including zero or all. Use radio buttons when exactly one option must be selected from a group. A practical test: if the user could logically choose more than one answer, use checkboxes. If the user must commit to exactly one answer from the list, use radio buttons.
| Question | Input Type |
|---|---|
| Which languages do you know? | Checkboxes |
| What is your highest level of education? | Radio buttons |
| Select all that apply: | Checkboxes |
| Choose one: | Radio buttons |
| Which newsletters would you like? | Checkboxes |
| What is your preferred payment method? | Radio buttons |
You now have all the building blocks for a complete form. This section walks through building a realistic contact form from planning to finished code, focusing on accessible structure throughout.
A contact form typically collects the sender's name, the sender's email address, the subject of the message, the message itself, and a submit button. Before writing any code, it helps to list the fields, their types, whether they are required, and what their labels will say.
| Field | Input Type | Required? | Label Text |
|---|---|---|---|
| Full name | text | Yes | Your name |
| Yes | Email address | ||
| Subject | select | No | Subject |
| Message | textarea | Yes | Your message |
| Submit | button | — | Send Message |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Contact Us — Student Learning Site</title>
</head>
<body>
<main>
<h1>Contact Us</h1>
<p>Fill in the form below and we will get back to you within two business days.</p>
<form action="#" method="post" novalidate>
<div>
<label for="fullname">Your name <span aria-hidden="true">*</span></label>
<input
type="text"
id="fullname"
name="fullname"
autocomplete="name"
required>
</div>
<div>
<label for="email">Email address <span aria-hidden="true">*</span></label>
<input
type="email"
id="email"
name="email"
autocomplete="email"
placeholder="[email protected]"
required>
</div>
<div>
<label for="subject">Subject</label>
<select id="subject" name="subject">
<option value="">— Choose a subject —</option>
<option value="general">General question</option>
<option value="lessons">Questions about lessons</option>
<option value="resources">Questions about resources</option>
<option value="feedback">Feedback or suggestions</option>
<option value="other">Other</option>
</select>
</div>
<div>
<label for="message">Your message <span aria-hidden="true">*</span></label>
<textarea
id="message"
name="message"
rows="6"
required></textarea>
</div>
<p>Fields marked <span aria-hidden="true">*</span><span class="sr-only">with an asterisk</span> are required.</p>
<div>
<button type="submit">Send Message</button>
</div>
</form>
</main>
</body>
</html>
When a screen reader user navigates this form, they hear something like the sequence below:
Each piece of that experience depends on the HTML being correctly structured. Remove the labels and the user hears only blank edit fields with no context. Remove the required attributes and the user does not know which fields are mandatory. Remove the descriptive button text and the user hears only "button." Good form structure is not extra work layered on top of a finished form. It is how the form is built from the start.
This chapter introduced three major categories of HTML content structure: lists, tables, and forms. The running principle across all three is the same: HTML communicates structure and meaning, not just appearance. A list is not just indented text with bullets. A table is not just a grid drawn on a page. A form is not just a collection of boxes. Each is a semantic structure that the browser, search engines, and assistive technologies can read and use.
Read each code block carefully. For each one, describe what the browser would display and identify any problems.
<ul> <li>Planning</li> <li>Research</li> <li>Writing</li> <li>Editing</li> <li>Publishing</li> </ul>
<ol> <li>Preheat oven to 375 degrees.</li> <li>Mix dry ingredients in a large bowl.</li> <li>Add wet ingredients and stir until combined.</li> <li>Pour into a greased baking dish.</li> <li>Bake for 30 minutes.</li> </ol>
<ul>
<li>Vegetables
<ul>
<li>Carrots</li>
<li>Broccoli</li>
<li>Spinach</li>
</ul>
</li>
<li>Fruits
<ul>
<li>Apples</li>
<li>Bananas</li>
</ul>
</li>
<li>Grains</li>
</ul>
<table>
<tr>
<th>Day</th>
<th>High Temperature</th>
<th>Low Temperature</th>
</tr>
<tr>
<td>Monday</td>
<td>72°F</td>
<td>58°F</td>
</tr>
<tr>
<td>Tuesday</td>
<td>68°F</td>
<td>55°F</td>
</tr>
</table>
<form action="/contact" method="post"> <input type="text" name="username" placeholder="Enter your name"> <input type="email" name="email" placeholder="Enter your email"> <button type="submit">Submit</button> </form>
<fieldset>
<legend>Preferred learning format</legend>
<label>
<input type="radio" name="format" value="video">
Video lectures
</label>
<label>
<input type="radio" name="format" value="text">
Reading materials
</label>
<label>
<input type="radio" name="format" value="interactive">
Interactive exercises
</label>
</fieldset>
Write an unordered list of five tools a web developer uses. Use appropriate HTML structure with <ul> and <li>.
Write an ordered list of three major steps for starting a web project. Add an unordered sub-list of two to three items inside at least one step.
Write a description list with four terms and their definitions. Choose a topic from this chapter: HTML lists, HTML tables, HTML forms, or any four input types.
Write a table that shows a simple class schedule with four rows of data. Include a caption, header cells with scope="col", and wrap the rows in <thead> and <tbody> sections. The table should have these columns: Day, Time, Subject, Room.
Extend your schedule table from Task 4 by adding a <tfoot> row that spans all columns and contains a note such as "All rooms are in Building A." Use colspan to span the note across all four columns.
Write the HTML for three labeled input fields: a text field for a full name, an email field for an email address, and a text field for a phone number. Each field must have a visible <label> with a matching for and id. Each field must have a name attribute.
Write a labeled <select> menu that asks users to choose their time zone from a list of at least six options. Group the options using two <optgroup> elements.
Write a <fieldset> with a <legend> and four checkboxes representing four types of notifications a user might want to receive (for example: email digest, new lesson alerts, event reminders, weekly summary).
Write a <fieldset> with a <legend> and four radio buttons for a single-choice question. All radio buttons must share the same name and have distinct value attributes.
Write a labeled <textarea> for a "Short biography" field. The textarea should have at least four rows and include a placeholder hint. It should be marked as required.
Review the following form code and answer the questions.
<form>
<div>
<p>Name:</p>
<input type="text" name="name" placeholder="Your name">
</div>
<div>
<label>Email</label>
<input type="email" name="email">
</div>
<div>
<label for="msg">Message</label>
<input type="text" id="message" name="msg">
</div>
<div>
<input type="checkbox" name="agree" value="yes">
I agree to the terms.
</div>
<button>Go</button>
</form>
Each code block below contains one or more errors. Identify each error and write a corrected version.
<ol>
<ul>
<li>First step</li>
<li>Second step</li>
</ul>
<li>Third step</li>
</ol>
<table>
<tr>
<th>Name</th>
<th>Score</th>
</tr>
<tr>
<td>Priya</td>
<td>88</td>
<td>Passed</td>
</tr>
</table>
<label for="phone">Phone number</label> <input type="tel" id="telephone" name="phone">
<fieldset> <input type="radio" name="size" value="small"> Small <input type="radio" name="size" value="medium"> Medium <input type="radio" name="size" value="large"> Large </fieldset>
<label for="country">Country</label> <select name="country"> <option>United States</option> <option>Canada</option> <option>Mexico</option> </select>
Apples<br> Oranges<br> Bananas<br>
<ul> <li>Apples</li> <li>Oranges</li> <li>Bananas</li> </ul>
<ol>
<li>First</li>
<ul>
<li>Sub-item</li>
</ul>
<li>Second</li>
</ol>
<ol>
<li>First
<ul>
<li>Sub-item</li>
</ul>
</li>
<li>Second</li>
</ol>
<table>
<tr>
<td><nav>Navigation links here</nav></td>
<td><main>Page content here</main></td>
</tr>
</table>
<nav>Navigation links here</nav> <main>Page content here</main>
Tables are for data. CSS handles layout.
<label for="user-email">Email</label> <input type="email" id="email" name="email">
<label for="email">Email</label> <input type="email" id="email" name="email">
<input type="text" name="name" placeholder="Your name">
<label for="name">Your name</label> <input type="text" id="name" name="name" placeholder="e.g. Sam Rivera">
<input type="radio" name="size" value="s"> Small <input type="radio" name="size" value="m"> Medium <input type="radio" name="size" value="l"> Large
<fieldset> <legend>Choose a size</legend> <label><input type="radio" name="size" value="s"> Small</label> <label><input type="radio" name="size" value="m"> Medium</label> <label><input type="radio" name="size" value="l"> Large</label> </fieldset>
<select name="country"> <option>United States</option> <option>Canada</option> </select>
<select id="country" name="country"> <option value="us">United States</option> <option value="ca">Canada</option> </select>
These questions draw on material from Chapters 5 through 9.
Chapter 9 completed the major visible content structures of HTML: lists, tables, and forms. Chapter 10 moves from visible content to the hidden layer of HTML documents: metadata. You will learn how the <head> section communicates with browsers, search engines, and sharing platforms. Topics include character encoding, the viewport meta tag, page descriptions, favicons, and a first look at how HTML structure affects how a page appears in search results. Chapter 10 completes the HTML part of the book and sets the stage for moving into CSS in Part III.