feat(curriculum): add accessibility table workshop (#62161)

Co-authored-by: Dario <105294544+Dario-DC@users.noreply.github.com>
This commit is contained in:
Jessica Wilkins
2025-10-07 01:12:47 -07:00
committed by GitHub
parent d488e7cbde
commit c8aeac5ce8
18 changed files with 1278 additions and 0 deletions
+6
View File
@@ -2323,6 +2323,12 @@
"In these lessons, you will learn about how to create accessible tables and forms."
]
},
"workshop-tech-conference-schedule": {
"title": "Build a Tech Conference Schedule Table",
"intro": [
"In this workshop, you will build an accessible tech conference schedule table."
]
},
"lecture-introduction-to-aria": {
"title": "Introduction to ARIA",
"intro": [
@@ -0,0 +1,9 @@
---
title: Introduction to the Build a Tech Conference Schedule Table
block: workshop-tech-conference-schedule
superBlock: full-stack-developer
---
## Introduction to the Build a Tech Conference Schedule Table
In this workshop, you will build an accessible tech conference schedule table.
@@ -0,0 +1,48 @@
---
id: 68c33e502cd97f2fd52cb63b
title: Step 1
challengeType: 0
dashedName: step-1
demoType: onLoad
---
# --description--
In this workshop, you will learn how to make accessible table elements by building out a schedule for a tech conference.
Start by adding an `h1` element with the text `Tech Conference 2025 Schedule`.
# --hints--
You should have an `h1` element.
```js
const h1 = document.querySelector("h1");
assert.exists(h1);
```
Your `h1` element should have the text `Tech Conference 2025 Schedule`.
```js
const h1 = document.querySelector("h1");
assert.strictEqual(h1?.textContent.trim(), "Tech Conference 2025 Schedule");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
--fcc-editable-region--
--fcc-editable-region--
</body>
</html>
```
@@ -0,0 +1,53 @@
---
id: 68c341332d98fe38fae733af
title: Step 2
challengeType: 0
dashedName: step-2
---
# --description--
Now it is time to start building out the table.
Start by adding a `table` element below your `h1` element. Inside of the `table` element, add a `caption` element with the text `Schedule by Track and Time`.
# --hints--
You should have a `table` element.
```js
assert.exists(document.querySelector("table"));
```
Your `table` element should have a `caption` element.
```js
assert.exists(document.querySelector("table caption"));
```
Your `caption` element should have the text `Schedule by Track and Time`.
```js
assert.equal(document.querySelector("table caption")?.textContent.trim(), "Schedule by Track and Time");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
--fcc-editable-region--
--fcc-editable-region--
</body>
</html>
```
@@ -0,0 +1,51 @@
---
id: 68c3420cb0176439a95af1b8
title: Step 3
challengeType: 0
dashedName: step-3
---
# --description--
The next step is to add the table head.
Start by adding a `thead` element below the `caption` element. Inside the `thead`, add a `tr` element.
# --hints--
You should have a `thead` element.
```js
assert.exists(document.querySelector("table thead"));
```
You should have a `tr` element inside the `thead`.
```js
assert.exists(document.querySelector("table thead tr"));
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
--fcc-editable-region--
--fcc-editable-region--
</table>
</body>
</html>
```
@@ -0,0 +1,71 @@
---
id: 68c34329d430583a6cd5f7f1
title: Step 4
challengeType: 0
dashedName: step-4
---
# --description--
Inside of your `tr` element, add four `th` elements. The first `th` element should have the text of `Time`, the second should have the text of `Track A`, the third should have the text of `Track B`, and the fourth should have the text of `Track C`.
# --hints--
Your `tr` element should have four `th` elements.
```js
assert.lengthOf(document.querySelectorAll("tr > th"), 4);
```
Your first `th` element should have the text of `Time`.
```js
assert.strictEqual(document.querySelector("tr > th:nth-of-type(1)")?.textContent.trim(), "Time");
```
Your second `th` element should have the text of `Track A`.
```js
assert.strictEqual(document.querySelector("tr > th:nth-of-type(2)")?.textContent.trim(), "Track A");
```
Your third `th` element should have the text of `Track B`.
```js
assert.strictEqual(document.querySelector("tr > th:nth-of-type(3)")?.textContent.trim(), "Track B");
```
Your fourth `th` element should have the text of `Track C`.
```js
assert.strictEqual(document.querySelector("tr > th:nth-of-type(4)")?.textContent.trim(), "Track C");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
--fcc-editable-region--
<thead>
<tr>
</tr>
</thead>
--fcc-editable-region--
</table>
</body>
</html>
```
@@ -0,0 +1,61 @@
---
id: 68c343692285523aef0fc6bf
title: Step 5
challengeType: 0
dashedName: step-5
---
# --description--
The `scope` attribute is used to specify whether a header cell is a header for a row, column, or group of rows or columns. Here is an example:
```html
<th scope="col">Example Header</th>
```
This helps screen readers understand the relationship between header and data cells.
For all `th` elements, add a `scope` attribute with a value of `col`.
# --hints--
Each `th` element should have a `scope` attribute with the value `"col"`.
```js
const tableHeaders = document.querySelectorAll("th");
tableHeaders.forEach(header => {
assert.equal(header?.getAttribute("scope"), "col");
});
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
--fcc-editable-region--
<th>Time</th>
<th>Track A</th>
<th>Track B</th>
<th>Track C</th>
--fcc-editable-region--
</tr>
</thead>
</table>
</body>
</html>
```
@@ -0,0 +1,60 @@
---
id: 68c346d03709343bff132707
title: Step 6
challengeType: 0
dashedName: step-6
---
# --description--
For the next few steps, you will build out the body of the table.
Start by adding a `tbody` element below the `thead` element. Then inside the `tbody`, add a `tr` element.
# --hints--
You should have a `tbody` element below the `thead` element.
```js
assert.exists(document.querySelector("tbody"));
```
You should have a `tr` element inside the `tbody` element.
```js
assert.exists(document.querySelector("tbody tr"));
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
--fcc-editable-region--
--fcc-editable-region--
</table>
</body>
</html>
```
@@ -0,0 +1,91 @@
---
id: 68c3482278a14e3cf225e897
title: Step 7
challengeType: 0
dashedName: step-7
---
# --description--
Inside your `tr` element, add a `th` element with the text of `9:00 AM`. Then below that `th` element, add three `td` elements with the text of `Keynote: Tech Future`, `Intro to Web Dev`, and `UX for All`.
# --hints--
You should have a `th` element inside of your `tr` element.
```js
assert.exists(document.querySelector("tbody tr th"));
```
Your `th` element should have the text content of `9:00 AM`.
```js
assert.equal(document.querySelector("tbody tr th")?.textContent.trim(), "9:00 AM");
```
You should have a total of three `td` elements below your `th` element.
```js
const tdElements = document.querySelectorAll("tbody tr td");
assert.lengthOf(tdElements, 3);
```
Your first `td` element should have the text content of `Keynote: Tech Future`.
```js
const tdElements = document.querySelectorAll("tbody tr td");
assert.equal(tdElements[0]?.textContent.trim(), "Keynote: Tech Future");
```
Your second `td` element should have the text content of `Intro to Web Dev`.
```js
const tdElements = document.querySelectorAll("tbody tr td");
assert.equal(tdElements[1]?.textContent.trim(), "Intro to Web Dev");
```
Your third `td` element should have the text content of `UX for All`.
```js
const tdElements = document.querySelectorAll("tbody tr td");
assert.equal(tdElements[2]?.textContent.trim(), "UX for All");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
<tbody>
<tr>
--fcc-editable-region--
--fcc-editable-region--
</tr>
</tbody>
</table>
</body>
</html>
```
@@ -0,0 +1,62 @@
---
id: 68c34a35c91b053dbae2a8c6
title: Step 8
challengeType: 0
dashedName: step-8
---
# --description--
Another value for the `scope` attribute is `row`, which indicates that a header cell is a header for its entire row.
Inside of your `th` element, add a `scope` attribute with a value of `row`.
# --hints--
Your `th` element should have a `scope` attribute with a value of `row`.
```js
assert.equal(document.querySelector("tbody tr th")?.getAttribute("scope"), "row");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
<tbody>
<tr>
--fcc-editable-region--
<th>9:00 AM</th>
--fcc-editable-region--
<td>Keynote: Tech Future</td>
<td>Intro to Web Dev</td>
<td>UX for All</td>
</tr>
</tbody>
</table>
</body>
</html>
```
@@ -0,0 +1,112 @@
---
id: 68c34ace730ca43e5fa7b8d6
title: Step 9
challengeType: 0
dashedName: step-9
---
# --description--
Now it is time to add another row to the table.
Start by adding another `tr` element. Inside that `tr` element, add a `th` element with a `scope` attribute set to `"row"` and the text content of `10:00 AM`.
Then, add three `td` elements with the following text content:
- `Accessibility Deep Dive`
- `CSS for Beginners`
- `Inclusive Design Principles`
# --hints--
You should have a second `tr` element inside of the `tbody` element.
```js
assert.lengthOf(document.querySelectorAll("tbody tr"), 2);
```
You should have a `th` element inside of the second `tr` element.
```js
assert.isNotNull(document.querySelectorAll("tbody tr")[1].querySelector("th"));
```
Your `th` element should have the text content of `10:00 AM`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[1].querySelector("th")?.textContent.trim(), "10:00 AM");
```
Your `th` element should have a `scope` attribute set to `"row"`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[1].querySelector("th")?.getAttribute("scope"), "row");
```
Your second `tr` element should have three `td` elements.
```js
assert.lengthOf(document.querySelectorAll("tbody tr")[1].querySelectorAll("td"), 3);
```
Your first `td` element should have the text content of `Accessibility Deep Dive`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[1].querySelectorAll("td")[0]?.textContent.trim(), "Accessibility Deep Dive");
```
Your second `td` element should have the text content of `CSS for Beginners`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[1].querySelectorAll("td")[1]?.textContent.trim(), "CSS for Beginners");
```
Your third `td` element should have the text content of `Inclusive Design Principles`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[1].querySelectorAll("td")[2]?.textContent.trim(), "Inclusive Design Principles");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">9:00 AM</th>
<td>Keynote: Tech Future</td>
<td>Intro to Web Dev</td>
<td>UX for All</td>
</tr>
--fcc-editable-region--
--fcc-editable-region--
</tbody>
</table>
</body>
</html>
```
@@ -0,0 +1,99 @@
---
id: 68c34c608cf9e53f5d36b1d5
title: Step 10
challengeType: 0
dashedName: step-10
---
# --description--
Next, add a third row to the table. Start by adding another `tr` element. Inside that `tr` element, add a `th` element with a `scope` attribute set to `"row"` and the text content of `11:00 AM`. Then below that `th` element, add a `td` element with the text content of `Break`.
# --hints--
You should have a third `tr` element inside of the `tbody` element.
```js
assert.lengthOf(document.querySelectorAll("tbody tr"), 3);
```
You should have a `th` element inside of the third `tr` element.
```js
assert.isNotNull(document.querySelectorAll("tbody tr")[2].querySelector("th"));
```
Your `th` element should have the text content of `11:00 AM`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[2].querySelector("th")?.textContent.trim(), "11:00 AM");
```
Your `th` element should have a `scope` attribute set to `"row"`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[2].querySelector("th")?.getAttribute("scope"), "row");
```
You should have a `td` element inside of the third `tr` element.
```js
assert.isNotNull(document.querySelectorAll("tbody tr")[2].querySelector("td"));
```
Your `td` element should have the text content of `Break`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[2].querySelector("td")?.textContent.trim(), "Break");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">9:00 AM</th>
<td>Keynote: Tech Future</td>
<td>Intro to Web Dev</td>
<td>UX for All</td>
</tr>
<tr>
<th scope="row">10:00 AM</th>
<td>Accessibility Deep Dive</td>
<td>CSS for Beginners</td>
<td>Inclusive Design Principles</td>
</tr>
--fcc-editable-region--
--fcc-editable-region--
</tbody>
</table>
</body>
</html>
```
@@ -0,0 +1,82 @@
---
id: 68c34d57ed874e4004f7b5d4
title: Step 11
challengeType: 0
dashedName: step-11
---
# --description--
Right now, the `td` element with the text content of `Break` only spans one column. But it would be nice if it spanned all three columns.
As you recall from earlier workshops and lessons, you can use the `colspan` attribute to make a table cell span multiple columns.
```html
<tr>
<td colspan="3">Total Points</td>
</tr>
```
Add a `colspan` attribute to the `td` element and set its value to `3`.
# --hints--
Your `td` element with the text content of `Break` should have a `colspan` attribute set to `3`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[2].querySelector("td")?.getAttribute("colspan"), "3");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">9:00 AM</th>
<td>Keynote: Tech Future</td>
<td>Intro to Web Dev</td>
<td>UX for All</td>
</tr>
<tr>
<th scope="row">10:00 AM</th>
<td>Accessibility Deep Dive</td>
<td>CSS for Beginners</td>
<td>Inclusive Design Principles</td>
</tr>
<tr>
<th scope="row">11:00 AM</th>
--fcc-editable-region--
<td>Break</td>
--fcc-editable-region--
</tr>
</tbody>
</table>
</body>
</html>
```
@@ -0,0 +1,124 @@
---
id: 68c34e201b347c40acda8111
title: Step 12
challengeType: 0
dashedName: step-12
---
# --description--
Now it is time to add another row to the table.
Start by adding another `tr` element. Inside that `tr` element, add a `th` element with a `scope` attribute set to `"row"` and the text content of `11:30 AM`.
Then, add three `td` elements with the following text content:
- `AR/VR in Education`
- `JavaScript Fundamentals`
- `Design Systems at Scale`
# --hints--
You should have a fourth `tr` element inside of the `tbody` element.
```js
assert.lengthOf(document.querySelectorAll("tbody tr"), 4);
```
You should have a `th` element inside of the fourth `tr` element.
```js
assert.isNotNull(document.querySelectorAll("tbody tr")[3].querySelector("th"));
```
Your `th` element should have the text content of `11:30 AM`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[3].querySelector("th")?.textContent.trim(), "11:30 AM");
```
Your `th` element should have a `scope` attribute set to `"row"`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[3].querySelector("th")?.getAttribute("scope"), "row");
```
Your fourth `tr` element should have three `td` elements.
```js
assert.lengthOf(document.querySelectorAll("tbody tr")[3].querySelectorAll("td"), 3);
```
Your first `td` element should have the text content of `AR/VR in Education`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[3].querySelectorAll("td")[0]?.textContent.trim(), "AR/VR in Education");
```
Your second `td` element should have the text content of `JavaScript Fundamentals`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[3].querySelectorAll("td")[1]?.textContent.trim(), "JavaScript Fundamentals");
```
Your third `td` element should have the text content of `Design Systems at Scale`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[3].querySelectorAll("td")[2]?.textContent.trim(), "Design Systems at Scale");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">9:00 AM</th>
<td>Keynote: Tech Future</td>
<td>Intro to Web Dev</td>
<td>UX for All</td>
</tr>
<tr>
<th scope="row">10:00 AM</th>
<td>Accessibility Deep Dive</td>
<td>CSS for Beginners</td>
<td>Inclusive Design Principles</td>
</tr>
<tr>
<th scope="row">11:00 AM</th>
<td colspan="3">Break</td>
</tr>
--fcc-editable-region--
--fcc-editable-region--
</tbody>
</table>
</body>
</html>
```
@@ -0,0 +1,116 @@
---
id: 68c34f4aeb2b1a4170506751
title: Step 13
challengeType: 0
dashedName: step-13
---
# --description--
Next, add a fifth row to the table. Start by adding another `tr` element. Inside that `tr` element, add a `th` element with a `scope` attribute set to `"row"` and the text content of `12:30 PM`. Then below that `th` element, add a `td` element with the text content of `Lunch Break`. Your `td` element should also have a `colspan` attribute set to `3` so that it spans all three tracks.
# --hints--
You should have a fifth `tr` element inside of the `tbody` element.
```js
assert.lengthOf(document.querySelectorAll("tbody tr"), 5);
```
You should have a `th` element inside of the fifth `tr` element.
```js
assert.isNotNull(document.querySelectorAll("tbody tr")[4].querySelector("th"));
```
Your `th` element should have the text content of `12:30 PM`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[4].querySelector("th")?.textContent.trim(), "12:30 PM");
```
Your `th` element should have a `scope` attribute set to `"row"`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[4].querySelector("th")?.getAttribute("scope"), "row");
```
You should have a `td` element inside of the fifth `tr` element.
```js
assert.isNotNull(document.querySelectorAll("tbody tr")[4].querySelector("td"));
```
Your `td` element should have the text content of `Lunch Break`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[4].querySelector("td")?.textContent.trim(), "Lunch Break");
```
Your `td` element should have a `colspan` attribute set to `3`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[4].querySelector("td")?.getAttribute("colspan"), "3");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">9:00 AM</th>
<td>Keynote: Tech Future</td>
<td>Intro to Web Dev</td>
<td>UX for All</td>
</tr>
<tr>
<th scope="row">10:00 AM</th>
<td>Accessibility Deep Dive</td>
<td>CSS for Beginners</td>
<td>Inclusive Design Principles</td>
</tr>
<tr>
<th scope="row">11:00 AM</th>
<td colspan="3">Break</td>
</tr>
<tr>
<th scope="row">11:30 AM</th>
<td>AR/VR in Education</td>
<td>JavaScript Fundamentals</td>
<td>Design Systems at Scale</td>
</tr>
--fcc-editable-region--
--fcc-editable-region--
</tbody>
</table>
</body>
</html>
```
@@ -0,0 +1,206 @@
---
id: 68c353c4b114aa428c01f260
title: Step 14
challengeType: 0
dashedName: step-14
---
# --description--
The last step is to add one more row to the table.
Start by adding another `tr` element. Inside that `tr` element, add a `th` element with a `scope` attribute set to `"row"` and the text content of `2:00 PM`.
Then, add three `td` elements with the following text content:
- `Voice UI Workshop`
- `Git & GitHub Essentials`
- `Color & Contrast in UI`
With those last set of changes, your table is now complete!
# --hints--
You should have a sixth `tr` element inside of the `tbody` element.
```js
assert.lengthOf(document.querySelectorAll("tbody tr"), 6);
```
You should have a `th` element inside of the sixth `tr` element.
```js
assert.isNotNull(document.querySelectorAll("tbody tr")[5].querySelector("th"));
```
Your `th` element should have the text content of `2:00 PM`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[5].querySelector("th")?.textContent.trim(), "2:00 PM");
```
Your `th` element should have a `scope` attribute set to `"row"`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[5].querySelector("th")?.getAttribute("scope"), "row");
```
Your sixth `tr` element should have three `td` elements.
```js
assert.lengthOf(document.querySelectorAll("tbody tr")[5].querySelectorAll("td"), 3);
```
Your first `td` element should have the text content of `Voice UI Workshop`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[5].querySelectorAll("td")[0]?.textContent.trim(), "Voice UI Workshop");
```
Your second `td` element should have the text content of `Git & GitHub Essentials`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[5].querySelectorAll("td")[1]?.textContent.trim(), "Git & GitHub Essentials");
```
Your third `td` element should have the text content of `Color & Contrast in UI`.
```js
assert.strictEqual(document.querySelectorAll("tbody tr")[5].querySelectorAll("td")[2]?.textContent.trim(), "Color & Contrast in UI");
```
# --seed--
## --seed-contents--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">9:00 AM</th>
<td>Keynote: Tech Future</td>
<td>Intro to Web Dev</td>
<td>UX for All</td>
</tr>
<tr>
<th scope="row">10:00 AM</th>
<td>Accessibility Deep Dive</td>
<td>CSS for Beginners</td>
<td>Inclusive Design Principles</td>
</tr>
<tr>
<th scope="row">11:00 AM</th>
<td colspan="3">Break</td>
</tr>
<tr>
<th scope="row">11:30 AM</th>
<td>AR/VR in Education</td>
<td>JavaScript Fundamentals</td>
<td>Design Systems at Scale</td>
</tr>
<tr>
<th scope="row">12:30 PM</th>
<td colspan="3">Lunch Break</td>
</tr>
--fcc-editable-region--
--fcc-editable-region--
</tbody>
</table>
</body>
</html>
```
# --solutions--
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Tech Conference 2025 Schedule</title>
</head>
<body>
<h1>Tech Conference 2025 Schedule</h1>
<table>
<caption>Schedule by Track and Time</caption>
<thead>
<tr>
<th scope="col">Time</th>
<th scope="col">Track A</th>
<th scope="col">Track B</th>
<th scope="col">Track C</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">9:00 AM</th>
<td>Keynote: Tech Future</td>
<td>Intro to Web Dev</td>
<td>UX for All</td>
</tr>
<tr>
<th scope="row">10:00 AM</th>
<td>Accessibility Deep Dive</td>
<td>CSS for Beginners</td>
<td>Inclusive Design Principles</td>
</tr>
<tr>
<th scope="row">11:00 AM</th>
<td colspan="3">Break</td>
</tr>
<tr>
<th scope="row">11:30 AM</th>
<td>AR/VR in Education</td>
<td>JavaScript Fundamentals</td>
<td>Design Systems at Scale</td>
</tr>
<tr>
<th scope="row">12:30 PM</th>
<td colspan="3">Lunch Break</td>
</tr>
<tr>
<th scope="row">2:00 PM</th>
<td>Voice UI Workshop</td>
<td>Git & GitHub Essentials</td>
<td>Color & Contrast in UI</td>
</tr>
</tbody>
</table>
</body>
</html>
```
@@ -0,0 +1,26 @@
{
"name": "Build a Tech Conference Schedule Table",
"isUpcomingChange": false,
"dashedName": "workshop-tech-conference-schedule",
"helpCategory": "HTML-CSS",
"blockType": "workshop",
"blockLayout": "challenge-grid",
"challengeOrder": [
{ "id": "68c33e502cd97f2fd52cb63b", "title": "Step 1" },
{ "id": "68c341332d98fe38fae733af", "title": "Step 2" },
{ "id": "68c3420cb0176439a95af1b8", "title": "Step 3" },
{ "id": "68c34329d430583a6cd5f7f1", "title": "Step 4" },
{ "id": "68c343692285523aef0fc6bf", "title": "Step 5" },
{ "id": "68c346d03709343bff132707", "title": "Step 6" },
{ "id": "68c3482278a14e3cf225e897", "title": "Step 7" },
{ "id": "68c34a35c91b053dbae2a8c6", "title": "Step 8" },
{ "id": "68c34ace730ca43e5fa7b8d6", "title": "Step 9" },
{ "id": "68c34c608cf9e53f5d36b1d5", "title": "Step 10" },
{ "id": "68c34d57ed874e4004f7b5d4", "title": "Step 11" },
{ "id": "68c34e201b347c40acda8111", "title": "Step 12" },
{ "id": "68c34f4aeb2b1a4170506751", "title": "Step 13" },
{ "id": "68c353c4b114aa428c01f260", "title": "Step 14" }
],
"usesMultifileEditor": true,
"hasEditableBoundaries": true
}
@@ -61,6 +61,7 @@
"lecture-importance-of-accessibility-and-good-html-structure",
"workshop-debug-coding-journey-blog-page",
"lecture-accessible-tables-forms",
"workshop-tech-conference-schedule",
"lecture-introduction-to-aria",
"lecture-accessible-media-elements",
"lab-checkout-page",