Syntax highlight any block on a Web Page
By Flavio Copes
Learn how to syntax highlight any element on a web page with highlight.js and hljs.highlightElement, even when your code is not inside a code tag.
You can syntax highlight any element on a page, not just code tags, using highlight.js and its hljs.highlightElement() function. Here’s how I found out.
I had the need to add syntax highlighting to a page, but I didn’t have the luxury of changing the markup.
Most syntax highlighting libraries, like Prism.js, force you to use a fixed structure like this:
<pre>
<code class="language-js">
...
</code>
</pre>
Citing this:
Prism does its best to encourage good authoring practices. Therefore, it only works with
elements, since marking up code without aelement is semantically invalid.
It’s all nice and idealistic and all but I had my code in a div from an outside source. You force me that markup, but I don’t have that.
I finally found https://highlightjs.org/ that lets me apply syntax highlighting to any element I want on the page.
How do you set it up?
First load the library and a theme stylesheet, for example from a CDN:
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css">
<script
src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js">
</script>
The stylesheet is what gives keywords and strings their colors. Pick any theme you like, github.min.css is just one of many.
Then select the elements you want to highlight, and call hljs.highlightElement() on each one:
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.my-code-div').forEach((el) => {
hljs.highlightElement(el)
})
})
That’s it. The library wraps the tokens it finds in span elements, and the theme CSS colors them.
Notice we wait for DOMContentLoaded. If you run the code before the page is parsed, querySelectorAll() finds nothing and nothing gets highlighted.
What about the language?
By default highlight.js tries to detect the language automatically by analyzing the content.
On short snippets the detection can guess wrong. A few lines of CSS might get highlighted as something else entirely, and the colors look off.
The fix is to tell it the language explicitly, with a class on the element:
<div class="my-code-div language-js">
const total = 42
</div>
When a language-* class is present, highlight.js skips detection and uses that language.
One more thing to watch out for: the element should contain plain text, not HTML markup. If your block contains real tags, highlight.js prints a warning in the console about unescaped HTML, because it can’t tell your markup apart from the code you want highlighted.
Related posts about tools: