UPDATE: Hugo has added a details shortcode in version 0.140.0. If you are just needing a basic details shortcode then use
hugo version
to check what version you are on. The below article implements a slightly more advanced details shortcode, as well as touches on how to style it.
In HTML <detail>
and <summary>
tags can be used to collapse sections of text that a reader can choose to expand.
This is useful to include technical details or other content that not every user may appreciate but the information will be available for those who are interested. These tags, however, do not work natively in markdown meaning Hugo can’t use <detail>
and <summary>
directly but can be used as a shortcode. In this article we will be creating our own details shortcode.
Here is an example of what we will be building:
Details
This is the first paragraph of detailed content. This is the second paragraph of even more detailed content.
- You can also include lists
- Or other markdown elements
Create details.html #
Create the following file in the specified directory relative to your project folder.
layouts/shortcodes/details.html
:
{{- /* Get arguments. */}}
{{- $summary := or (.Get "summary") (T "details") "Details" | .Page.RenderString }}
{{- $altSummary := or (.Get "altSummary") $summary | .Page.RenderString }}
{{- $open := false }}
{{- with .Get "open" }}
{{- if not (eq . false) }}
{{- $open = true }}
{{- end }}
{{- end }}
{{- $attributes := dict }}
{{- range $key, $value := .Params }}
{{- if not (in (slice "summary" "altSummary" "open") $key) }}
{{- $attributes = merge $attributes (dict (string $key) $value) }}
{{- end }}
{{- end }}
{{- /* Render. */}}
<details
{{- if $open }} open {{- end -}}
{{- range $key, $value := $attributes }} {{ $key }}="{{ $value }}"{{- end }}
>
<summary onclick="this.innerHTML = this.parentNode.open ? '{{ $summary }}' : '{{ $altSummary }}';">
{{ if $open }}
{{ $altSummary }}
{{ else }}
{{ $summary }}
{{ end }}
</summary>
{{ .Inner | .Page.RenderString (dict "display" "block") }}
</details>
Arguments: #
When using this shortcode there are several arguments:
summary
(str). Default = “Details:”. This is the text that appears for users to click on.open
(bool). Default =false
. If this argument is specified, and a value other thanfalse
(bool) is provided, then the element will be expanded upon page load.altSummary
(str). Default =summary
. This is the text that appears when the details tag is open. If not provided it will be the same as the summary text.- […params] (object) Additional HTML attributes passed directly to the details element. Such as
class
orname
.
Usage: #
Within your markdown, you can now use this as a shortcode as follows:
{{< details >}}
This is the first paragraph of detailed content.
This is the second paragraph of even more detailed content.
- You can also include lists
- Or other markdown elements
{{< /details >}}
Details
This is the first paragraph of detailed content. This is the second paragraph of even more detailed content.
- You can also include lists
- Or other markdown elements
It is important to remember to call the shortcode, type your text, and then close the shortcode.
Using summary
#
Below is an example with specifying the summary name.
{{< details summary="Super Secret Text" >}}
Enter your super secrets here
{{< /details >}}
Super Secret Text
Enter your super secrets here
Using open
#
Here is an example specifying the content to be expanded when the page loads.
{{< details summary="Super Secret Text" open=true >}}
Oh no, my secrets are out!
{{< /details >}}
Super Secret Text
Oh no, my secrets are out!
Using altSummary
#
The below example specifies an alternate summary for when the details element is open
{{< details summary="Super Secret Text" open=false altSummary="click to close before anyone sees!" >}}
Oh no, my secrets are out!
{{< /details >}}
Super Secret Text
Oh no, my secrets are out!
Using name
#
Below we will specify three details elements, all with the same name
. They can still have different summaries and text within them, however, since they will have the same name only one element will be able to be open at a time.
{{< details summary="Planning" name="name demonstration" >}}
Planning text
{{< /details >}}
{{< details summary="Designing" name="name demonstration" >}}
Designing text
{{< /details >}}
{{< details summary="Implementation" name="name demonstration" >}}
Implementation text
{{< /details >}}
Try opening “Designing” Try opening “Implementation Try opening “Planning”
Planning
Designing
Implementation
As you can see, only one of the “Planning”, “Designing”, “Implementation” elements can be open at the same time.
Additional Usage #
This shortcode has a few additional features:
Specifying named arguments in any order #
The details shortcode can accept any of the named arguments in any order. Such as:
{{< details altSummary="This is my alt summary even though listed first" open=false summary="This is my summary even though listed last" >}}
See, order does not matter when passing named arguments
{{< /details >}}
This is my summary even though listed last
See, order does not matter when passing named arguments
Using only some arguments #
In some of our first examples we used no arguments and later started passing additional arguments. You are able to pass any number of arguments.
{{< details altSummary="Only One Argument" >}}
Here I only passed 1 named argument, the `altSummary`
{{< /details >}}
Details
Here I only passed 1 named argument, the altSummary
Styling #
Since we are able to pass any attribute to the HTML, this includes class
. If you want to add styling to your details elements then you can select them with CSS. To do this you will need to load a CSS stylesheet. Within it you can use the following to select different parts of the details element. Suppose you want to modify my-custom-class
:
/*Target details element*/
details.my-custom-class { }
/*Target summary element*/
details.my-custom-class > summary > * { }
/*Target inner content*/
details.my-custom-class > :not(summary) { }
Using Headers in details elements #
If you intend to use headers in your summaries, then you will want to make the summaries appear inline. This is because headers are block elements that naturally begin on a new line and will appear a line lower than where the details element starts. To fix this for your my-custom-class
you can use the following:
details.my-custom-class > summary > * {
display: inline;
}