Lists and Tables
Finding things in a long list: search, filters, tables with and without actions, files to download, Load More and pages, and folded lists.
On This Page
Search App
One search box over a list: a sentence saying what the user can search by, then a box
across the full width, searching as people type. The sentence does the label's job on
screen, so the
<label> is for screen readers only (sr-only). The
placeholder says what you'll find, ending in an ellipsis.
cmu-search-bar, sr-only
| Course | Title | Status |
|---|---|---|
| 15-112 | Fundamentals of Programming | Available |
| 15-122 | Principles of Imperative Computation | Unavailable |
| 21-120 | Differential and Integral Calculus | Available |
| 48-100 | Architecture Design Studio | Unavailable |
| 76-101 | Interpretation and Argument | Available |
| 85-102 | Introduction to Psychology | Available |
Showing all 6 sections
- One box over a list is a search. Several groups side by side, such as a search box and checkboxes, are filters, each with its own small label.
- Say how many are showing under the list, in the same words everywhere: "Showing 20 of 312 sections," "Showing all 312 sections," "Showing 1 section," and with nothing found, the template's own "Sorry, no results to display."
Filters App
A row of filter groups above a list, each with a small label over a search box or checkboxes. A group with a text box takes the row's spare width; two or more split it, and wrap on a narrow screen. For a single search box, use a search instead.
cmu-filters, cmu-filter-group,
cmu-filter-checks
| Course | Title | Status |
|---|---|---|
| 15-112 | Fundamentals of Programming | Available |
| 15-122 | Principles of Imperative Computation | Unavailable |
| 21-120 | Differential and Integral Calculus | Available |
| 48-100 | Architecture Design Studio | Unavailable |
| 76-101 | Interpretation and Argument | Available |
| 85-102 | Introduction to Psychology | Available |
Showing all 6 sections
- Filter as people type, and say how many rows are showing under the table (see Load More).
-
Keep the stripes even: Move hidden rows to the end of the table, so
table.alternatestill alternates. - Put the filters in the URL, so a filtered list can be bookmarked and shared.
-
To match words that aren't shown, such as other names for the same
thing, put them in a
data-keywordsattribute on the row for your filter to read, not in a hidden cell.
Tables CMS
Use the template's table.alternate for striped rows. Add
cmu-full to stretch a table to full width from 768px up (below that, the
template lets it scroll sideways). cmu-compare splits a two-column table
evenly, for before-and-after comparisons. Cells are centered top to bottom, so a
one-line cell sits level with a wrapped one or a picture beside it; to center pictures
of different widths across their column too, add the template's
aligncenter to those cells.
Give every table a header row, with <th scope="col"> for each
column, so screen readers can say which column a cell is in. A column of buttons gets
a header too, hidden with sr-only, such as "Actions."
table.cmu-full, table.cmu-compare
| Before | Now |
|---|---|
| One file per section | One file can cover many sections |
| Count modules to see where you stand | A completion bar and status filters |
Tables With Actions AppScript
The bulk bar sits on top of a table.alternate: the selection count, then
actions for the selected rows. Its height is fixed, so buttons appearing don't push
the table down. Each row gets one button, the next thing to do, and a ⋯ menu with the
rest; a row with nothing else to do gets no menu.
cmu-bulk-bar, cmu-selection-count,
cmu-has-selection, cmu-select-cell, cmu-sort,
cmu-sort-arrow, cmu-fit, cmu-row-buttons,
cmu-row-menu, cmu-row-menu-list, data-cmu-menu,
num
- One button per row: solid for something missing (Upload Syllabus), outlined when it's there (Replace Syllabus), at one fixed width and the height of a two-line button so rows stay even.
-
The ⋯ menu (
cmu-row-menu) holds the row's other actions, in the bulk bar's words: a button for each, or a link for one that goes somewhere. Name the ⋯ button for screen readers ("More actions for 15-112 A") and give it a matchingtitle.cmu-app.jsopens it, one at a time; a click elsewhere or Escape closes it. -
Something to open, such as a file, gets a plain link in a column of
its own before the actions, with its type after it: "View [PDF]." Keep the row's
title plain text. Hide the column's header with
sr-onlyand name what the link opens ("Syllabus"); the actions column's hidden header is "Actions." -
Selection: the app's script keeps the count current ("No sections
selected" when there are none), adds
cmu-has-selectionto it when anything is selected and shows each bulk button only when it applies to a selected row, with how many: "Upload Syllabus (2)." Try it above. - Checkbox cells: the label fills the cell, so the whole cell is the click target.
-
Sorting: put
data-sort-keyon the header and abutton.cmu-sortinside it; setaria-sorton the sorted column. For filtering, see Filters. -
cmu-fitshrinks a column to its content.num(onthandtd) right-aligns numbers. -
Keep labels together with
, so "a" never ends a line inside a button.
| Course | Title | Seats | Status | Syllabus | Actions | |
|---|---|---|---|---|---|---|
| 15-112 A | Fundamentals of Programming | 120 | Unavailable | |||
| 15-122 A | Principles of Imperative Computation | 95 | Available | View [PDF] |
File Table CMS
A list of forms or documents to download, with when each was last changed. Use
table.alternate with real column headings, and put the file type after
each link in plain text. Don't put the links in <h4> headings to
make them stand out, since screen readers then announce every row as a heading. A long
page of them can go under collapsed headings, as below.
table.alternate, cmu-full
| Form | Last Updated |
|---|---|
| Syllabus Template [Word] | August 2026 |
| Accessibility Checklist [PDF] | June 2026 |
| Department Administrator Guide [PDF] | October 2026 |
Load More App
A button under a long list that adds the next batch to it, after a count of what's showing. It suits browsing and search results, where people scan down. For a list people need to come back to a place in, use Pagination instead.
The app loads the results and updates the count; it doesn't depend on the template's
script. Load More is a ghost button half the page wide, and the full width on phones.
Hide its paragraph (hidden) once everything is showing.
Style
Name what the button loads, with the same noun as the count: “Load More Sections.”
cmu-results-count, cmu-load-more
| Course | Title | Status |
|---|---|---|
| 15-112 | Fundamentals of Programming | Available |
| 15-122 | Principles of Imperative Computation | Unavailable |
| 15-150 | Principles of Functional Programming | Available |
| 15-210 | Parallel and Sequential Data Structures and Algorithms | Available |
| 21-120 | Differential and Integral Calculus | Available |
| 21-122 | Integration and Approximation | Unavailable |
| 48-100 | Architecture Design Studio | Available |
| 48-200 | Architecture Design Studio: Composition | Unavailable |
| 76-101 | Interpretation and Argument | Available |
| 76-106 | Writing About Literature, Art and Culture | Available |
| 85-102 | Introduction to Psychology | Available |
| 85-211 | Cognitive Psychology | Unavailable |
Showing 4 of 12 sections
Pagination App
One batch of results at a time, each with its own address, under a count of what's showing. It's for a list people come back to a place in, or one that's too long to keep adding to with Load More.
A pager is one list: first («), previous (‹), the page numbers, next
(›) and last (»). Mark the current page with
aria-current="page", and give each arrow an
aria-label ("First page" and so on) for screen readers. An arrow that
goes nowhere, such as previous on the first page, keeps its place but loses its
href and gets aria-disabled="true", which grays it out. Keep
the numbers to seven slots, so the pager stays the same width as people move through:
the first page, the last and the pages around the current one, with an ellipsis for
each gap (1 2 3 4 5 … 16 near the start, 1 … 7 8 9 … 16 in the
middle, 1 … 12 13 14 15 16 near the end). With seven pages or fewer, show them
all. Use the same batch size as Load More, such as 20. On phones, « and »
give way to the numbers.
cmu-results-count, cmu-pager
Showing 21-40 of 312 sections
Folded Lists App
A <details> whose summary reads as a line of text ending in a bold
toggle with a chevron, which points down while closed, flips up when open and turns
red on hover. It opens right there, so it doesn't look like a call to action to
another page. Closed, the toggle is the count of what's hidden ("6 More"); open, it
says Show Fewer, and the whole list shows. It works without a script, and it slides
open and closed where the browser supports that (not for people who turn motion down).
Tabs fold the same way.
cmu-more, cmu-more-link, cmu-more-closed,
cmu-more-open
ARC, CS, ECE and 6 MoreShow Fewer
ARC, CS, ECE, HIS, HSS, MSE, MUS, PHI, STA