Styling Hugo Code Blocks
Styling code blocks in Hugo get a little crazy. Here’s how I went about styling them.
Types of Code Blocks
Content in Hugo can generate 6ish types of code blocks.
-
Inline Code
This style is for simple highlights within some other text.
You write it like this:
Inline code is written with `backticks`.
The HTML looks like this:
<p>Inline code is written with <code>backticks</code>.</p>
And the final output looks like this:
Inline code is written with
backticks
. -
Unhighlighted Blocks
Unhighlighted code blocks are the standard three-backticks blocks in normal Markdown.
You write it like this:
``` this kind of code block is great for ascii art ```
The HTML looks like this
<pre tabindex="0"> <code>this kind of code block is great for ascii art</code> </pre>
And the final output looks like this:
this kind of code block is great for ascii art
-
Highlighted Blocks: Recognized
This is where it starts to get a bit messy
You write it like this:
```lua print("hello world") ```
The HTML looks like this:
<div class="highlight"> <pre tabindex="0" style="color:#ebdbb2;background-color:#282828;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"> <code class="language-lua" data-lang="lua"> <span style="display:flex;"><span>print(<span style="color:#b8bb26">"hello world"</span>)</span></span> </code> </pre> </div>
And the final output looks like this:
print("hello world")
-
Highlighted Blocks: Table Line Numbers
You write it like this:
```lua {linenos=table,hl_lines=[4,"1-2"],linenostart=199} function hello_world(name) print("Hi "..name) end hello_world("Dave") ```
The HTML looks like this:
<div class="highlight"> <div style="color:#ebdbb2;background-color:#282828;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;"> <table style="border-spacing:0;padding:0;margin:0;border:0;"> <tbody> <tr> <td style="vertical-align:top;padding:0;margin:0;border:0;"> <pre tabindex="0" style="color:#ebdbb2;background-color:#282828;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;"> <code> <span style="background-color:#3d3d3d"> <span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#756d59">199</span> </span> <span style="background-color:#3d3d3d"> <span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#756d59">200</span> </span> <span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#756d59">201</span> <span style="background-color:#3d3d3d"> <span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#756d59">202</span> </span> <span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:0.4em;padding:0 0.4em 0 0.4em;color:#756d59">203</span> </code> </pre> </td> <td style="vertical-align:top;padding:0;margin:0;border:0;;width:100%"> <pre tabindex="0" style="color:#ebdbb2;background-color:#282828;-moz-tab-size:4;-o-tab-size:4;tab-size:4;display:grid;"> <code class="language-lua" data-lang="lua"> <span style="display:flex; background-color:#3d3d3d"> <span> <span style="color:#fe8019">function</span> <span style="color:#fabd2f">hello_world</span>(name) </span> </span> <span style="display:flex; background-color:#3d3d3d"> <span> print( <span style="color:#b8bb26">"Hi "</span> <span style="color:#fe8019">..</span>name) </span> </span> <span style="display:flex;"> <span> <span style="color:#fe8019">end</span> </span> </span> <span style="display:flex; background-color:#3d3d3d"> <span></span> </span> <span style="display:flex;"> <span>hello_world( <span style="color:#b8bb26">"Dave"</span>) </span> </span> </code> </pre> </td> </tr> </tbody> </table> </div> </div>
(There’s a lot going on. the important bits are that the
<code>
with the data-lang is buried inside the table, there are two sets of<pre><code>…</code></pre>
tags, there are now two<div>
s before the<table>
, and also there’s a<table>
now. )And the final output looks like this:
199 200 201 202 203
function hello_world(name) print("Hi "..name) end hello_world("Dave")
-
Highlighted Blocks: Unrecognized
You write it like this:
```thisLanguageDoesNotExist Who knows what this is supposed to do. ```
The HTML looks like this:
<pre tabindex="0"> <code class="language-thisLanguageDoesNotExist" data-lang="thisLanguageDoesNotExist">Who knows what this is supposed to do.</code> </pre>
And the final output looks like this:
Who knows what this is supposed to do.
It’s extremely similar to the Unhighlighted block, but the
<code>
still has thedata-lang
attribute -
Inline Highlighted Code
Hugo comes with a shortcode to do syntax highlighting on inline code.
You write it like this:
Inline highlighted code → {{< highlight lua "hl_inline=true" >}}if true print("hello world!") end{{< /highlight >}}.
The HTML looks like this:
<p>Inline highlighted code looks like this → <code class="code-inline language-lua"> <span style="color:#fe8019">if</span> <span style="color:#fe8019">true</span> print(<span style="color:#b8bb26">"hello world!"</span>) <span style="color:#fe8019">end</span> </code>.</p>
And the final output looks like this:
Inline highlighted code looks like this →
if true print("hello world!") end
.It renders a similar kind of output as the unhighlighted inline code type, just simple set of
<code>
tags and some<spans>
for the actual highlighting. But unlike the other highlighted code blocks, this one does not have thehighlight
class, or thedata-lang
attribute.
These are all structurally pretty different. Sometimes the top level is a <div>
, sometimes it’s a <pre>
, and sometimes you’ll have multiple <pre>
s and <div>
s within a block.
CSS
Getting a consistent look out of all of these types a few iterations, but I came up with something pretty clean. Here’s a generic version of the CSS I use on this website to style my code blocks. Feel free to copy and modify this to fit your Hugo website.
|
|
The syntax highlighting itself comes from Hugo’s Highlighter system, which uses Chroma.
This post was originaly written with Hugo 0.141 in mind.
Future versions of Hugo may generate a different HTML structure, which may break this CSS.
If by chance you want to see what my CSS actually looks like, you can find it here.