James Zhan in real life.

Responsive List Spacing for Bear Blog

My blog has a ton of lists, some of which contain only 1 line per item while others can have more than 1 line per item. I find that for the latter, the list quickly becomes a dense block of text and lacks a visual separation between each item. Take this list from my commentary on my employer’s return-to-office mandate for example:

  1. I’m not saying everyone should have the option to work from home (WFH) no matter what. For positions that require the employees’ physical presence on-site regularly, like a circulation clerk at a library or a construction worker, then obviously that makes total sense. No one is saying you should try to do these jobs from home; don’t be obtuse.
  2. I have nothing against the act of “going into the office” itself; what I have issue with is, specifically, being forced to go into office when your job is not dependent on you being physically in the office.
  3. I’m using the terms “WFH” and “hybrid work” interchangeably here. When I say “WFH,” I’m not saying 100% remote work. I’m referring to the flexibility of WFH when an employee’s tasks can be completed without them being in the office.

It’s just a huge block of text, and this is only 3 items. My Canada Day celebration post has 12. I use lists to make things easier to read and follow but the one above is anything but.

The easiest way to add spacing to a list in Bear Blog is to add an empty line between each bullet:

- list

- list

- list

Bear Blog will render that as:

That was what I was doing but I quickly found that I didn’t like that solution because I write all my blog posts in iA Writer and I don’t want so much spacing while drafting in Markdown. I started manually adding the spaces after I copied the final drafts to Bear Blog’s editor and I’m just too lazy to do that for every list going forward. I scoured Google for a solution to no avail so eventually, I said FINE and reluctantly resorted to Claude (I have no background in HTML/CSS/JS so I simply cannot write the code/script myself). Note that this post—and all the non-code, written content on this blog—is written, edited, proofread and formatted 100% by me, though.

Claude gave me some CSS code and a JS script to use, which I tested in CodeRunner offline with my own blog to make sure they worked before making it live.

I wanted to share it in case it helps someone, but please DO NOT use it without testing it first. I don’t know anything about JavaScript and so while the script works for my blog, it might not for yours. Please test it before using!

What the CSS + script does

Demo (this probably won’t work if you’re reading this on an RSS reader):

If I type this in the Bear Blog editor:

- line
- line
- line

I will get:

The spacing of the list is the same as the line-height for the post body, which is typically set in main {…}.

If I type this:

- line
- line line line line line line line line line line line line line line line line line line line line line 
- line

I will get:

The spacing is still the same as the line-height for the post body because only 1 item is longer than 1 line.

If I type this:

- line
- line line line line line line line line line line line line line line line line line line line line line 
- line line line line line line line line line line line line line line line line line line line line line 
- line

I will get:

The spacing becomes more roomy and is set by a dedicated value in the global CSS (more below).

To see more examples of this script in practice, you can check out my list-heavy pages:

How to implement

In your global CSS, add:

    main ul.multiline > li,
    main ol.multiline > li { margin-bottom: 0.6em; } /* this controls the spacing when an item in a list is longer than 1 line */

In the footer directive, add:

<script>
  // responsive list spacing
(function () {
  function markMultiline() {
    document.querySelectorAll('main ul, main ol').forEach(list => {
      if (list.closest('.footnotes')) return;

      const items = [...list.children].filter(el => el.tagName === 'LI');

      const wrapCount = items.filter(li => {
        if (li.querySelector('ul, ol')) return false;
        const cs = getComputedStyle(li);
        let lh = parseFloat(cs.lineHeight);
        if (isNaN(lh)) lh = parseFloat(cs.fontSize) * 1.2;
        return li.offsetHeight > lh * 1.5;
      }).length;

      list.classList.toggle('multiline', wrapCount >= 2);
    });
  }
  markMultiline();
  document.fonts.ready.then(markMultiline);
})();
  
</script>

IMPORTANT NOTES:

That’s it. If you’re a programmer and have a better way to do this, or can write a better script than what Claude gave me, please let me know! If you end up giving it a try and find issues, feel free to contact me or leave a message on my guestbook! Hope it turns out to be useful to someone :)

|


Reply via email. Subscribe to my blog via email or RSS feed.

#rabbit-holes