webdevpuneet.com

Bootstrap User Permission Matrix — Free HTML CSS JS Snippet

Bootstrap User Permission Matrix · Dashboards · Plain HTML, CSS & JS · Live preview

CategoryDashboards

Copy & paste

Source Code

<div class="container py-5 d-flex justify-content-center">
  <div class="card bsperm-card">
    <div class="card-body p-3">
      <h6 class="fw-bold mb-2">Role permissions</h6>
      <div class="table-responsive">
        <table class="table table-sm align-middle mb-0" id="bspermTable">
          <thead>
            <tr>
              <th>Permission</th>
              <th class="text-center">Viewer</th>
              <th class="text-center">Editor</th>
              <th class="text-center">Admin</th>
            </tr>
          </thead>
          <tbody></tbody>
        </table>
      </div>
      <p class="small text-muted mt-2 mb-0">Click a cell to toggle it. Admin always keeps every permission.</p>
    </div>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Permission state lives in one plain grid object, indexed identically to the rendered rows and columns
Admin permissions are structurally locked, not just pre-checked and still technically editable
The click handler explicitly rejects locked cells before ever touching the underlying grid state
Toggling any unlocked cell is one symmetric operation with no per-permission or per-role special cases
Adding a new permission or role only requires extending the two source arrays, not new logic

About this UI Snippet

Bootstrap User Permission Matrix — HTML, CSS & JavaScript

Screenshot of the Bootstrap User Permission Matrix snippet rendered live

The permission state lives in one plain grid object keyed by role, each holding a boolean array indexed the same way as PERMISSIONS — grid.editor[2] is unambiguously "does the editor role have the third permission," which is what makes rendering the entire table a matter of mapping over two small arrays rather than hand-writing markup for every one of the fifteen cells.

Admin's row isn't just pre-checked — every cell in grid.admin is genuinely fixed to true and separately marked locked in the render function, and the click handler explicitly bails out on a locked cell before touching grid at all. That distinction matters: a "pre-checked but still editable" admin row would let someone accidentally uncheck "Manage billing" for admins and lock the whole team out of billing, which a real permission matrix should treat as structurally impossible, not just discouraged.

Toggling any unlocked cell is a single, symmetric operation — grid[role][row] = !grid[role][row] — with no special-casing per permission or per role beyond the one admin-lock check, which is what keeps adding a sixth permission or a fourth role a matter of extending the two source arrays rather than writing new toggle logic.

Step by step

How to Use

  1. 1
    Load the snippetA 5x3 grid renders with Viewer, Editor, and Admin columns, each cell showing a checkmark or dash.
  2. 2
    Click a checkmark or dash in the Viewer or Editor columnIt toggles immediately between granted and not granted.
  3. 3
    Try clicking any cell in the Admin columnNothing happens — every Admin cell is genuinely locked to always-granted, not just pre-checked.
  4. 4
    Toggle several Editor permissions on and offEach cell updates independently, with no effect on Viewer or Admin.

Real-world uses

Common Use Cases

Admin panels managing team or workspace roles
A direct, editable view of exactly what each role can do, more scannable than a paragraph description per role.
DEV
Reviewing who changed a permission and when
Pair with bootstrap-audit-log-viewer so a permission change here shows up as a searchable, filterable event there.
Enterprise and B2B SaaS access control settings
Pairs with bootstrap-role-comparison-table-style summaries for a fuller access-management section.
DEV
Internal tools defining custom role-based access
A starting point for any admin UI letting an operator define exactly which permissions a custom role should carry.

Got questions?

Frequently Asked Questions

A pre-checked-but-editable cell can be accidentally unchecked by a stray click, silently removing a permission a role is supposed to always have — locking it structurally (both visually and in the click handler) makes that mistake impossible rather than just unlikely.

Yes — add it to the ROLES array and give it its own boolean array in grid keyed by that role name; render() and the click handler both iterate ROLES generically and need no changes.

Add its label to PERMISSIONS and a corresponding boolean to every role's array in grid, at the same index — the table automatically grows by one row.

Yes. Keep the grid object in component state, and toggle a cell by producing a new grid object with that one role/row value flipped (respecting your framework's immutability conventions) rather than mutating it directly.