Implementing Focused Reading Mode on My Blog

Amit Merchant · May 9, 2022 ·

The other day, I was scrolling through my Twitter feed and I saw this tweet from Paco where he implemented what he calls “fuzzy reading mode” on his blog.

The idea

The idea is when you’re on an article and press Alt, everything (except a few things such as heading and iframes) on that article turns into a blurry state. So, now if you want to read something, you’d need to hover over it so that specific parts get unblurred.

Some people would prefer reading in a “focused reading” mode like this. And so, I thought why not implement it on my blog?

I attempted to implement it and turns out, it only took me 15 minutes or so to implement it (with a slight modification where I’m triggering this feature on pressing the M or m keys) and in this article, I’m going to explain how I implemented it.

But first, here’s what it looks like when enabled.

The JavaScript implementation

To implement something like this is pretty simple. First, I needed to add a class called focus-mode to the <body> when the user triggers an action.

In my case, I wanted to trigger this when user presses the M or m keys when on the article. Essentially, pressing these keys will toggle adding the focus-mode class. I did this using the following piece of JavaScript snippet.

window.addEventListener('keydown', function (event) {
    if (
        event.code === 'KeyM'
        && document.activeElement !== document.getElementById('tlemail') 
    ) {
        document.body.classList.toggle('focus-mode');
    }
}, false);

As you can tell, I’m listening to the keydown event and when event.code is “KeyM”, I’m toggling the focus-mode class on the <body>. I’ve intentionally omitted this action when on the tlemail element since it’s a text input and it doesn’t make sense to invoke the action when the user is typing something in it.

The CSS implementation

Once the focus-mode is added to the <body>, we can further manipulate the article container and its content based on that.

For instance, we want to blur a few of the elements of an article when the focus-mode class is activated. Here’s how I did it.

.focus-mode .post .entry :where(p, pre, li, img, div) {
  opacity: .6;
  filter: blur(2px);
  transition: 480ms;
  transition-property: opacity, filter;
}

As you can tell, I chose the post class because that’s where the content of the article lies. And then selected the items (that I wanted to get blurred) using the :where() pseudo-class function.

The blur effect is achieved using the combination of the opacity and filter properties. To make the transition to “focused mode” smooth, I applied the transition and transition-property properties with desired values.

Finally, when the user hovers over a certain element, it should get unblurred. Here’s how I did it.

.focus-mode .post .entry :where(p, pre, li, img, div):hover {
    opacity: 1;
    filter: none;
}

And that’s about it! A simple “focused reading” mode is ready in a cinch!

👋 Hi there! I'm Amit. I write articles about all things web development. If you like what I write and want me to continue doing the same, I would like you buy me some coffees. I'd highly appreciate that. Cheers!

Comments?