Таблица в HTML - это не про визуальные столбики, а про данные, у которых есть строки и столбцы: расписание, цены, сравнение характеристик. За это отвечают три тега внутри <table> - <tr> для строки, <td> для обычной ячейки и <th> для ячейки-заголовка.
Попробуй добавить ещё одну строку через <tr><td>...</td><td>...</td></tr> - таблица справа сама вырастет на строку.
Тег table - только для данных
Тег <table> предназначен для содержимого, у которого есть смысловая связь между строками и столбцами - расписание уроков, сравнение цен, список характеристик. Он не предназначен для того, чтобы просто разложить блоки по странице визуально в несколько колонок - для этого в CSS есть свои инструменты (например, flexbox и grid).
<table><tr><th>День</th><th>Урок</th></tr><tr><td>Пн</td><td>HTML</td></tr></table> - настоящие табличные данные: день и урок связаны по строке.
<table><tr><td>Меню сайта</td><td>Основной текст</td><td>Реклама</td></tr></table> - таблица используется, чтобы просто расставить блоки по странице, а не показать связанные данные.
Строки tr и ячейки td
Внутри <table> каждая строка - это <tr>, а внутри строки обычная ячейка с данными - <td>. Количество ячеек стоит держать одинаковым в каждой строке: браузер не выдаст ошибку, если в одной строке ячеек больше или меньше, чем в других, но таблица визуально «съедет» и перестанет быть правильной табличной структурой.
<tr><td>Пн</td><td>HTML</td></tr><tr><td>Вт</td><td>CSS</td></tr> - в каждой строке по две ячейки, столбцы совпадают.
<tr><td>Пн</td><td>HTML</td></tr><tr><td>Вт</td></tr> - во второй строке не хватает ячейки, столбцы больше не совпадают между строками.
Заголовочные ячейки th и scope
Тег <th> - это ячейка-заголовок: браузер сам делает её жирной и по центру, но дело не только во внешнем виде. Атрибут scope явно указывает, к чему относится заголовок - scope="col" к целому столбцу, scope="row" к целой строке. Это не всегда меняет что-то визуально, зато помогает программам чтения с экрана правильно озвучивать, к какому заголовку относится каждая ячейка с данными.
<tr><th scope="col">День</th><th scope="col">Урок</th></tr> - явно указано, что оба заголовка относятся к своим столбцам.
<tr><td>День</td><td>Урок</td></tr> - обычные td вместо th: выглядит как заголовок только за счёт текста, а для программ чтения с экрана это обычные данные, не заголовок.
Частые ошибки новичков
| Ошибка | Что происходит | Как исправить |
|---|---|---|
| Использовать table для раскладки блоков страницы вместо данных | Ломается доступность и семантика - программы чтения с экрана видят несуществующие «данные» | Верстать макет через CSS (flexbox, grid), а table оставлять для настоящих табличных данных |
| Делать разное количество ячеек в разных строках | Браузер не покажет ошибку, но столбцы визуально перестанут совпадать между строками | Следить, чтобы в каждой строке было одинаковое количество ячеек |
| Оформлять заголовок таблицы через td с жирным текстом вместо th | Выглядит как заголовок только визуально - для программ чтения с экрана это обычная ячейка данных | Использовать th для заголовочных ячеек, а не имитировать вид жирным текстом в td |
| Не задумываться про scope у th в таблице с заголовками и по строкам, и по столбцам | Программе чтения с экрана сложнее понять, к чему именно относится заголовок | Указывать scope="col" или scope="row" явно, особенно в таблицах сложнее одной строки заголовков |
Шпаргалка
| Термин | Значение |
|---|---|
| table | Обёртка для табличных данных - не для макета страницы |
| tr | Одна строка таблицы |
| td | Обычная ячейка с данными |
| th | Заголовочная ячейка - жирная по умолчанию и с семантическим значением |
| scope | У th указывает, к столбцу (col) или строке (row) относится заголовок |
Коротко: отвечаем на вопросы
Можно ли сегодня использовать таблицу для вёрстки страницы вместо CSS?
Не стоит. В 1990-х это было массовой практикой из-за слабого CSS, но ломало доступность - программы чтения с экрана пытались прочитать макет как таблицу с данными. Сегодня для раскладки блоков по странице есть CSS (flexbox, grid), а table стоит использовать только для настоящих табличных данных.
Чем th отличается от td, если можно просто сделать td жирным через CSS?
Дело не только во внешнем виде. th несёт смысл заголовка, а атрибут scope явно связывает его со столбцом или строкой - это помогает программам чтения с экрана правильно озвучивать, к какому заголовку относится каждая ячейка. td, даже визуально оформленный жирным, для таких программ остаётся обычной ячейкой данных.
Что будет, если в разных строках таблицы разное количество ячеек?
Браузер не выдаст ошибку - HTML к этому терпим. Но таблица визуально «съедет»: столбцы перестанут совпадать между строками, и структура перестанет быть корректной табличной разметкой. Правильная таблица держит одинаковое количество ячеек в каждой строке.