Skills Matrix

People versus skills/competencies matrix.

Team skills
PersonDesignEngineeringWriting
Priya Nair
Alex Chen
Beginner Proficient Expert

html

<figure class="skillsmatrix skillsmatrix--comfortable" style="--c:#BFD9F2;">
  <figcaption class="skillsmatrix__title">Team skills</figcaption>
  <table class="skillsmatrix__table">
    <thead>
      <tr><th scope="col">Person</th><th scope="col">Design</th><th scope="col">Engineering</th><th scope="col">Writing</th></tr>
    </thead>
    <tbody>
      <tr><th scope="row">Priya Nair</th><td><span class="skillsmatrix__cell" data-level="3" aria-label="Expert"></span></td><td><span class="skillsmatrix__cell" data-level="2" aria-label="Proficient"></span></td><td><span class="skillsmatrix__cell" data-level="1" aria-label="Beginner"></span></td></tr>
      <tr><th scope="row">Alex Chen</th><td><span class="skillsmatrix__cell" data-level="1" aria-label="Beginner"></span></td><td><span class="skillsmatrix__cell" data-level="3" aria-label="Expert"></span></td><td><span class="skillsmatrix__cell" data-level="2" aria-label="Proficient"></span></td></tr>
    </tbody>
  </table>
  
  <figcaption class="skillsmatrix__legend">
    <span><span class="skillsmatrix__cell" data-level="1"></span> Beginner</span>
    <span><span class="skillsmatrix__cell" data-level="2"></span> Proficient</span>
    <span><span class="skillsmatrix__cell" data-level="3"></span> Expert</span>
  </figcaption>
  
</figure>
<style>
.skillsmatrix { font: 13px/1.4 system-ui, sans-serif; color: #241430; margin: 0; max-width: 420px; }
.skillsmatrix__title { font-weight: 700; margin-bottom: 8px; text-align: left; }
.skillsmatrix__table { border-collapse: collapse; width: 100%; }
.skillsmatrix__table th, .skillsmatrix__table td { border: 1px solid #24143022; padding: 8px; text-align: center; }
.skillsmatrix__table th[scope="row"] { text-align: left; font-weight: 600; }
.skillsmatrix--compact .skillsmatrix__table th, .skillsmatrix--compact .skillsmatrix__table td { padding: 4px 6px; }
.skillsmatrix__cell { display: inline-block; width: 14px; height: 14px; border-radius: 3px; background: #24143014; }
.skillsmatrix__cell[data-level="1"] { background: color-mix(in srgb, var(--c) 35%, #FAF7F2); }
.skillsmatrix__cell[data-level="2"] { background: color-mix(in srgb, var(--c) 70%, #FAF7F2); }
.skillsmatrix__cell[data-level="3"] { background: var(--c); }
.skillsmatrix__legend { display: flex; gap: 14px; margin-top: 8px; font-size: 12px; }
.skillsmatrix__legend span { display: inline-flex; align-items: center; gap: 5px; }
</style>

tailwind

<figure class="skillsmatrix-tw skillsmatrix-tw--comfortable font-sans text-[13px] text-[#241430] max-w-md m-0" style="--c:#BFD9F2;">
  <figcaption class="font-bold mb-2 text-left">Team skills</figcaption>
  <table class="border-collapse w-full">
    <thead>
      <tr><th scope="col" class="border border-[#24143022] p-2">Person</th><th scope="col" class="border border-[#24143022] p-2">Design</th><th scope="col" class="border border-[#24143022] p-2">Engineering</th><th scope="col" class="border border-[#24143022] p-2">Writing</th></tr>
    </thead>
    <tbody>
      <tr><th scope="row" class="border border-[#24143022] p-2 text-left">Priya Nair</th><td class="border border-[#24143022] p-2 text-center"><span class="skillsmatrix-tw__cell" data-level="3" aria-label="Expert"></span></td><td class="border border-[#24143022] p-2 text-center"><span class="skillsmatrix-tw__cell" data-level="2" aria-label="Proficient"></span></td><td class="border border-[#24143022] p-2 text-center"><span class="skillsmatrix-tw__cell" data-level="1" aria-label="Beginner"></span></td></tr>
      <tr><th scope="row" class="border border-[#24143022] p-2 text-left">Alex Chen</th><td class="border border-[#24143022] p-2 text-center"><span class="skillsmatrix-tw__cell" data-level="1" aria-label="Beginner"></span></td><td class="border border-[#24143022] p-2 text-center"><span class="skillsmatrix-tw__cell" data-level="3" aria-label="Expert"></span></td><td class="border border-[#24143022] p-2 text-center"><span class="skillsmatrix-tw__cell" data-level="2" aria-label="Proficient"></span></td></tr>
    </tbody>
  </table>
  
  <figcaption class="flex gap-3.5 mt-2 text-xs">
    <span class="inline-flex items-center gap-1"><span class="skillsmatrix-tw__cell" data-level="1"></span> Beginner</span>
    <span class="inline-flex items-center gap-1"><span class="skillsmatrix-tw__cell" data-level="2"></span> Proficient</span>
    <span class="inline-flex items-center gap-1"><span class="skillsmatrix-tw__cell" data-level="3"></span> Expert</span>
  </figcaption>
  
</figure>
<style>
.skillsmatrix-tw__cell { display: inline-block; width: 14px; height: 14px; border-radius: 3px; background: #24143014; }
.skillsmatrix-tw__cell[data-level="1"] { background: color-mix(in srgb, var(--c) 35%, #FAF7F2); }
.skillsmatrix-tw__cell[data-level="2"] { background: color-mix(in srgb, var(--c) 70%, #FAF7F2); }
.skillsmatrix-tw__cell[data-level="3"] { background: var(--c); }
.skillsmatrix-tw--compact th, .skillsmatrix-tw--compact td { padding: 4px 6px !important; }
</style>

react

const ROWS = [
  { name: "Priya Nair", levels: [3, 2, 1] },
  { name: "Alex Chen", levels: [1, 3, 2] },
];
const LEVEL_LABEL = { 1: "Beginner", 2: "Proficient", 3: "Expert" };

export function SkillsMatrix({
  title = "Team skills",
  color = "#BFD9F2",
  density = "comfortable",
  showLegend = true,
}) {
  const pad = density === "compact" ? "4px 6px" : "8px";
  const cellColor = (level) => ({ 1: `${color}59`, 2: `${color}b3`, 3: color }[level] ?? "#24143014");
  return (
    <figure style={{ font: "13px/1.4 system-ui, sans-serif", color: "#241430", maxWidth: 420, margin: 0 }}>
      <figcaption style={{ fontWeight: 700, marginBottom: 8 }}>{title}</figcaption>
      <table style={{ borderCollapse: "collapse", width: "100%" }}>
        <thead>
          <tr>
            <th scope="col" style={{ border: "1px solid #24143022", padding: pad }}>Person</th>
            <th scope="col" style={{ border: "1px solid #24143022", padding: pad }}>Design</th>
            <th scope="col" style={{ border: "1px solid #24143022", padding: pad }}>Engineering</th>
            <th scope="col" style={{ border: "1px solid #24143022", padding: pad }}>Writing</th>
          </tr>
        </thead>
        <tbody>
          {ROWS.map((row) => (
            <tr key={row.name}>
              <th scope="row" style={{ border: "1px solid #24143022", padding: pad, textAlign: "left" }}>{row.name}</th>
              {row.levels.map((level, i) => (
                <td key={i} style={{ border: "1px solid #24143022", padding: pad, textAlign: "center" }}>
                  <span aria-label={LEVEL_LABEL[level]} style={{ display: "inline-block", width: 14, height: 14, borderRadius: 3, background: cellColor(level) }} />
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
      {showLegend && (
        <figcaption style={{ display: "flex", gap: 14, marginTop: 8, fontSize: 12 }}>
          {[1, 2, 3].map((level) => (
            <span key={level} style={{ display: "inline-flex", alignItems: "center", gap: 5 }}>
              <span style={{ display: "inline-block", width: 14, height: 14, borderRadius: 3, background: cellColor(level) }} /> {LEVEL_LABEL[level]}
            </span>
          ))}
        </figcaption>
      )}
    </figure>
  );
}