Tinkering with a blog is a pretty good way to learn things you never meant to study in the first place.
A couple of months ago, I wrote about improving my blog’s search feature. Not long after that, someone named @xymoryn came across the site and gave it a fairly blunt critique. The comments were actually useful. I had been using the minimal theme for a long time without really touching the styling, mostly because I’m bad at CSS 😂—not because I didn’t want to change anything. One of the suggestions was to let AI help with the polish, which honestly made sense. If I can’t write the CSS myself, I might as well ask a machine to do some of the heavy lifting.
Styling changes
Although I was given some reference CSS, I didn’t really like that direction. The biggest issue was that it turned the original left-right layout into a top-bottom one. The whole reason I picked the minimal theme years ago was because of its two-column layout. If I wanted a stacked layout, I might as well have used the hacker theme instead.
That reference CSS also had some rough edges, probably because it had been generated by AI without fully accounting for the theme’s existing behavior. For example, the theme makes links become bold on hover. Since bold text can get wider, that can shift the layout around a bit. The reference stylesheet solved this by forcing all hovered links to become thinner instead. That stopped the width jump, but it also made links that were supposed to stay bold—like titles—look wrong.
I wanted to keep the minimal theme’s overall styling, but I also didn’t like the hover-to-bold effect. So I asked AI about that specific problem. The answer it gave me was to use font-weight: inherit;, which did fix the issue. But having no visible hover feedback at all felt awkward, so I copied GitHub a little and added an underline on hover instead.
I also adjusted font size, line height, and layout width, but only slightly. I didn’t want a dramatic redesign. A small increase in type size and spacing was enough to make the pages feel less cramped.
The layout needed a bigger change. The original minimal theme used fixed widths: 270px on the left and 500px on the right. On my MacBook, that was acceptable because the screen is relatively small, so the content still used a decent amount of space. On larger displays, though, an 860px content area is not much at all. On a 4K screen it can end up looking like a tiny strip in the center, which is not pleasant. So I switched to a percentage-based layout so the page can make better use of wider screens.
Another thing I changed was paragraphing. I knew perfectly well that in Markdown, two line breaks create a new paragraph, but when writing I had usually chosen single line breaks instead because the gap between paragraphs felt too large. In Chinese, though, a wall of unbroken text does not look great. I also didn’t want to go back and manually rewrite all my older posts.
So I took a shortcut: I replaced all line breaks with paragraph breaks. In Jekyll, that can be done with the replace filter by turning every <br> into </p><p>. Since Markdown parsing already wraps content in a paragraph, simply closing one p and opening another is enough to split the text into multiple paragraphs.
And why bother doing that? Mostly for first-line indentation. I find that it helps readability quite a bit. The CSS is simple enough: just give p a text-indent: 2em;.
The last styling-related issue was comment authorization. I use Gitalk, and people had asked about its permission scope before. After checking GitHub’s OAuth documentation carefully, I found that there really is no way to restrict it so it can only write Issues 😥. Other comment systems tend to depend more heavily on a backend, and some of them bothered me for other reasons. Giscus, for example, embeds a page from the Giscus website via iframe 😅. If that site goes down one day, the comment system goes with it. Of course GitHub itself is not exactly beyond failure either. Self-hosting was even less appealing; I’m not in a position to keep a server running as reliably as a large company can 😆.
In the end, I kept Gitalk and added a hint telling users that if they do not want to log in, they can click through to GitHub and comment directly there. I let AI write the CSS for that tooltip, and it produced this:
.gt-btn-login::after {
content: "如果不想登录,请点击上方评论数跳转至对应ISSUE进行评论";
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
background: #333;
color: #fff;
padding: 8px 12px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
opacity: 0;
visibility: hidden;
transition: opacity 0.2s, visibility 0.2s;
z-index: 10;
}
.gt-btn-login:hover::after {
opacity: 1;
visibility: visible;
}
.gt-btn-login::after {
margin-top: 8px;
}
.gt-btn-login::after {
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
}
At this point, I think the visual side of the blog is noticeably more pleasant to use, so I’m genuinely grateful for the earlier critique.
Compatibility work
Recently, for certain reasons, I started using Windows 7 again. I still think Windows 7 was a very good operating system. It had a lot of thoughtful features—desktop gadgets, built-in feed subscriptions, Windows Live Essentials, and so on. Microsoft eventually cut all of that 🤣.
Once I found myself back on Windows 7, I thought: since the system is so nice, why not also make the blog work better in Internet Explorer 8?
The Jekyll themes provided by GitHub were originally IE8-compatible, including the minimal theme I use. The problem is that over the years I’ve added a lot of features of my own, and most of them were built with a simple principle: if it works, it’s good enough. Compatibility was not a priority.
Still, most of the features I wrote are pretty simple. If something is theoretically possible in IE8, then in many cases it is not actually that hard to retrofit. Some things are impossible in principle, of course—WebGL, for example. That means my Live2D character has no chance of working there. As for other features, if they were merely tedious rather than impossible, I picked and chose what was worth the effort. Gitalk, for example, was not something I wanted to force into old-browser support.
Post view counter
My article view counter had already become fairly compatible after I rewrote it to call my own API through jQuery. Since jQuery exists largely to smooth over browser differences, and IE8 is within its support range, the basic feature was fine.
The one problem was cross-domain requests. IE8 does not support using XHR for cross-origin requests; it can only do that through XDomainRequest instead. Fortunately, there is an existing library that makes jQuery fall back to XDR in those cases. I used conditional comments to load that library only for IE9 and below, and after that the post view count displayed normally in IE 😆.
Responsive layout
IE8 does not support CSS media queries, so the page cannot adjust styles properly when the window size changes. I had not planned to solve that at first, but then I happened to come across Respond.js, so I just used it 😝.
Full-text search
From a pure functionality standpoint, full-text search should absolutely be possible in IE8. The issue was the library I had been using. It was a strange one: const was scattered all over the place, yet at the same time it included code that looked like it was trying to detect old XHR behavior, almost as if it claimed to support old browsers. Cleaning that up felt annoying enough that I did not want to spend the time.
So I used a shortcut. If local search does not work, then Google can do the searching instead. Whether Google supports IE8 is not really my problem 🤣. I simply wrapped the search box in a form, which also has the nice side effect of allowing search without JavaScript, assuming Google will accept that scenario.
Feed reader support
Previously, my blog only supported feeds through the official jekyll-feed plugin, which outputs Atom. Most feed readers support Atom just fine, and even IE8 handles it perfectly.
But I found that a very small number of services cannot parse Atom and only support RSS. So I added RSS support as well, along with XSLT templates for previewing both Atom and RSS feeds. And since I was already doing that, I also added JSON Feed 😆, even though the practical value of that is fairly limited.
Adding Web Slices
If I was going to support IE8, I figured I might as well use the features that browser had. In IE8’s feed subscription area there is an option called “Add to Web Slices.”
Because there were hardly any examples to look at, I did not even fully understand what the feature was supposed to look like at first. It seemed to borrow some ideas from the hAtom Microformat spec. At first I thought every item needed its own entry-title and entry-content, but that turned out not to be the case 😅. A single hslice can only have one entry-title.
The feature itself is simple. It lets the browser extract part of a webpage and display that part separately. When that selected portion updates, IE can notify the user. In practice, hslice needs to wrap all the elements involved, so you put it in the class of the outermost container. entry-title is the name shown when the user subscribes, and entry-content is the part of the page that gets sliced out and displayed. The exact details are documented by Microsoft.
Experimenting with IndieWeb support
Since Microformats came up, IndieWeb naturally followed. Hardly anyone around me seems to care about it, but it looked interesting enough to try for fun.
Level 0: domain name
According to the beginner guide, the most important requirement for being part of the IndieWeb is having your own domain. Seeing that made me wonder whether the whole thing was secretly a pitch from domain registrars. I do not really want to pay money to one.
Yes, DNS infrastructure costs something to maintain, but how much does it really cost? Most of it is effectively spread across ISPs anyway. And while IndieWeb advocates often point out that large company platforms can disappear, domains are not immune to external control either. Registrars and registries absolutely have the power to make a domain unusable. That is not something I control.
So even though a personal domain is considered important for IndieWeb, I decided not to bother. Which means, strictly speaking, my blog is not really IndieWeb 🤣.
Level 1: identity
Not having a custom domain does not prevent the next step. A big platform’s domain is still a domain, even if it is not mine.
The guide suggests that supporting IndieAuth is very easy: just add a rel=me link tag in the head pointing to a personal profile that supports IndieAuth, and make sure that profile links back to your site. For example, if it points to your GitHub profile and your GitHub profile points back, then GitHub login can be used to verify that the site belongs to you. This part can be checked with IndieWebify.Me.
Level 2: publishing
Before publishing, it helps to mark up content with microformats2 so other software can read it more reliably. That part is not too hard. You basically follow the relevant guide and add the expected class names to the right elements. After that, IndieWebify.Me can verify it.
The site identity also needs an h-card, which acts like a machine-readable business card for the website.
There is also Webmention. Declaring Webmention support allows other sites to notify you when they reference your article. For a static blog, though, it is not especially friendly. You have to receive those mentions and ideally display them, and you also need to send them when you cite someone else’s post and their site supports Webmention.
Jekyll does have plugins for this, but using extra plugins with GitHub-hosted deployment would mean writing my own Actions, and my publishing setup already has to update a bunch of Pages instances. It is not a great fit. So I chose a compromise: receive-only, not send, and not display them either. For that, I only need to add the Webmention endpoint in a link tag. Hardly anyone here uses Webmention anyway 🤣. If anyone is curious who has sent me Webmentions, that can be checked through the endpoint itself, although most of them were manually sent by me anyway 🤣.
Anyone who wants to add full Webmention support to their own site can test it with Webmention Rocks!. If the site runs on WordPress, this support is built in—you just need to enable it.
Level 3: interaction
A major part of IndieWeb is interaction between sites. The larger goal is to avoid depending entirely on big platforms, so this is meant to substitute for services like Twitter or Facebook. But while those services still exist, posting links to your own site there is also a way to attract readers. IndieWeb calls that POSSE.
For me, posting a newly written article in places like WeChat or QQ already counts as POSSE, since I do not really use foreign social platforms 😆.
Apparently there is also an expectation that comments from elsewhere can be synced back to your site. The most I can really manage is Gitalk, and that is enough for me.
One extra thing
Since I had already added some IndieWeb support, I figured I might as well join the IndieWeb Webring too. Most sites in the IndieWeb Webring 🕸💍 have made some effort to support IndieWeb, so joining felt like a small way to acknowledge that I had tried as well 😊.
Making the site more reliable
In the past, my main response to GitHub’s unreliability was simply to deploy the site on multiple Pages services. Later I realized that Git itself is distributed by design, and distribution is easy. If I really wanted better reliability, I could just use Git to push the site to many hosting providers directly.
So I used GitLab’s repository mirroring feature to synchronize the site to dozens of well-known Git hosting platforms in one go. That way, the blog is much less dependent on any single provider.
Final thoughts
This round of blog work taught me quite a few things. I ended up learning more CSS, exploring ways to improve browser compatibility, and thinking more seriously about reliability and visibility. Messing around with a blog really does become a kind of self-improvement project all by itself—and then there is the added bonus of writing about the process afterward 😆.
Maybe none of this will be particularly useful in the future. But it was interesting, and that is enough 😁.