I’ve been running this blog for about five years, and during that time, it’s undergone several transformations. Initially, it was built with plain Markdown, HTML, and CSS. Over time, I experimented with various frameworks before finally settling on Tailwind CSS. The blog has been using Tailwind for a while now, and I’m happy with the results. In addition to Tailwind, I’ve incorporated other tools that enhance the blog’s functionality and aesthetics, such as Pygments for syntax highlighting and Medium Zoom for an interactive image zooming experience. Now that I've settled on a stack that I'm happy with, I thought it would be a good idea to document it. This post will cover the tools I use for my blog, including Tailwind, Pygments, Medium Zoom, and other tips & tricks.
Tailwind
Tailwind is a utility first CSS framework that is very popular. It is the best framework by far for me that uses plain HTML and CSS which I use for my website since I use Django and Wagtail. The framework provides also provides plugins for various things such as typography which we use in the blog for Markdown text.
The Tailwind setup I use is the following:
module.exports = {
theme: {
extend: {
fontFamily: {
sans: ['Noto Sans', 'Inter var'],
},
},
},
plugins: [
require('@tailwindcss/forms'),
require('@tailwindcss/typography'),
require('@tailwindcss/line-clamp'),
require('@tailwindcss/aspect-ratio'),
require('daisyui'),
]
}
The most relevant plugins for Markdown are @tailwindcss/typography
and daisyui
The typography
plugin is used for styling the Markdown text. The daisyui
plugin provides a component library for Tailwind and custom styling for Tailwind. The typography
plugin is documented here.
The usage of the typography plugin is as follows:
<article class="prose font-['Noto_Sans']">{{ page.body|markdown }}</article>
Note: The font-['Noto_Sans']
class is used to set the font for the Markdown text. The prose
class is used to style the Markdown text. The syntax {{ page.body|markdown }}
is used to render the Markdown text in the Django template.
The font comes from Google Fonts and is imported in the base.html
file:
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans:ital,wght@0,100..900;1,100..900" rel="stylesheet" />
With the above Tailwind/DaisyUI setup any text that has the prose
class will be styled according to the Tailwind typography plugin which is great for Markdown text. It provides a nice and clean look for the blog posts and is minimal effort to integrate it.
Pygments
Pygments is a syntax highlighting tool that is used to highlight code snippets in the blog posts. It supports all languages and has several themes. To generate Pygments CSS you'll use the following command:
pygmentize -f html -a .codehilite > <my_directory>/pygments.css>
The generated CSS file can be included in the Django template to style the code snippets. The CSS file is included in the blog.html
file:
<link rel="stylesheet" href="{% static 'css/pygments.css' %}" />
The code snippets are styled using the codehilite
class:
<pre><code class="codehilite">print("Hello, World!")</code></pre>
However, for a large Markdown file, it is better to use the markdown
library in Python to render markdown
. The Python library is a Python implementation of John Grueber's markdown
which converts markdown
to html
. The markdown
library supports the codehilite
extension which can be used to highlight code snippets. The markdown
library can be used as follows:
markdown.markdown(
markdown_text, extensions=["extra", "codehilite", "tables"]
)
The above will transform the markdown_text
to html
and highlight the code snippets using the codehilite
extension. The tables
extension is used to render tables in the markdown
text. This is what the wagtail-markdown
library does under the hood when you use the markdown
filter in the Django template, and you can do the same in any of your projects.
Theming
Pygments also supports several themes. I prefer the github-dark
theme to align my blog with GitHub's theming. You can generate a CSS file for a specific theme using the following command:
pygmentize -S github-dark -f html -a .codehilite > <my_directory>/pygments.css
As you can see all code snippets in this blog are styled using Pygments' with the GitHub theme.
Medium Zoom
Medium Zoom is a JavaScript library that is used to zoom images on the blog. It works by zooming the image when it is clicked. This allows us to have large images in blog posts and any time we click it, we will see all details. It really works great! Adding it to your blog is simple, you just need to include the library in the HTML file and then initialize it for the images you want to zoom. The following is an example of how to include the library and initialize it:
<script src="https://cdnjs.cloudflare.com/ajax/libs/medium-zoom/1.0.6/medium-zoom.min.js"
integrity="sha512-N9IJRoc3LaP3NDoiGkcPa4gG94kapGpaA5Zq9/Dr04uf5TbLFU5q0o8AbRhLKUUlp8QFS2u7S+Yti0U7QtuZvQ=="
crossorigin="anonymous"
referrerpolicy="no-referrer"></script>
<script>
const images = Array.from(document.querySelectorAll(".prose img"));
images.forEach(img => {
mediumZoom(img, {
margin: 0,
/* The space outside the zoomed image */
scrollOffset: 40,
/* The number of pixels to scroll to close the zoom */
container: null,
/* The viewport to render the zoom in */
template: null /* The template element to display on zoom */
});
});
The prose
class is used to select the images in the Markdown text. The prose
class is used to style the Markdown text. The img
tag is used to select the images in the Markdown text. The mediumZoom
function is used to initialize the zoom for the images. If you do not use the prose
class you need to select the images to zoom using a different way.
You can click on the image below from my Comprehensive Kubernetes Autoscaling Monitoring with Prometheus and Grafana to see the zoom in action:
Conclusion
This post covered the tools I use for my blog, including Tailwind, Pygments, Medium Zoom, and other tips & tricks. This is the stack I use for my blog, and I'm quite happy with it. It is minimal compared to all the custom HTML and CSS I used to write, and it is easy to maintain and implement.