<table class="c-tbl--light" data-component="table" data-param="noinlineborder" id="table">
  <thead>
    <tr><th>Name</th><th>Known As</th><th>Year</th></tr>
  </thead>
  <tbody>
    <tr><td>Bruce Wayne</td><td>Batman</td><td>1939</td></tr>
    <tr><td>Clark Kent</td><td>Superman</td><td>1938</td></tr>
    <tr><td>Tony Stark</td><td>Iron Man</td><td>1963</td></tr>
    <tr><td>Peter Parker</td><td>Spider-Man</td><td>1962</td></tr>
    <tr><td>Matt Murdock</td><td>Daredevil</td><td>1964</td></tr>
  </tbody>
</table>
<p>
  <label>
    Choose a parameter
    <select onchange="table.dataset.param=this.value">
      <option value="hovercell">Hover cell</option>
      <option value="hoverrow">Hover row</option>
      <option value="noinlineborder" selected>No inline border</option>
      <option value="stickycol">Sticky first column</option>
      <option value="zebracol">Zebra columns</option>
      <option value="zebrarow">Zebra row</option>
    </select>
  </label>
  <label>
    Choose a style
    <select onchange="table.className=this.value">
      <option value="">None</option>
      <option value="c-tbl--purple">Purple</option>
      <option value="c-tbl--light" selected>Light</option>
    </select>
  </label>
</p>
/* Demo Styles */
.c-tbl--purple {
  --tbl-bdrs: 0;
  --tbl-hue: 250;
  --tbl-sat: 20%;
}
.c-tbl--light {
  --tbl-bdrs: 0;
  --tbl-sat: 15%;
  --tbl-th-bgc: #eee;
  --tbl-th-bdc: #eee;
  --tbl-th-c: #555;
  --tbl-th-tt: normal;
}

/**
 * table.css
 * @version 1.0.2
 * @description Generic Table Component
*/
:where([data-component="table"]) {
  --tbl-hue: 200;
  --tbl-sat: 60%;

  --tbl-bdc: hsl(var(--tbl-hue), var(--tbl-sat), 80%);
  --tbl-bdrs: 0.5rem;
  --tbl-bdw: 1px;
  --tbl-td-pb: 1.25ch;
  --tbl-td-pi: 2ch;
  --tbl-td-hover-bgc: hsl(var(--tbl-hue), var(--tbl-sat), 95%);
  --tbl-th-bgc: hsl(var(--tbl-hue), var(--tbl-sat), 40%);
  --tbl-th-c: hsl(var(--tbl-hue), var(--tbl-sat), 99%);
  --tbl-zebra-bgc: hsl(var(--tbl-hue), var(--tbl-sat), 90%);

  background-color: var(--tbl-bgc, transparent);
  border-collapse: var(--tbl-bdcl, separate);
  border-radius: var(--tbl-bdrs);
  border-spacing: var(--tbl-col-gap, 0) var(--tbl-row-gap, 0);
  box-shadow: var(--tbl-bxsh, none);
  table-layout: var(--tbl-tbl, auto);
  width: var(--tbl-w, 99.9%);
}

:where([data-component="table"] thead th) {
  background-color: var(--tbl-th-bgc);
  border-style: var(--tbl-th-bds, solid);
  border-block-start-width: 0;
  border-color: var(--tbl-th-bdc, initial);
  border-inline-end-width: var(--tbl-bdw);
  border-block-end-width: 0;
  border-inline-start-width: 0;
  color: var(--tbl-th-c);
  font-weight: var(--tbl-th-fw, 700);
  overflow: hidden;
  padding-block: var(--tbl-td-pb);
  padding-inline: var(--tbl-td-pi);
  position: relative;
  text-align: var(--tbl-th-tal);
  text-overflow: ellipsis;
  text-transform: var(--tbl-th-tt, uppercase);
  white-space: nowrap;
}

:where([data-component="table"] td) {
  background-color: var(--tbl-td-bgc, #FFF);
  border-color: var(--tbl-td-bdc, var(--tbl-bdc));
  border-style: var(--tbl-td-bds, solid);
  border-block-start-width: 0;
  border-inline-end-width: var(--tbl-bdw);
  border-block-end-width: var(--tbl-bdw);
  border-inline-start-width: 0;
  overflow: hidden;
  padding-block: var(--tbl-td-pb);
  padding-inline: var(--tbl-td-pi);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Because of `border-collapse: separate`, we need to  */
:where([data-component="table"] tr td:first-of-type) {
  border-inline-start-width: var(--tbl-bdw);
}
/* For header-cells, we set the `border-color` of the first and last border to it's `background-color` */
:where([data-component="table"] tr th:last-of-type) {
  border-inline-color: var(--tbl-th-bgc);
}
:where([data-component="table"] tr th:first-of-type) {
  border-inline-start-color: var(--tbl-th-bgc);
}
/* Set `border-radius` on first and last rows, on first and last cell */
:where([data-component="table"] thead th:first-of-type) {
  border-start-start-radius: var(--tbl-bdrs);
}
:where([data-component="table"] thead th:last-of-type) {
  border-start-end-radius: var(--tbl-bdrs);
}
:where([data-component="table"] tbody tr:last-of-type td:first-of-type) {
  border-end-start-radius: var(--tbl-bdrs);
}
:where([data-component="table"] tr:last-of-type td:last-of-type) {
  border-end-end-radius: var(--tbl-bdrs);
}

/* Optionally, set text-alignment and/or width per column */
[data-component="table"] tr > *:nth-of-type(1) { text-align: var(--ca1, initial); width: var(--cw1, initial); }
[data-component="table"] tr > *:nth-of-type(2) { text-align: var(--ca2, initial); width: var(--cw2, initial); }
[data-component="table"] tr > *:nth-of-type(3) { text-align: var(--ca3, initial); width: var(--cw3, initial); }
[data-component="table"] tr > *:nth-of-type(4) { text-align: var(--ca4, initial); width: var(--cw4, initial); }


/* Parameters */
[data-param~="noinlineborder"] tbody tr > td,
[data-param~="noinlineborder"] thead tr > th {
  border-block-start-width: 0;
  border-inline-end-width: 0;
  border-block-end-width: var(--tbl-bdw);
  border-inline-start-width: 0;
}
[data-component="table"][data-param~="stickycol"] thead tr th:first-child,
[data-component="table"][data-param~="stickycol"] tbody tr td:first-child {
  --tbl-td-bgc: var(--tbl-zebra-bgc);
  inset-inline-start: 0;
  position: sticky;
}
[data-component="table"][data-param~="stickyrow"] thead th {
  inset-block-start: -1px;
  position: sticky;
}
[data-component="table"][data-param~="zebracol"] tbody td:nth-of-type(odd) {
  --tbl-td-bgc: var(--tbl-zebra-bgc);
}
[data-component="table"][data-param~="zebrarow"] tr:nth-child(even) td {
  --tbl-td-bgc: var(--tbl-zebra-bgc);
}

/*
=====
HOVER
=====
*/
@media (hover: hover) {
  [data-param~="hovercell"] td:hover:not(:focus) {
    --tbl-td-bgc: var(--tbl-td-hover-bgc);
  }
  :where([data-param~="hoverrow"]:not([data-param~="hovercell"]) tr:hover td:not(:focus)),
  :where([data-param~="hoverrow"][data-param~="hovercell"] tr:hover td:not(:hover):not(:focus)) {
    --tbl-td-bgc: var(--tbl-td-hover-bgc);
  }
}

/* For demo */
body {
  font-family: ui-sans-serif, sans-serif;
  margin-block: 2ch;
  margin-inline: auto;
  max-inline-size: 64rem;
  padding-inline: 2ch;
}
label {
  font-size: 80%;
  font-weight: 500;
}
select {
  display: block;
  margin-block-end: 1ch;
  width: 10rem;
}
p {
  display: flex;
  gap: 2ch;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.