freeCodeCamp
freeCodeCamp copied to clipboard
Implement Table component
Current specs
- Variants:
- Dark
- Light
- Types of tables:
- Condensed
- Striped
- Bordered
- Borderless
- Sizes (for responsive mode):
- Large (lg)
- Medium (md) (default)
- Small (sm)
- a11y best practices for tables?
Screenshots
Usage | Light theme | Dark theme |
---|---|---|
Timeline on user profile | ![]() |
![]() |
User settings under certifications | ![]() |
![]() |
Table component is only used in the timeline and in the user settings
Implementation plan
Use the bootstrap v3.3.7 stylesheet for styling references and the react bootstrap table component source for implementation reference.
Props interface
Prop | Type | Required | Default | Note |
---|---|---|---|---|
variant |
'light' | 'dark' |
|||
size |
'large' | 'medium' | 'small' |
'medium' |
||
bordered |
boolean |
|||
borderless |
boolean |
|||
hover |
boolean |
Hover state on table rows within a <tbody> . |
||
responsive |
boolean |
|||
striped |
boolean |
|||
className |
string |
Table layout
We should just use Tailwind's table-auto
utility class for the Table component as the default since according to Tailwind:
...it will allow the table to automatically size columns to fit the contents of the cell.
Reference:
Delivery plan (Will add more as needed)
- [x] Remove Table Component with new basic one (variant, sizes, etc.) - #47263
- [ ] Create tests for a11y - #48823
Regarding accessibility for tables, if the table is rather simple then there is really not a lot you need to do to make it accessible other than using the native table elements properly. The link you have to table best practices above is a description of the different roles that are assigned to the various table elements, which is helpful for when you aren't using the native HTML elements. But you should always use the native HTML elements, so I would just ignore that link :smile:
Some accessibility considerations for tables:
- Providing a
caption
is a good accessibility practice but it is not a requirement. - Although it seems like they would be helpful, the
thead
,tfoot
andtbody
elements provide no accessibility functionality at all. For sure there are other reasons to include them, but accessibility is not one of them. - Very simple tables do not really need any further help, but as your tables get more complex, especially the header structure, then you may need to use the
scope
attribute on the headers. And for very complex tables you will need to use theheaders
attribute on the data cells, which will require addingid
s to the headers. You can get examples of all of these levels of complexity at W3C Tables Tutorial. - As for navigating the tables with screen readers, there is nothing that needs to be done to assist with this. Screen readers have their own built in key commands for navigating tables. You do not need to add
tabindex
attributes or anything else to help screen reader users. - While it is great to try and make tables responsive, it is not a requirement. Tables are allowed to scroll horizontally if needed. They are considered to be "two-dimensional data" elements and thus are exempt from the reflow requirements dictated under WCAG 1.4.10.
- Regarding horizontal scroll, while all browsers will automatically add a scroll bar for tables if you narrow the browser skinnier than the table, unfortunately only Firefox makes that scroll bar keyboard accessible at the moment. So if there is a chance your table will scroll, then to be really accessible you need to wrap the table in a div, give it a role of region, and assign it an accessible name (most people use the table caption). A good description of how to do this can be found at Under-Engineered Responsive Tables.
For the props, we should only implement the props that are used in learn such as striped
, condensed
, etc.
The aim for the first sprint of the component library is to create only what we use. In the upcoming sprints, we will improve those components and make them more usable.
A few issues I've encountered while implementing the table:
I saw the following bootstrap CSS code for the table:
.table > thead > tr > th,
.table > tbody > tr > th,
.table > tfoot > tr > th,
.table > thead > tr > td,
.table > tbody > tr > td,
.table > tfoot > tr > td {
padding: 8px;
line-height: 1.42857143;
vertical-align: top;
border-top: 1px solid #ddd;
}
Notice this would require multiple tailwind variants to work. Then if I were to want my table condensed, it would require the following CSS:
.table-condensed > thead > tr > th,
.table-condensed > tbody > tr > th,
.table-condensed > tfoot > tr > th,
.table-condensed > thead > tr > td,
.table-condensed > tbody > tr > td,
.table-condensed > tfoot > tr > td {
padding: 5px;
}
I tried adding a variant with the following code(tried with * and without it):
addVariant('table-children', '& * > thead > tr > th, * > tbody > tr > th, * > tfoot > tr > th, * > thead > tr > td, * > tbody > tr > td, * > tfoot > tr > td');
but it doesn't work. It will get messy quickly if I add multiple tailwind variants.