Aleksandr Hovhannisyan
Posted on January 1, 2020
Note: This is a syndicated post. If you'd like to, you can view the original on my dev blog.
It's a common practice in blogs to make a heading a link; this makes it easier for users to share a specific part of your content without linking to the entire post.
How can we create heading links in Jekyll without losing our sanity and with zero lines of JavaScript?
Answer: with the power of Jekyll includes!
Jekyll Heading Anchors with Includes
Create a file named linkedHeading.html
in your _includes
folder. Here's what we want to do:
- Create a dynamic heading that can be any level we want.
- Give the heading an ID that we can reference.
- Nest an anchor inside that heading that references the ID from above.
- Fill the heading itself with some text.
With Liquid and Jekyll includes, it's super simple to create linked headings. Here's the markup:
{% assign heading = include.heading %}
<h{{ include.level }} id="{{ heading | slugify }}" class="linked-heading">
<a href="#{{ heading | slugify }}">#</a> {{ heading }}
</h{{ include.level }}>
Simply use the following in your markdown to create a heading anchor in Jekyll:
{% include linkedHeading.html heading="My Heading" level=someNumber %}
Short and sweet! And much more legible than copy-pasting a bunch of heading tags and anchors. Plus, you don't have to introduce any unnecessary dependencies, JavaScript, or gems to get this done.
Note: If instead you want to link the entire heading, simply move
{{ heading }}
into the anchor itself.
If you're curious, here's how that works:
We pass in a string to
heading
, which we access viainclude.heading
. We assign this to a local variable so we don't have to keep repeatinginclude.heading
.Using Liquid objects, we specify the level of the heading dynamically with
h{{ include.level }}
. So if we pass inlevel=2
, then we'll geth2
. Do this for both the opening and closing tags.Give the h tag an ID. The ID will be the string we passed in, but slugged. You can also give it a class name if you want to style it later.
Create a nested anchor that points to the same slug:
href="#{{ heading | slugify }}"
. The anchor text can be anything you want. I was inspired by the CSS Tricks website and used a hashtag.
Then, after the anchor, we simply put a space followed by our unformatted heading string.
Sticky Navbar and Linked Headings
If you have a sticky/fixed navbar like I do on my personal site, you may run into a problem where your heading anchors get stuck under the navbar when you click them.
Fortunately, the fix is a neat little trick: a negative top margin combined with a positive top padding. I like to leave about a 40px
difference between the two for spacing:
h2 {
margin-top: -50px;
padding-top: 90px;
}
My navbar is 64px
tall, so I found that these two numbers work best. Feel free to play around with them. And of course, you can also apply this to other heading levels in case you want to link to them as well.
And That's It!
The best part is that you can pick which headings you want to link to.
I hope you found this post helpful 🙂
Posted on January 1, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.