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 for example:

  1. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam suscipit, nunc ut accumsan pulvinar, tortor odio pharetra sem, quis pretium lacus felis sit amet libero. Ut posuere ante vel velit laoreet rutrum. Suspendisse mi nulla, luctus nec tincidunt elementum, sodales sed tellus. Nunc vel rutrum quam, ut elementum orci.
  2. In pharetra turpis eu ipsum dignissim, pharetra accumsan quam vulputate. Duis commodo in nisi vitae interdum. Phasellus vitae blandit leo. Sed hendrerit massa eu metus vehicula gravida.
  3. Praesent non orci blandit, consectetur lacus a, blandit ligula. Donec pellentesque varius ultricies. Proin in mattis elit. Nulla non lacinia ligula. Mauris mattis tortor eu nisl imperdiet, id viverra erat efficitur.

It’s just a huge block of text and hard to tell where each item begins and ends. 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 limited knowledge of 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