GitHub Contributions Chart

GitHub profile pages are, to many, the de facto place to quickly judge the value of a developer. The contributions chart is an at-a-glance visual indicator of that value.

I disagree completely with the notion of the chart (or GitHub overall) as a way to value anyone, and I am not alone. But that is outside the scope of this post.

That being said, the contributions chart is wildly inaccessible. It may look pretty, but for anyone is who is not working in idealized conditions it is a problem. It is completely keyboard inaccessible, its hit areas are too small, it offers no cues for what is interactive, its contrast is poor, it is not exposed to screen readers in any way, heck, it’s not even responsive.

In short, if it is as important as many claim, then it needs to be rebuilt.

The Rebuild

See the Pen GitHub Contributions Chart I by Adrian Roselli (@aardrian) on CodePen.

The first, most critical thing to do is represent the grid with HTML that is appropriate. SVG is not it, since SVG does not natively impart any semantic nor structural value. A pile of <div>s is also wrong for the same reason. Lists do not fit since they are for single dimensions of data, and even a definition list is still a single dimension of name/value pairs.

The chart is quite clearly best served with a <table>. It is tabular data arranged into related columns and rows. In fact, this qualifies as a simple table with only a couple complexities (the spanning column and row headers). I have a whole blog post about making this kind of table, and it is accessible. I make it responsive, and still accessible, with a simple wrapper, which I address in another post.

Oh, there is also no JavaScript. I wasn’t trying to avoid it, but it just is not needed.

Keyboard-only Support

I make it usable with a keyboard in the most appropriate way possible. Each cell that represents contributions contains a link, because those links bring you to a page of activity. A keyboard user can Tab through the chart to get to a specific cell. A screen reader user can jump out of table navigation and also Tab through the chart.

Those inaccessible mouse-only tool-tips are just as easy to make accessible. I use the same technique as I wrote for making emoji accessible. They are keyboard-friendly and supported in screen readers. I also ignore all the empty cells because that would just be noise.

I also made sure to add an obvious focus outline style since the browser default is woefully inadequate. Relying on the tool-tip alone won’t do, since when tightly packed with activity it can be hard to distinguish which day has the focus.

Contrast

The squares rely on color to convey the relative number of commits for a day. Because I wanted this rebuild to look very much like the current chart, I used the same shades of green. However, for anyone with reduced vision, or who works in the sun, that just won’t do. If you toggle the Change fill checkbox then you can see the boxes change the area of the fill to signify contribution volume instead of color.

For users of Windows High Contrast Mode, those colors are essentially useless, but it is an easy fix with the right media queries. The squares are partially filled using a diagonal gradient with CSS system color keywords Window (black in this theme) to Highlight (green in this theme). The amount of the box filled corresponds to the amount of commits on a day.

A grid of nearly white squares on a black background, some of the squares have faint coloring.
The current chart at GitHub as seen in Windows High Contrast Mode using Internet Explorer 11.
A field of black with implied headings and rows from text headers; there are some squares that are partially or fully colored.
My chart as seen in Windows High Contrast Mode using Internet Explorer 11.

Update: February 13, 2018 (Fat Tuesday)

Per Glenda’s comment, I added a toggle to enable borders for each day box in the grids. I set it to to #949494 against the white background to meet the 3:1 ratio in the proposed WCAG Success Criterion 1.4.11, but I also left #767676 commented out in the code if you decide you want to see it at 4.5:1

Low Vision / Mobility

The whole thing is resizable without causing weird layout problems. All units are set in relative sizes (ems) so if you scale the default text size in your browser, the chart honors it. The tool-tips for the last few columns (from 45 up) adjust their position so they do not push past the right edge of the grid. I do this with a :nth-child(n + 45) and adjust the spacing accordingly.

You can try the resizing by changing the base font size of your browser. Alternatively, toggle the Make bigger checkbox, which adds font-size: 200%; to the wrapping <div>. While WCAG 2.1 has a minimum target size (Success Criterion 2.5.3 Target Size), it is only at level AAA, or beyond the level AA de facto standard most organizations follow. Regardless,

I should note that I would not advocate a toggle to enlarge the text in a real-world use of this chart (do not recreate browser features). The ideal base size for users should be chosen, and it should allow users to scale it as they see fit.

Screen Readers

Making such a large table easy to navigate can be tricky. With proper use of scope attributes, the header cells can do their job just fine. I also added headers attributes to point to the ids of the header cells and relay them in the order I want. So <td headers="Feb17 y17 Sun"> tells the screen reader to read the month, year, and day name in an effort to get the more important information spoken first. This way a user can quickly know if she has changed months when jumping into a new cell, for example.

For cells with links, I use aria-labelledby to pull the same text that I use in the tool-tips. This reads as plain language and also corresponds to what a sighted screen reader user will see (since not all screen reader users are blind).

The current chart at GitHub using Firefox 58.0.2 with NVDA 2017.4. If you cannot hear it, NVDA just skips the entire chart after rattling off all the visible text in one breath. Attempting to find it with table controls yields nothing.
My version of the chart, also using Firefox 58.0.2 with NVDA 2017.4. The audio demonstrates me first discovering the table, checking for other tables, and then starting to navigate the table using NVDA keyboard commands (Ctrl + Alt + ///). I first explore the months and years (from 0:14 to 0:35) and then I start navigating by cell to find dates where I know I contributed.

The Re-Rebuild

See the Pen GitHub Contributions Chart II by Adrian Roselli (@aardrian) on CodePen.

Spending time hitting Tab to navigate the chart made me wonder if it made sense for each row to span months. When I think of a wall calendar, it goes day by day through each month, not by each Sunday of the year, then each Monday of the year, and so on.

So I swapped the axes of the grid. Sunday through Saturday across the top, months down the side. Like a wall calendar. This has the advantage of fitting in a narrow display quite nicely. It also meant that making it adopt the wider layout on the GitHub site required some CSS trickery.

The first step was using CSS to rotate the table. Because adapting the <caption> was going to throw off all the spacing, I visually hid it and am using a <h#> as a visual landmark. Then I had to separately rotate some of the text, including the tool-tips.

Because rotating the table means the layout (and tab order) is essentially inverted from what we want, I also had to mirror the the entire table. Which then meant I had to un-mirror the text. Here is where I learned that the order of operations on a CSS transform matters. It’s amazing how transform: matrix(-1, 0, 0, 1, 0, 0) rotate(90deg); can save your day.

Fun fact: it all works in Internet Explorer 11.

I made no effort to adjust the width media queries nor the tool-tip positioning when the user toggles to larger text. This version is very prototype-y. Also, sighted screen reader users will struggle with table navigation on wider displays (since down means right, right means up, and so on) due to the mirrored and rotated table. After all, source order drives focus order, and they should match.

Filing an Issue

GitHub has no official issue tracker for its own site. I followed its documented process and provided a report through the contact form. I also file an issue in the unofficial GitHub repo (not maintained by GitHub): Profile page contributions chart is inaccessible #1182

The Motivation

I think I need to frame this first. It all started with a tweet. Jeffrey Zeldman shared a CSS grid experiment by Ire Aderinokun which was a recreation of the GitHub contribution chart. I saw it picked up at CSS Tricks, shared elsewhere, and generally fawned over.

Of course I did what I do, and got frustrated on Twitter. It is a nice experiment, but only an experiment. Visually, it is a natural application of CSS grid, though practically that is the wrong reason to use grid. Further, the code example uses lists, does not consider the interaction in place, and is inaccessible in as many ways as the original.

This pile of words is my effort to be more productive. Experiments are all too often taken as gospel when the right voices get behind it.

Update: June 8, 2018

Now that Microsoft owns GitHub, I suggested perhaps Microsoft’s accessibility team could help here. At their suggestion via Twitter, I have filed an issue on the User Voice forum that points back to this post. Because there is no GitHub category, it is mis-categorized for now.

So, yeah, go vote I guess? Since the forum implies popularity of an issue gets eyeballs, this may sit for a long time before being passed to anyone at GitHub.

5 Comments

Reply

Adrian, I love this! I’m working on the proposed SC for WCAG 2.1 proposed SC 1.4.11 Non-Text Color Contrast and your change fill in the rebuild totally made my day!

One question I have…could you add thin dark outline on each light grey grid blocks? For people with low vision those light grey boxes have very little contrast with the white…and I think they do add value (are informational).

What do you think?

In response to Glenda Sims. Reply

Glenda, yep, a thin gray outline is absolutely do-able. I even played with one briefly but left it off for the following reasons:

1. I was trying to mimic the current look first,
2. I felt the empty cells were mostly noise so letting them recede was better,
3. I thought it looked crappy (my opinion) and was very busy.

They could just as easily be added with another toggle checkbox. Maybe when I get back from Fat Tuesday gluttony I will add one.

In response to Glenda Sims. Reply

Glenda, I modified both examples with a toggle to enable borders.

Reply

I just looked at it quickly so perhaps I’m missing something but I don’t think that a tall narrow activity sheet will meet their usability needs except maybe a mobile view. Why not swap the row and columns to make it long and wide?

In response to David MacDonald. Reply

David, I may be misunderstanding your question. The default grid is long and wide. The first example (the embedded CodePen) shows this. The second example (the other embedded CodePen) is my effort to re-order the grid so it follows a different visual tab sequence. In a wide screen it would still be long and wide. The tall and thin version for narrow screens is just a bonus.

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

This site uses Akismet to reduce spam. Learn how your comment data is processed.

To respond on your own website, enter the URL of your response which should contain a link to this post's permalink URL. Your response will then appear (possibly after moderation) on this page. Want to update or remove your response? Update or delete your post and re-enter your post's URL again. (Learn More)