logo My Digital Garden

Excerpt

By James Kolean on Jan 16, 2023
Demo: https://codepen.io/jameskolean/pen/GRBMEqG
CSSJavaScriptTips
banner

I got used to Gatsby providing Excerpts from GraphQL. Many CMS do the same. However, I recently converted my Gatsby site to Astro and want this functionality back. A LogRocket article has some techniques to accomplish this. For this article, I will create a Codepen based on that article so I can easily reference it in the future.

Ideally, I want a solution to be as simple as possible. A pure CSS solution would is preferred. A bit of Javascript is the next best option. I would rather not have to pull in a library but let’s look at the trade-offs.

Single Line CSS

To truncate a single line, just add this class.

.single-line-css {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

This solution falls short since it only works for a single line and doesn’t respect work boundaries.

Multiline CSS

.multi-line-css {
    overflow: hidden;
    text-overflow: ellipsis;
    max-height: 2rem;
    line-height: 1rem;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    text-overflow: ellipsis;
    display: block;
}

This solution is closer, but the ellipsis is missing.

Javascript

It looks like we need to reach for Javascript.

function truncate(words, maxlength) {
    return `${words.slice(0, maxlength)} …`;
}
const excerptElement = document.getElementById('js-excerpt')

const excerpt = excerptElement.innerText
excerptElement.innerText = truncate(excerpt, 200)

This solution is close, but I want to split on a word boundary. We can fix that with a bit more complicated javascript.

function smartTruncate(words, maxlength) {
    if (words.length <= maxlength) {
        return words;
    }
    if (/\s/.test(words[maxlength])) {
        return `${words.slice(0, maxlength)} …`;
    }
    const positionOfLastWhiteSpace = words.slice(0, maxlength).search(/ [^ ]*$/);
    return `${words.slice(0, positionOfLastWhiteSpace)} …`;
}
© Copyright 2024 Digital Garden cultivated by James Kolean.