Resurrecting an old technique to build UI in GitHub READMEs

Almost exactly six years ago, I launched Octo Ring, a webring for GitHub. I hadn’t thought about it at all since launch, so I was delighted to find that it organically collected over 1100 members. It spread entirely through the Markdown widgets that members are encouraged (but not required) to place on their profiles. You can see an example on mine:

It’s a pretty standard badge, if a bit garish. The most surprising thing is that the buttons actually work! Prev, Random, and Next will each take you to different profiles. GitHub aggressively strips way everything but a very limited set of HTML tags and attributes, precisely to stop you from doing this. But I did it anyway.

I used an old webmaster’s trick. Before we had such a nice variety of layout options and luxuries like border-radius, developers had to build UI by slicing images. The widget is made of five parts, and the challenge is gluing them back together in GitHub’s constrained environment:

Removing gaps

Luckily images already display side by side (inline) so we just need to set their widths using width and use <br> to start new rows. Then we can get rid of vertical gaps with align="top".

(Below, I’m displaying the code with newlines so you can read it. But that will add spaces to the actual layout, so when you do it yourself, you should remove all whitespace between elements or swallow them with comments.)

<a href="https://octo-ring.com/"><img src="https://octo-ring.com/static/img/widget/top.png" width="99%" alt="Octo Ring logo" align="top"></a>
<br>
<a href="https://octo-ring.com/p/veggiedefender/prev"><img src="https://octo-ring.com/static/img/widget/prev.png" width="33%" alt="previous" align="top" title="previous profile"></a>
<a href="https://octo-ring.com/p/veggiedefender/random"><img src="https://octo-ring.com/static/img/widget/random.png" width="33%" alt="random" align="top" title="random profile"></a>
<a href="https://octo-ring.com/p/veggiedefender/next"><img src="https://octo-ring.com/static/img/widget/next.png" width="33%" alt="next" align="top" title="next profile"></a>
<br>
<a href="https://octo-ring.com/"><img src="https://octo-ring.com/static/img/widget/bottom.png" width="99%" alt="check out other GitHub profiles in the Octo Ring" align="top"></a>

Constraining size

It’s enormous. If we wanted that, then we’d be done. And if we had used fixed pixel widths, then we wouldn’t have this problem at all, but we would encounter wrapping at small window sizes. To get the best of both worlds, we need a container. A table was the best I could find.

<table>
  <tbody>
    <tr>
      <td>
        <a href="https://octo-ring.com/"><img src="https://octo-ring.com/static/img/widget/top.png" width="99%" alt="Octo Ring logo" align="top"></a>
        <br>
        <a href="https://octo-ring.com/p/veggiedefender/prev"><img src="https://octo-ring.com/static/img/widget/prev.png" width="33%" alt="previous" align="top" title="previous profile"></a>
        <a href="https://octo-ring.com/p/veggiedefender/random"><img src="https://octo-ring.com/static/img/widget/random.png" width="33%" alt="random" align="top" title="random profile"></a>
        <a href="https://octo-ring.com/p/veggiedefender/next"><img src="https://octo-ring.com/static/img/widget/next.png" width="33%" alt="next" align="top" title="next profile"></a>
        <br>
        <a href="https://octo-ring.com/"><img src="https://octo-ring.com/static/img/widget/bottom.png" width="99%" alt="check out other GitHub profiles in the Octo Ring" align="top"></a>
      </td>
    </tr>
  </tbody>
</table>

What will you do with this power?

I hope you build something silly with this technique and send it to me! I bet this works really well with SVGs. And please remember to include descriptive alt attributes on every element that has a significant meaning. That way your UI remains accessible to blind users.