Чи можемо ми мати кілька <tbody> в одному <table>?


594

Чи можемо ми мати кілька <tbody>тегів одночасно <table>? Якщо так, то в яких сценаріях ми повинні використовувати кілька <tbody>тегів?

Відповіді:


710

Так, ви можете використовувати їх, наприклад, я використовую їх для більш легкого стилю груп даних, наприклад, такий:

thead th { width: 100px; border-bottom: solid 1px #ddd; font-weight: bold; }
tbody:nth-child(odd) { background: #f5f5f5;  border: solid 1px #ddd; }
tbody:nth-child(even) { background: #e5e5e5;  border: solid 1px #ddd; }
<table>
    <thead>
        <tr><th>Customer</th><th>Order</th><th>Month</th></tr>
    </thead>
    <tbody>
        <tr><td>Customer 1</td><td>#1</td><td>January</td></tr>
        <tr><td>Customer 1</td><td>#2</td><td>April</td></tr>
        <tr><td>Customer 1</td><td>#3</td><td>March</td></tr>
    </tbody>
    <tbody>
        <tr><td>Customer 2</td><td>#1</td><td>January</td></tr>
        <tr><td>Customer 2</td><td>#2</td><td>April</td></tr>
        <tr><td>Customer 2</td><td>#3</td><td>March</td></tr>
    </tbody>
    <tbody>
        <tr><td>Customer 3</td><td>#1</td><td>January</td></tr>
        <tr><td>Customer 3</td><td>#2</td><td>April</td></tr>
        <tr><td>Customer 3</td><td>#3</td><td>March</td></tr>
    </tbody>
</table>

Ви можете переглянути приклад тут . Він працюватиме лише в новіших браузерах, але це те, що я підтримую в моєму теперішньому додатку, ви можете використовувати групування для JavaScript і т.д. Головне - це зручний спосіб візуально згрупувати рядки, щоб зробити дані набагато читабельнішими . Звичайно, є й інші способи використання, але, що стосується прикладних прикладів, це для мене є найбільш поширеним.


6
добре дякую за чудову відповідь. Чи має значення для читання екрана, один tbodyчи кілька?
Джітендра Вяс

1
@ metal-gear-solid - На мій досвід, вони справляються з ними чудово, наприклад: як би вони були одна <tbody>. Коли ви починаєте вкладати таблиці, саме це зазвичай створює реальні проблеми з навігацією для екранного зчитувача.
Нік Крейвер

10
@metal: ні, є семантична різниця - кілька <tbody>елементів описують окремі групи в таблиці, як було пояснено у відповіді. Також слід додати, що зазвичай краще орієнтувати клітинки на фони, тому CSS повинен бути, наприклад,tbody:nth-child(odd) td { background: #f5f5f5; }
DisgruntledGoat

4
Що таке визначення "новіших браузерів"?
Тім Даун

8
@TimDown - коли я сказав "новіші браузери", це стосується лише :nth-child()використання CSS для пов'язаної демонстрації, множина <tbody>працюватиме в будь-якому браузері.
Нік Крейвер

298

Так. З ДТД

<!ELEMENT table
     (caption?, (col*|colgroup*), thead?, tfoot?, (tbody+|tr+))>

Тож він очікує одного або декількох. Потім це продовжує говорити

Використовуйте кілька розділів tbody, коли потрібні правила між групами рядків таблиць.


12
Що стосується специфікації HTML5, це незначно змінюється, але основне "так, кілька tbodyелементів добре) залишається. Зокрема, тепер вам дозволяється вводити один tfootелемент після того, tbodyяк вам подобається ." Вони акуратно перейшли на бік аспекту DTD. сказавши, що вони не надають його .) :-)
TJ Crowder

5
Дякуємо за цю відповідь. Технічні рекомендації - це відповідь №1 у моїй книзі
KernelCurry

1
Тож він очікує одного або декількох. Це неправильно, це може бути набір, <tr>так що він також може бути нульовим (тобто tbody або tr означає, що це може бути просто tr, а не tbody.)
Alexis Wilke,

@AlexisWilke це правда відповідно до специфікацій: пусковий тег TBODY завжди потрібний, за винятком випадків, коли в таблиці є лише одне тіло таблиці та не мають розділів голови або стопи
Gecko IT


14

Проблема Мартіна Столяра викликана нерозумінням <caption>тегу.

<caption>Тег визначає заголовок таблиці.

<caption>Тег повинен бути першим нащадком <table>тега.

Ви можете вказати лише один підпис на таблицю.

Також зауважте, що scopeатрибут повинен бути розміщений на <th>елементі, а не на <tr>елементі.

Правильний спосіб написання багатозаголовкової таблиці з декількома телами був би приблизно таким:

<table id="dinner_table">
    <caption>This is the only correct place to put a caption.</caption>
    <tbody>
        <tr class="header">
            <th colspan="2" scope="col">First Half of Table (British Dinner)</th>
        </tr>
        <tr>
            <th scope="row">1</th>
            <td>Fish</td>
        </tr>
        <tr>
            <th scope="row">2</th>
            <td>Chips</td>
        </tr>
        <tr>
            <th scope="row">3</th>
            <td>Peas</td>
        </tr>
        <tr>
            <th scope="row">4</th>
            <td>Gravy</td>
        </tr>
    </tbody>
    <tbody>
        <tr class="header">
            <th colspan="2" scope="col">Second Half of Table (Italian Dinner)</th>
        </tr>
        <tr>
            <th scope="row">5</th>
            <td>Pizza</td>
        </tr>
        <tr>
            <th scope="row">6</th>
            <td>Salad</td>
        </tr>
        <tr>
            <th scope="row">7</th>
            <td>Oil</td>
        </tr>
        <tr>
            <th scope="row">8</th>
            <td>Bread</td>
        </tr>
    </tbody>
</table>


captionТег повинен слідувати відкриває tableтег. developer.mozilla.org/en-US/docs/Web/HTML/Element/table
Cypher

Ти правий. Я якось неправильно трактував документи. Я виправив помилку.
Джон Slegers

Spec рекомендує використовувати scope="rowgroup"(замість col) для tbodyзаголовків. Див. Приклад .
CletusW

7

Так. Я використовую їх для динамічного приховування / виявлення відповідної частини таблиці, наприклад, курсу. Віз.

<table>
  <tbody id="day1" style="display:none">
    <tr><td>session1</td><tr>
    <tr><td>session2</td><tr>
  </tbody>
  <tbody id="day2">
    <tr><td>session3</td><tr>
    <tr><td>session4</td><tr>
  </tbody>
  <tbody id="day3" style="display:none">
    <tr><td>session5</td><tr>
    <tr><td>session6</td><tr>
  </tbody>
</table>

Для переключення між усім або просто поточним днем ​​можна використовувати кнопку, маніпулюючи фрагментами, не обробляючи багато рядків окремо.


4

EDIT: captionТег належить до таблиці, і тому він повинен існувати лише один раз. Не пов'язуйте а captionз кожним tbodyелементом, як я:

<table>
    <caption>First Half of Table (British Dinner)</caption>
    <tbody>
        <tr><th>1</th><td>Fish</td></tr>
        <tr><th>2</th><td>Chips</td></tr>
        <tr><th>3</th><td>Pease</td></tr>
        <tr><th>4</th><td>Gravy</td></tr>
    </tbody>
    <caption>Second Half of Table (Italian Dinner)</caption>
    <tbody>
        <tr><th>5</th><td>Pizza</td></tr>
        <tr><th>6</th><td>Salad</td></tr>
        <tr><th>7</th><td>Oil</td></tr>
        <tr><th>8</th><td>Bread</td></tr>
    </tbody>
</table>

НАПРИКЛАДНИЙ ПРИКЛАД ПРО НАС: НЕ КОПУЙТЕ

Наведений вище приклад не відображається так, як ви очікували, оскільки написання подібним чином вказує на нерозуміння captionтегу. Вам знадобиться безліч хаксів CSS, щоб зробити це візуалізацією правильно, оскільки ви будете суперечити стандартам.

Я шукав стандарти W3Cs у captionтезі, але не міг знайти явного правила, згідно з яким captionу таблиці має бути лише один елемент, але це насправді так.


3

Крім того, якщо ви запускаєте документ HTML із декількома <tbody>тегами через HTML Validator W3C , з DOCTYPE HTML5, він буде успішно перевірений.


2

Я створив JSFiddle, де у мене є два вкладені ng-повторення з таблицями та батьківський ng-повтор на tbody. Якщо ви оглянете будь-який рядок у таблиці, ви побачите, що є шість елементів tbody, тобто батьківський рівень.

HTML

<div>
        <table class="table table-hover table-condensed table-striped">
            <thead>
                <tr>
                    <th>Store ID</th>
                    <th>Name</th>
                    <th>Address</th>
                    <th>City</th>
                    <th>Cost</th>
                    <th>Sales</th>
                    <th>Revenue</th>
                    <th>Employees</th>
                    <th>Employees H-sum</th>
                </tr>
            </thead>
            <tbody data-ng-repeat="storedata in storeDataModel.storedata">
                <tr id="storedata.store.storeId" class="clickableRow" title="Click to toggle collapse/expand day summaries for this store." data-ng-click="selectTableRow($index, storedata.store.storeId)">
                    <td>{{storedata.store.storeId}}</td>
                    <td>{{storedata.store.storeName}}</td>
                    <td>{{storedata.store.storeAddress}}</td>
                    <td>{{storedata.store.storeCity}}</td>
                    <td>{{storedata.data.costTotal}}</td>
                    <td>{{storedata.data.salesTotal}}</td>
                    <td>{{storedata.data.revenueTotal}}</td>
                    <td>{{storedata.data.averageEmployees}}</td>
                    <td>{{storedata.data.averageEmployeesHours}}</td>
                </tr>
                <tr data-ng-show="dayDataCollapse[$index]">
                    <td colspan="2">&nbsp;</td>
                    <td colspan="7">
                        <div>
                            <div class="pull-right">
                                <table class="table table-hover table-condensed table-striped">
                                    <thead>
                                        <tr>
                                            <th></th>
                                            <th>Date [YYYY-MM-dd]</th>
                                            <th>Cost</th>
                                            <th>Sales</th>
                                            <th>Revenue</th>
                                            <th>Employees</th>
                                            <th>Employees H-sum</th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr data-ng-repeat="dayData in storeDataModel.storedata[$index].data.dayData">
                                            <td class="pullright">
                                                <button type="btn btn-small" title="Click to show transactions for this specific day..." data-ng-click=""><i class="icon-list"></i>
                                                </button>
                                            </td>
                                            <td>{{dayData.date}}</td>
                                            <td>{{dayData.cost}}</td>
                                            <td>{{dayData.sales}}</td>
                                            <td>{{dayData.revenue}}</td>
                                            <td>{{dayData.employees}}</td>
                                            <td>{{dayData.employeesHoursSum}}</td>
                                        </tr>
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>

(Побічна примітка: Це заповнює DOM, якщо у вас є багато даних на обох рівнях, тому я працюю над директивою щодо отримання даних та заміни, тобто додавання в DOM при натисканні на батьків і видалення, коли натискається інший або той самий батьківський Ще раз. Щоб отримати таку поведінку, яку ви знайдете на Prisjakt.nu , якщо прокрутити вниз до перерахованих комп’ютерів і натиснути рядок (а не посилання). Якщо ви це зробите і оглянете елементи, ви побачите, що додається tr і потім видаляється, якщо батько натискається знову чи інше.)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.