As I also plan to upload non-technical posts and notes on my website, I added the ability to filter content based on categories. Trying to avoid another Javascript solution, I remembered the CSS :has
selector (which I read about in a blog post from Ryan Mulligan’s website).
I based my solution on his examples, tailoring it to the classes available in my Hugo theme. First, I added a partial with a fieldset
and included it in the HTML
template used for lists. For now, the categories are hard-coded, as I don’t plan on adding more in the future:
<fieldset> <legend>Filter by category:</legend> <div> <input type="radio" id="all" name="filter" value="all" checked /> <label for="all">Show all</label> </div> <div> <input type="radio" id="tech" name="filter" value="tech" /> <label for="tech">Only technical</label> </div> <div> <input type="radio" id="nontech" name="filter" value="nontech" /> <label for="nontech">Only non-technical</label> </div></fieldset>
Next, I added the following to my css
:
fieldset { opacity: 75%; font-size: 0.75em; border: dotted; border-width: 1px;} body:has([name="filter"][value="tech"]:checked) .post-line:not([category="tech"]) { display: none;} body:has([name="filter"][value="nontech"]:checked) .post-line:not([category="nontech"]) { display: none;}
Finally, to make the filters work, I added a category to every post or note in Hugo:
---title: "CSS filter posts by category"date: "2024-08-24"⋯category: "tech"---
and included this category in the partial for post entries:
<div class="post-line" category="{{ .Params.category }}"> ⋯</div>