---
title: Table
desc: Element that displays tabular data in a structured format of rows and columns.
ico: mdi:table
keywords:
  - column
  - data
  - row

props:
  - class: .prs-table-container
    type: component
    desc: Container
  - class: .prs-table
    type: component
    desc: For <table>
  - class: .prs-table-fixed
    type: modifier
    desc: Equal column widths
  - class: .prs-table-bordered
    type: modifier
    desc: Add divider lines
  - class: .prs-table-striped
    type: modifier
    desc: Even/odd highlight
  - class: .prs-table-compact
    type: modifier
    desc: Less padding
  - class: .prs-table-pin-rows
    type: modifier
    desc: Sticky <thead> and <tfoot>
  - class: .prs-table-pin-cols
    type: modifier
    desc: Sticky <th> columns
  - class: .prs-cell-name
    type: part
    desc: Name/email
  - class: .prs-cell-stacked
    type: part
    desc: Stacked content
  - class: .prs-cell-end
    type: part
    desc: Justify end/right
  - class: .prs-cell-actions
    type: part
    desc: Header cell actions container
  - class: .prs-cell-info
    type: part
    desc: Info tooltip container
  - class: .prs-cell-sort
    type: part
    desc: Sorting container

controls:
  - name: bordered
    type: toggle
    label: Bordered
    desc: Border between rows.
    default: true
  - name: fixed
    type: toggle
    label: Fixed
    desc: Equal width columns.
    default: false
  - name: striped
    type: toggle
    label: Striped
    desc: Subtle grey background on every other tbody > tr.
    default: false
  - name: compact
    type: toggle
    label: Compact
    desc: Reduce cell padding.
    default: false
  - name: subLabel
    type: toggle
    label: Show sub header
    desc: Optional header sub-label.
    default: false
  - name: subData
    type: toggle
    label: Show sub data
    desc: Optional cell sub-data.
    default: false
  - name: end
    type: toggle
    label: End alignment
    desc: End-align the last cells in each column.
    default: false
  - name: pinRows
    type: toggle
    label: Pin rows
    desc: Pin header/footer rows so that if the table to needs to scroll the cells stay within view.
    default: false
  - name: pinCols
    type: toggle
    label: Pin columns
    desc: Pin th columns so that if the table to needs to scroll the cells stay within view.
    default: false

previewHeight: 20
preview: |
  <div class="prs-table-container w-screen max-w-lg max-h-[16rem]">
    <table class="prs-table" :class="{
      'prs-table-fixed': fixed,
      'prs-table-bordered': bordered,
      'prs-table-striped': striped,
      'prs-table-compact': compact,
      'prs-table-pin-rows': pinRows,
      'prs-table-pin-cols': pinCols,
    }">
      <thead>
        <tr>
          <th></th>
          <th class="w-fit" :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span :class="((pinCols || pinRows) && !fixed) && 'whitespace-nowrap'">Header</span>
              <strong x-show="subLabel" class="whitespace-nowrap" x-text="'Sub label'"></strong>
            </div>
          </th>
          <th class="w-fit" :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span :class="((pinCols || pinRows) && !fixed) && 'whitespace-nowrap'" x-text="pinRows ? 'Header with longer label' : 'Header'"></span>
              <strong x-show="subLabel" class="whitespace-nowrap" x-text="'Sub label'"></strong>
            </div>
          </th>
          <th class="w-fit" :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span :class="((pinCols || pinRows) && !fixed) && 'whitespace-nowrap'">Header</span>
              <strong x-show="subLabel" class="whitespace-nowrap" x-text="'Sub label'"></strong>
            </div>
          </th>
          <th class="w-fit" :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span :class="((pinCols || pinRows) && !fixed) && 'whitespace-nowrap'">Header</span>
              <strong x-show="subLabel" class="whitespace-nowrap" x-text="'Sub label'"></strong>
            </div>
          </th>
          <th class="w-fit" :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span :class="((pinCols || pinRows) && !fixed) && 'whitespace-nowrap'">Header</span>
              <strong x-show="subLabel" class="whitespace-nowrap" x-text="'Sub label'"></strong>
            </div>
          </th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th class="w-px text-xs font-bold">#.</th>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <th class="w-px text-xs font-bold">#.</th>
        </tr>
        <tr>
          <th class="w-px text-xs font-bold">#.</th>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <th class="w-px text-xs font-bold">#.</th>
        </tr>
        <tr>
          <th class="w-px text-xs font-bold">#.</th>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <th class="w-px text-xs font-bold">#.</th>
        </tr>
        <tr>
          <th class="w-px text-xs font-bold">#.</th>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <th class="w-px text-xs font-bold">#.</th>
        </tr>
        <tr>
          <th class="w-px text-xs font-bold">#.</th>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <td :class="{
            'prs-cell-end': end,
          }">
            <div class="prs-cell-stacked">
              <span>Cell</span>
              <em class="whitespace-nowrap" x-show="subData">Some data</em>
            </div>
          </td>
          <th class="w-px text-xs font-bold">#.</th>
        </tr>
      </tbody>
    </table>
  </div>
  <p class="kbd kbd-sm font-semibold absolute top-1 left-1 pointer-events-none select-none">Scrollable on x/y axis</p>

code:
  html: |
    <table class="prs-table{bordered}{fixed}{striped}{pinRows}{pinCols}{compact}">
      <thead>
        <tr>
          <th></th>
          <th{end}>{header}</th>
          <!-- more cells -->
        </tr>
      </thead>
      <tbody>
        <tr>
          <th><!-- possible sticky/pinned cell --></th>
          <td{end}>{cell}</td>
          <!-- more cells -->
        </tr>
      </tbody>
    </table>
  logic:
    bordered: "this.bordered ? ' prs-table-bordered' : ''"
    fixed: "this.fixed ? ' prs-table-fixed' : ''"
    striped: "this.striped ? ' prs-table-striped' : ''"
    pinRows: "this.pinRows ? ' prs-table-pin-rows' : ''"
    pinCols: "this.pinCols ? ' prs-table-pin-cols' : ''"
    compact: "this.compact ? ' prs-table-compact' : ''"
    end: "this.end ? ' class=\"prs-cell-end\"' : ''"
    header: "this.subLabel ? '\\n        <div class=\"prs-cell-stacked\">\\n          <span>Header</span>\\n          <strong>Sub label</strong>\\n        </div>\\n      ' : 'Header'"
    cell: "this.subData ? '\\n        <div class=\"prs-cell-stacked\">\\n          <span>Cell</span>\\n          <em>Some data</em>\\n        </div>\\n      ' : 'Cell'"
---
