reddit spritesheet CSS magic

So you've got yourself a subreddit. Now you need to configure it. Boy, what a hard time /r/lubuntu had trying to get flair figured out. Unfortunately, the reddit group is our newest channel to connect with the larger community, so I didn't have a lot of help.

See the issue was that we already had this spritesheet created by our Artwork God, Rafael Laguna. He actually had made another one to make this fantastic stylesheet, using Naut (look at that winking Snoo!), so I was confident this would be easy.

However, I had quite a bit of problems trying to get background-position to behave right. It looked like it was going all over the place. In looking at tutorials, none of them, even the most helpful, covered what to do if you have a spritesheet. Instead, they all assume you just have individual images.

There were several problems I had going on including extra padding and incorrectly sized images on the spritesheet that created issues. The spritesheet was remade with more Lubuntu specific images (well, at least for half of them).

Lubuntu spritesheet

Making it a single row of equal-sized (16x16) images made things easier. The ah ha moment came when realizing that background-position moves the background relative to the canvas. It does NOT move the background on the canvas. So we needed to use negative numbers and all was well.

And yet, there was another problem: there's optional text that can go with the flair. Unfortunately, it was included in the span that was styled with our background spritesheet. It was appearing right on top of the flair and there was no way around this looking at the HTML.

<span class="flair flair-lxqt" title="Release Mgr. | QA Head">Release Mgr. | QA Head</span>
"Release Mgr. | QA Head"

Enter the ::before pseudo element. Note I didn't say selector. The following code creates an an element that sits before the element that it acts on, which is, in this case, the flair class. So before we see any flair things, we have an blank element that is 4 pixels away from the flair class (which includes the image and the text) and and that is 4 pixels away from the next element, which happens to be the text. It also makes sure that our spritesheet is in there and that we're selecting 16x16 bits of it.

.flair::before {
margin: 0 4px 0 4px;
display: inline-block;
background: url(%%reddit-sprite%%) no-repeat scroll top left;
min-width: 16px;
min-height: 16px;

And lastly, we need the specific positioning. Remember that the element that has the margin and everything is the pseudo element, so we need to use ::before on these as well. We'll also make sure to use the specific classes we created in the "edit flair" option in reddit Moderation Tools, so that we can act specifically on these.

.flair-lxde::before { background-position: 0px 0px !important; }
.flair-lxqt::before { background-position: -16px 0px !important; }
.flair-lenny::before { background-position: -32px 0px !important; }
.flair-user::before { background-position: -48px 0px !important; }
.flair-invader::before { background-position: -64px 0px !important; }
.flair-orb::before { background-position: -80px 0px !important; }

I basically hacked this together through inspecting elements at r/PixelDungeon (which is currently my favourite roguelike game and one that I hope to rewrite using Python and Kivy, if anyone's interested in helping) since they have all sorts of fantastic functionality going on. Kudos to them.

I do hope this helps save someone the sanity that I lost yesterday. ;)

blog comments powered by Disqus