tl;dr summary: jump to the solution down below for a neat trick.

the problem

as i was porting one of my old pages to Hugo, i encountered and unexpected snag. the page contained an image which i wanted to appear on the page centered (< gasp > fancy that!). sounds like a 16-character problem solved straight out of muscle memory, right? not quite.

the philosophical angle

the thing is, that Hugo is mainly - but not only - geared towards writing content in extended Markdown. in fact, one of the major selling points of static blog/content generators like Jekyll and Hugo is their proclaimed ability to let you “Blog Like a Hacker” 1, not “blog like an underpaid web designer”. so falling back to HTML would be a cop-out, but unfortunately Markdown syntax itself has no means of positioning images. the Law of Leaky Abstractions rears its ugly head again…

the official Markdown philosophy stance on the subject of formatting is… conflicted. it starts out with a bang:

A Markdown-formatted document should be publishable as-is, as plain text, without looking like it’s been marked up with tags or formatting instructions. […] Markdown’s formatting syntax only addresses issues that can be conveyed in plain text.

which i can totally relate to: while i’m writing and re-reading the content i don’t want to constantly tear through swathes of machine-readable gobbledygook. but then this philosophy fizzles out with a whimper:

For any markup that is not covered by Markdown’s syntax, you simply use HTML itself.

ending up with the exact opposite of the original intent. oh well, that’s philosophy for you.

Hugo authors are acutely aware of the problem, and so Hugo does come with a solution of sorts: “shortcodes” (and {{ <figure> }} shortcode in particular). this is a powerful concept and i’ve seen people really go to town with it, even on the subject of images.

unfortunately, this approach has two drawbacks that i take issue with. for one thing, i’m not a web designer, nor do i plan to become one. for me Hugo, and the content engines i’ve been using before it, is but a means to an end. being back to square one reading swathes of gobbledygook intended for a different kind of parser instead of reading my content is not much of an improvement.

the other drawback stems from the “content engines i’ve been using before” Hugo remark above. formats like Markdown, rST and Textile are fairly ubiquitous and many static blog engines support each. Hugo’s shortcodes, on the other hand, are Hugo-specific and are apparently rooted fairly deep in Go’s standard text templating. if for some reason i’ll be compelled to move to a new engine again, i’ll be facing the unappealing prospect of having to fix a whole bunch of posts. “vendor lock-in” might sound a little harsh, but i value my freedom.

now, don’t get me wrong - shortcodes seem like a pretty good solution for the Hugo blog templates code, i.e. for the all the other stuff, but not for the content i actually care about, and some of which i’ve been dragging around with me for many years.

the solution

in the end, after some energetic googling i did cobble together something that gets the job done with minimal markup and no extraneous tags in the content.

to be able to center images in a Hugo-based blog or float them left/right (read: align left/right with text wrapping around them ), add the following to your CSS (typically under static/css/ on your side, or wherever the theme you’re using keeps its own stylesheets if you’re hacking the theme CSS directly):

img[src$='#center']
{
    display: block;
    margin: 0.7rem auto; /* you can replace the vertical '0.7rem' by
                            whatever floats your boat, but keep the
                            horizontal 'auto' for this to work */
    /* whatever else styles you fancy here */
}

img[src$='#floatleft']
{
    float:left;
    margin: 0.7rem;      /* this margin is totally up to you */
    /* whatever else styles you fancy here */
}

img[src$='#floatright']
{
    float:right;
    margin: 0.7rem;      /* this margin is totally up to you */
    /* whatever else styles you fancy here */
}

then, inside your Markdown content, pull in the images as follows:

![your_img](/img/your_img.png#center)
![your_img](/img/your_img.png#floatleft)
![your_img](/img/your_img.png#floatright)

which should result in them being positioned correspondingly:

ebadf ebadf ebadf

so, we’re down to 7 characters of overhead to center an image, with nary a tag in sight - not too bad! i also suspect that this will work in some of the other Markdown based site generators (Jekyll?), though i gaven’t tested it anywhere else.

i encountered the idea for this hack (though not for the centering - that took some extra googling) over yonder. so, thanks, stiobhart, it did prove to be a “handy tip for other folks”!

the rant

incidentally, it was about 20 years ago that Netscape 3.0 added support for the upcoming HTML 3.2, centering images on web pages became a solved problem, and <center>/align=center got ingrained in my muscle memory. having to waste time on looking for any solution to this non-problem again, 20 years later, after moving my blog to Hugo was a bit of a disappointment… but i’ll touch on the topic of Hugo documentation some other time.


  1. i’ll bet Tom is still chuckling about that one… [return]