Skip to main content
Squeezing Reactions Into the Header featured

Squeezing Reactions Into the Header

August 16, 2026

4 min read
DevelopmentGiscussionsMeta
Photo by Karan Mandre

Fresh off fixing the schema bug in the last post, I looked at the top of a Giscussions thread and it just felt wrong. Not broken — wrong. Reactions sat in their own block above the comment/reply counts, which meant the first screenful before you even reached the timeline was taller than it needed to be, split into pieces that had nothing to do with each other.

Original Giscussions header with reactions in a separate block above the timeline

Every individual piece of that header looked fine in isolation. Together they had no rhythm at all.

What I was going for

One compact row: comments, replies, and reactions on the left, sort controls on the right. Related discussion signals grouped together, controls kept separate. That was the whole brief.

Moving it

I relocated reactions out of their standalone block and into the left side of the header — comment count, reply count, reactions text, reaction pills1, all in one scanning path. Immediately less fragmented.

Getting five different pieces of content to wrap and align predictably on one row (especially on narrow screens) took more fiddling than the change sounds like it should. And once they were together, I noticed comments and reactions text were both linking to the same destination, which was just noise — two links pointing at one place teaches nobody anything. I dropped the reactions link and kept comments as the one canonical navigational text, with reactions staying as plain informational text and the reaction buttons themselves still interactive.

That also meant fixing the visual hierarchy: comments count stays the loudest thing in the row, replies and reactions sit quieter beside it, and the reaction controls read as distinctly interactive rather than blending into the labels.

The last piece was tightening the gap between the header and whatever comes next — the timeline, or the comment box. This is where it got annoying: the element that follows the header isn't the same in every state. Populated thread, empty thread, comment box in top-input mode — each one changes what's actually adjacent to the header in the DOM, so a spacing rule that looked right in one state missed the others completely. I had to write selectors that covered all three adjacency patterns before spacing actually held consistently everywhere.

I could have left reactions in their own block and only tightened spacing around it, but that keeps the split hierarchy that made the top of the thread feel disjointed in the first place — the whole point was pulling those signals into one place, not just shrinking the gap between them.

All of this landed in components/Giscus.tsx and the theme stylesheets (styles/base.css, styles/themes/custom_example.css), commit 8ce7763.

Refactored Giscussions header with reactions inline beside comment and reply counts

Where it actually went wrong the first few times

Three things ate most of the iteration time here, and none of them were the CSS itself:

Selectors that worked for the populated-thread state silently missed the empty-thread state, because the sibling elements were different in each. Flex gap on the parent kept fighting with the ad-hoc margins I was adding on top of it, so spacing looked inconsistent even when the values were technically correct. And the redundant comments/reactions links turned out to be a UX smell, not a styling detail — fixing it was less about CSS and more about admitting two links to one destination wasn't helping anyone.

Screenshots from one state don't tell you much here. Something can look perfect in a populated thread and still be off in an empty one, or in top-input mode versus bottom-input mode. I ended up checking every combination — populated, empty, top-input, bottom-input, narrow viewport — before trusting any single selector.

Where it landed

Reactions now sit inline beside comments and replies, the header groups align cleanly left and right, comments is the one link, reactions is plain text, and the gap before the timeline or comment box holds steady no matter which state renders next to it. It reads as one component now instead of three stacked pieces competing for attention.

Refactored Giscussions header with reactions inline beside comment and reply counts

The thing I'd actually take away from this: checking every render state up front would have saved most of the back-and-forth, and I stopped treating this as "just CSS" the moment I realized spacing bugs here were really about DOM order and which rule owned which sibling relationship. A canonical link beat two redundant ones. And CSS-only changes still needed the same verification discipline as anything else — fast to write isn't the same as safe to ship.

No regressions turned up after this one shipped. Small refactor, but the top of the thread finally feels like it was designed on purpose instead of assembled from parts.

Footnotes

  1. Reaction pills: emoji reaction buttons styled as compact pill-shaped chips, each showing an emoji and a count. ↩

Marc Santos

Marc Santos

Full-Stack Engineer & Product Developer

I write about building things—from site features to developer tooling—alongside travel, photography, and occasional personal reflections.

When I’m not building, I’m exploring—whether that’s a new place with a camera, a mountainside, or somewhere underwater.

About MarcBuild a product together

Keep reading

Forking Giscus: Actor Gotcha

Forking Giscus: Actor Gotcha

Jul 05, 2026

Disqus to Giscus in Gatsby

Disqus to Giscus in Gatsby

May 24, 2026

Masonry Grid Implementation

Masonry Grid Implementation

May 10, 2026

Designed and developed by Marc Santos.
This website is a work in progress made with .
© 2011–2026. All Rights Reserved. Hikari v4.9.2.