Carbon: Basic Syntax Highlighting with Zero Overhead Using JavaScript

👋 Ciprian on Tuesday, May 11, 2021 in Blog, Featured, JavaScript
Last modified on Tuesday, May 11, 2021

Learn JavaScript by example. Code snippets, how-to's and tutorials. Try now!

Carbon: Basic Syntax Highlighting
Carbon: Basic Syntax Highlighting

If you have ever used PrismJS or CodeMirror or any other syntax highlighter solution, you’ll know it adds lots of dependencies bases on what language support you need. If you need HTML, JS and PHP support, you’ll add at least 2 JavaScript files and 2 CSS files. If you have lots of articles with code areas, it quickly adds up and impacts your page loading experience.

I have come up with a simple solution for styling a <pre> preformatted tag and adding line numbers. It’s enough for what I need, and it’s 273 bytes gzipped (424 bytes uncompressed).

Note that the code content is selectable and the line numbers are not, which makes it easy to copy the code. Also, it supports multiple preformatted areas on the same page.

Here’s the basic JavaScript code:

(function() {
    const pre = document.querySelectorAll('pre'),
          pl = pre.length;

    for (let i = 0; i < pl; i++) {
        pre[i].innerHTML = `<span class="line-number"></span>${pre[i].innerHTML}`;
        let num = pre[i].innerHTML.split(/\n/).length;
        for (let j = 0; j < num; j++) {
            let line_num = pre[i].getElementsByTagName('span')[0];
            line_num.innerHTML += `<span>${(j + 1)}</span>`;
        }
    }
})();

The JavaScript code above splits the <pre> content line by line and adds a line number in front of it. I am using a Flex CSS layout to make everything flexible.

Here are the CSS styles:

pre.carbon {
    display: flex;
    background-color: #eee;
    overflow: auto;
    margin: 0 0 1em;
    padding: .5em 1em;
}

pre.carbon code,
pre.carbon .line-number {
    font: normal normal 14px/16px "Cascadia Code", "Courier New", Courier, Monospace;
    color: #000000;
    display: block;
}

pre.carbon .line-number {
    margin: 0 1em 0 -1em;
    border-right: 1px solid #666666;
    text-align: right;
    user-select: none;
}

pre.carbon .line-number span {
    display: block;
    padding: 0 .5em 0 1em;
}

And here’s an HTML sample:

<pre class="carbon"><code>&lt;div class="example"&gt;
    &lt;span&gt;Lorem ipsum dolor sit amet...&lt;/span&gt;
&lt;/div&gt;</code></pre>

<pre class="carbon"><code>(function() {
    let s = document.createElement('script');

    s.src = 'carbon.min.js';
    s.id = 'carbon';
    s.type = 'text/javascript';
    s.async = true;

    document.body.appendChild(s);
})();</code></pre>

Now, see the same sample above in a Carbon preformatted area:

<div class="example">
    <span>Lorem ipsum dolor sit amet...</span>
</div>
(function() {
    let s = document.createElement('script');

    s.src = 'carbon.min.js';
    s.id = 'carbon';
    s.type = 'text/javascript';
    s.async = true;

    document.body.appendChild(s);
})();

Pretty awesome, right?

Find more JavaScript tutorials, code snippets and samples here or more jQuery tutorials, code snippets and samples here.

👋 Added by Ciprian on Tuesday, May 11, 2021 in Blog, Featured, JavaScript. Last modified on Tuesday, May 11, 2021.

Leave a Reply

You have to agree to the comment policy.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Privacy Policy