Bootstrap Style Tables in Hugo (without bootstrap...)

Thu, Mar 10, 2022 4-minute read

Tables in Markdown are a bit of an anomaly that requires a mish-mash of hypens and pipes. You can get the basics from this article at markdownguide. By default, though, how these then render will depend on your template (and the configured CSS) but it’s reasonable to say there’s a chance the tables will look a bit shit.

What if we could have swanky looking tables à la bootstrap? Yep, but what if you don’t actually use bootstrap in your theme? You could just use it, but this is almost certainly going to interfere with at least some of your other styling. So what if you could have bootstrap style tables but without actually having bootstrap? Well, yep, that’s doable in two-ish, steps.

Step 1: Get the bootstrap table styling

First thing you need is the actual bootstrap styling, which I got from this gist:

.table {
  width: 100%;
  max-width: 100%;
  margin-bottom: 1rem;
}

.table th,
.table td {
  padding: 0.75rem;
  vertical-align: top;
  border-top: 1px solid #eceeef;
}

.table thead th {
  vertical-align: bottom;
  border-bottom: 2px solid #eceeef;
}

.table tbody + tbody {
  border-top: 2px solid #eceeef;
}

.table .table {
  background-color: #fff;
}

.table-sm th,
.table-sm td {
  padding: 0.3rem;
}

.table-bordered {
  border: 1px solid #eceeef;
}

.table-bordered th,
.table-bordered td {
  border: 1px solid #eceeef;
}

.table-bordered thead th,
.table-bordered thead td {
  border-bottom-width: 2px;
}

.table-striped tbody tr:nth-of-type(odd) {
  background-color: rgba(0, 0, 0, 0.05);
}

.table-hover tbody tr:hover {
  background-color: rgba(0, 0, 0, 0.075);
}

.table-active,
.table-active > th,
.table-active > td {
  background-color: rgba(0, 0, 0, 0.075);
}

.table-hover .table-active:hover {
  background-color: rgba(0, 0, 0, 0.075);
}

.table-hover .table-active:hover > td,
.table-hover .table-active:hover > th {
  background-color: rgba(0, 0, 0, 0.075);
}

.table-success,
.table-success > th,
.table-success > td {
  background-color: #dff0d8;
}

.table-hover .table-success:hover {
  background-color: #d0e9c6;
}

.table-hover .table-success:hover > td,
.table-hover .table-success:hover > th {
  background-color: #d0e9c6;
}

.table-info,
.table-info > th,
.table-info > td {
  background-color: #d9edf7;
}

.table-hover .table-info:hover {
  background-color: #c4e3f3;
}

.table-hover .table-info:hover > td,
.table-hover .table-info:hover > th {
  background-color: #c4e3f3;
}

.table-warning,
.table-warning > th,
.table-warning > td {
  background-color: #fcf8e3;
}

.table-hover .table-warning:hover {
  background-color: #faf2cc;
}

.table-hover .table-warning:hover > td,
.table-hover .table-warning:hover > th {
  background-color: #faf2cc;
}

.table-danger,
.table-danger > th,
.table-danger > td {
  background-color: #f2dede;
}

.table-hover .table-danger:hover {
  background-color: #ebcccc;
}

.table-hover .table-danger:hover > td,
.table-hover .table-danger:hover > th {
  background-color: #ebcccc;
}

.thead-inverse th {
  color: #fff;
  background-color: #292b2c;
}

.thead-default th {
  color: #464a4c;
  background-color: #eceeef;
}

.table-inverse {
  color: #fff;
  background-color: #292b2c;
}

.table-inverse th,
.table-inverse td,
.table-inverse thead th {
  border-color: #fff;
}

.table-inverse.table-bordered {
  border: 0;
}

.table-responsive {
  display: block;
  width: 100%;
  overflow-x: auto;
  -ms-overflow-style: -ms-autohiding-scrollbar;
}

.table-responsive.table-bordered {
  border: 0;
}

Obviously you don’t get any of the extra dynamic gubbins you get like when you use actual bootstrap, but I’ll assume you’re OK with that. Save that CSS in to a file, say tables.css and save it in to your themes > theme > assets > css directory.

You now need to amend your theme to actually import the CSS file. There are multiple ways of doing it, but the easiest is probably a good ol’ fashioned <link rel> in the <head> section of your template. So find where that’s defined - possibly a partial called header.html (or similar) in your theme > layouts > partials directory, then tell it to load it:

 {{ $tableStyles := resources.Get "css/tables.css" | resources.Minify | resources.Fingerprint }}
  <link
    rel="stylesheet"
    href="{{ $tableStyles.RelPermalink }}"
    integrity="{{ $tableStyles.Data.Integrity }}"
    crossorigin="anonymous"
    media="screen"
  />

If you now rebuild your site, you should see it referenced in the source, although this directive will minify it and add that no-cache fingerprint to it.

Time for step 2.

Step 2: Use the styling

You’re going to create an additional partial called, say, table.html and pop that in your layout > partials folder. In the file, create:

{{ $htmlTable := .Inner | markdownify }}
{{ $class := .Get 0 | default "" }}
{{ $old := "<table>" }}
{{ $new := printf "<table class='%s'>" $class }}
{{ $htmlTable := replace $htmlTable $old $new }}
{{ $htmlTable | safeHTML }}

This does replacey-magic to actually apply the styling to your table. You just need to append some additional fluff to your table call:

| Col 1 | Col 2  |
| :-:   | ------ |
| hello | world! |

wrap it with:

{{< table \"table table-striped table-bordered\" >}}
| Col 1 | Col 2  |
| :-:   | ------ |
| hello | world! |
{{< /table >}}

And you should end up with something like this:

 
 
 


Col 1 Col 2
hello world!

Lovely. Step 2 from here.

Posts in this Series