Tabs

The tabs codeblock markup makes it possible for you to convert Markdown content into tabs, where users see different content depending on which tab is active.

When used, it inserts an <sl-tab-group> element from Shoelace to the page with named tabs (as <sl-tab> elements) and their content (as <sl-tab-panel> elements) that site visitors can switch between to render different content as needed.

Syntax #

The tabs codeblock supports setting options as either attributes or as YAML in a data block at the start of the codeblock. If you’re using the attribute syntax, the options must be specified on the same line that the codeblock opens on. If you’re using the data syntax, the options must be specified as valid YAML wrapped with three dashes (---) before the rest of the definition.

For more information, see Using Codeblocks in the User Guide.

With Attributes #

``````tabs { [.class [.class]] [#id] [legacy=(true|false)] [preset="preset"] }
```tab { [.class [.class]] [#id] [name="name"] [preset="preset"] }
Markdown to _render_ for the tab
```
``````

With Data #

``````tabs
---
activation: (auto|manual)
class: class
custom: false
id: id
legacy: false
no_scroll_controls: false
placement: (top|bottom|start|end)
preset: preset
standardize_height: false
---

```tab
---
class: class
closable: false
disabled: false
id: id
name: name
preset: preset
---

Markdown to _render_ for the tab
```
``````

Examples #

1. Minimal Definition with Attributes #

This example shows the minimal additional markup needed to render tabs in Platen with attributes on the codeblocks.

Note that the first tab uses an id to set the name. The specified #first-tab is converted into First Tab. For the second tab, the name is passed directly.

Only the first tab gets an ID added to the element.

While you can use attributes with your codeblocks when you want to mostly use the default options, we recommend using the YAML option syntax for a more readable and editable definition.

Markdown Input
``````tabs
```tab { #first-tab }
This content only displays when the first tab is active.
```

```tab { name="Second _Tab_" }
This content only displays when the second tab is active.
```
``````
HTML Output
<sl-tab-group class="platen-tabs"
              placement="top"
              activation="auto"
              noScrollControls="false">
  <sl-tab slot="nav"
          panel="first-tab"
          id="first-tab">
    <span>First Tab</span>
  </sl-tab>
  <sl-tab-panel name="first-tab">
    <p>This content only displays when the first tab is active.</p>
  </sl-tab-panel>
  <sl-tab slot="nav"
          panel="Second Tab">
    <span>Second <em>Tab</em></span>
  </sl-tab>
  <sl-tab-panel name="Second Tab">
    <p>This content only displays when the second tab is active.</p>
  </sl-tab-panel>
</sl-tab-group>
Rendered Output
First Tab

This content only displays when the first tab is active.

Second Tab

This content only displays when the second tab is active.

2. Minimal Definition with YAML Options #

This example shows the minimal additional markup needed to render tabs in Platen with YAML options in the codeblocks.

Note that the first tab uses an id to set the name. The specified #first-tab is converted into First Tab. For the second tab, the name is passed directly.

Only the first tab gets an ID added to the element.

Markdown Input
``````tabs
```tab
---
name: First Tab
---

This content only displays when the first tab is active.
```

```tab
---
name: Second Tab
---

This content only displays when the second tab is active.
```
``````
HTML Output
<sl-tab-group class="platen-tabs"
              placement="top"
              activation="auto"
              noScrollControls="false">
  <sl-tab slot="nav"
          panel="First Tab">
    <span>First Tab</span>
  </sl-tab>
  <sl-tab-panel name="First Tab">
    <p>This content only displays when the first tab is active.</p>
  </sl-tab-panel>
  <sl-tab slot="nav"
          panel="Second Tab">
    <span>Second Tab</span>
  </sl-tab>
  <sl-tab-panel name="Second Tab">
    <p>This content only displays when the second tab is active.</p>
  </sl-tab-panel>
</sl-tab-group>
Rendered Output
First Tab

This content only displays when the first tab is active.

Second Tab

This content only displays when the second tab is active.

3. Full Definition #

This example showcases the available options for tabs. It adds an id to the tab group itself and gives it the example class.

It uses the placement option to put the tabs at the bottom of the content instead of the top. You could also put the tabs before or after the content by setting placement to start or end respectively. For more information, see placement.

It sets the activation to manual, which prevents the tabs from automatically swapping when you use the arrow keys to change the tab you’re focused on. For more information on how activation works, see activation.

It sets no_scroll_controls to false, which is also the default. Because this tab group has too many tabs to fit in the space, the tabs can be scrolled to see the full options by clicking the arrows on either end of the tab list or using the arrow keys on your keyboard. If this option was set to true, you would only be able to use your keyboard to scroll the list. For more information, see no_scroll_controls.

Finally, it sets standardize_height to true, which ensures that the height of the tab panels is made consistent, setting every tab to the same height as the tallest rendered tab.

Markdown Input
``````tabs
---
id: full-tab-definition
class: example
placement: bottom
activation: auto
no_scroll_controls: false
standardize_height: true
---

```tab
---
name: Name-Only Tab
---

This tab only has a name. Because it's the first in the group,
it's displayed by default when the page loads.

It has no other options.
```

```tab
---
id: id-only-tab
---

This tab has only an ID. Note that the ID is added to the tab element
and that the name of the tab is automatically generated as
`Id Only Tab` from the defined id `id-only-tab`.
```

```tab
---
id: name-and-id-tab
name: Tab with `name` & `id`
---

This tab defines both `id` and `name`.

Note that the the ID is added to the `sl-tab` element,
but that the `name` and `panel`
attributes on the `sl-tab-panel` and `sl-tab` elements
are the plain-text of the rendered `name` option.

This also shows that you can use inline Markdown for the `name`
to control how it's displayed without breaking things.
```

```tab
---
name: Tab with a Class
class: example
---

This tab is the first in the group and is displayed by default. It has the
`example` class, which makes the content (describe style).
```

```tab
---
name: Closable Tab
closable: true
---

This tab can be closed, removing it from view until you
refresh the page.
```


```tab
---
id: disabled-tab
disabled: true
---

This tab is disabled. It can't be selected,
so the content is visible in the rendered view.
```
``````
HTML Output
<sl-tab-group class="platen-tabs example"
              id="full-tab-definition"
              placement="bottom"
              activation="auto"
              data-standardize-height="true"
              noScrollControls="false">
  <sl-tab slot="nav"
          panel="Name-Only Tab">
    <span>Name-Only Tab</span>
  </sl-tab>
  <sl-tab-panel name="Name-Only Tab">
    <p>This tab only has a name. Because it&rsquo;s the first in the group,
    it&rsquo;s displayed by default when the page loads.</p>
    <p>It has no other options.</p>
  </sl-tab-panel>
  <sl-tab slot="nav"
          panel="id-only-tab"
          id="id-only-tab">
    <span>Id Only Tab</span>
  </sl-tab>
  <sl-tab-panel name="id-only-tab">
    <p>This tab has only an ID. Note that the ID is added to the tab element
    and that the name of the tab is automatically generated as
    <code>Id Only Tab</code> from the defined id <code>id-only-tab</code>.</p>
  </sl-tab-panel>
  <sl-tab slot="nav"
          panel="Tab with name &amp;amp; id"
          id="name-and-id-tab">
    <span>Tab with <code>name</code> &amp; <code>id</code></span>
  </sl-tab>
  <sl-tab-panel name="Tab with name &amp;amp; id">
    <p>This tab defines both <code>id</code> and <code>name</code>.</p>
    <p>Note that the the ID is added to the <code>sl-tab</code> element,
    but that the <code>name</code> and <code>panel</code>
    attributes on the <code>sl-tab-panel</code> and <code>sl-tab</code> elements
    are the plain-text of the rendered <code>name</code> option.</p>
    <p>This also shows that you can use inline Markdown for the <code>name</code>
    to control how it&rsquo;s displayed without breaking things.</p>
  </sl-tab-panel>
  <sl-tab slot="nav"
          panel="Tab with a Class"
          class="example">
    <span>Tab with a Class</span>
  </sl-tab>
  <sl-tab-panel name="Tab with a Class"
                class="example">
    <p>This tab is the first in the group and is displayed by default. It has the
    <code>example</code> class, which makes the content (describe style).</p>
  </sl-tab-panel>
  <sl-tab slot="nav"
          panel="Closable Tab"
          closable>
    <span>Closable Tab</span>
  </sl-tab>
  <sl-tab-panel name="Closable Tab">
    <p>This tab can be closed, removing it from view until you
    refresh the page.</p>
  </sl-tab-panel>
  <sl-tab slot="nav"
          panel="disabled-tab"
          id="disabled-tab"
          disabled>
    <span>Disabled Tab</span>
  </sl-tab>
  <sl-tab-panel name="disabled-tab">
    <p>This tab is disabled. It can&rsquo;t be selected,
    so the content is visible in the rendered view.</p>
  </sl-tab-panel>
</sl-tab-group>
Rendered Output
Name-Only Tab

This tab only has a name. Because it’s the first in the group, it’s displayed by default when the page loads.

It has no other options.

Id Only Tab

This tab has only an ID. Note that the ID is added to the tab element and that the name of the tab is automatically generated as Id Only Tab from the defined id id-only-tab.

Tab with name & id

This tab defines both id and name.

Note that the the ID is added to the sl-tab element, but that the name and panel attributes on the sl-tab-panel and sl-tab elements are the plain-text of the rendered name option.

This also shows that you can use inline Markdown for the name to control how it’s displayed without breaking things.

Tab with a Class

This tab is the first in the group and is displayed by default. It has the example class, which makes the content (describe style).

Closable Tab

This tab can be closed, removing it from view until you refresh the page.

Disabled Tab

This tab is disabled. It can’t be selected, so the content is visible in the rendered view.

4. Legacy Example #

This example uses the legacy template for rendering the tabs.

With legacy set to true in the attributes or YAML options, Platen renders the Markdown in a <div> HTML container. Each tab is added as an <input> and <label> representing the tab control and a child <div> for the tab content. The Markdown content in each tab is rendered as normal.

This option is included to allow folks to intentionally transition from the legacy implementation to Shoelace, which will become the default in the future. Eventually, the legacy implementation will be removed.

For more information, see Legacy Template.

Markdown Input
``````tabs { #unique-tab-id legacy=true}
```tab { #first-legacy-tab }
This content only displays when the first tab is active.
```

```tab { name="Second _Tab_" }
This content only displays when the second tab is active.
```
``````
HTML Output
<div class="platen-tabs" id="unique-tab-id">
  <input type="radio"
         class="toggle"
         name="tabs-unique-tab-id"
         id="first-legacy-tab"
         checked="checked"/>
  <label for="first-legacy-tab">
    First Legacy Tab
  </label>
  <div class="platen-tabs-content markdown-inner">
    <p>This content only displays when the first tab is active.</p>
  </div>
  <input type="radio"
         class="toggle"
         name="tabs-unique-tab-id"
         id="tabs-unique-tab-id-second-_tab_"/>
  <label for="tabs-unique-tab-id-second-_tab_">
    Second <em>Tab</em>
  </label>
  <div class="platen-tabs-content markdown-inner">
    <p>This content only displays when the second tab is active.</p>
  </div>
</div>
Rendered Output

This content only displays when the first tab is active.

This content only displays when the second tab is active.

Attributes #

class #

Specify any additional classes to insert into the class list for the tabs container element.

By default, the container element has the platen-tabs class. For more information about how classes affect the styling of content in this markup, see Styling.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String

id #

Specify this attribute to add an id to the tabs’ container element.

If you’re using the legacy template, you must specify a value for id either as an attribute or an option. When you do, you’re specifying a unique name for this group of tabs. Specify the unique name for this group of tabs. If you use the legacy template without this value or with a non-unique value, the tab navigation will break unpredictably.

Specify the ID as a bare string without any spaces and with a # prefix, like #my-id

Required: false
Type: String

legacy #

Specify true to use the legacy template for the tabs markup, or false to use the <sl-tab-group> element from Shoelace. If this value isn’t set, Platen uses the value of the platen.markup.tabs.use_legacy setting defined in your site configuration. For more information, see Configuration.

When this setting is true, the following options are ignored:

Specify true or false without wrapping quotes.

Required: false
Type: Boolean

preset #

Specify the name of the preset to use, if any. If the preset is defined in a subfolder, specify the dot-path relative to data/platen/tabs. For example, the preset defined in data/platen/tabs/info/installing would be specified as info.installing.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String

YAML Options #

activation #

Specify the activation mode to use for the tab group. When the tab group is focused, keyboard users can press the kbd:Left and kbd:Right keys to select the desired tab.

When the value of this option is auto, the selected tab is shown immediately.

To require the user to press kbd:Space or kbd:Enter to show the tab, set this value to manual.

If this option isn’t set in the markup, Platen uses the value of the platen.markup.tabs.activation setting defined in your site configuration. The site configuration default is auto. For more information, see Configuration.

This option isn’t valid with the legacy template.

Required: false
Type: Enum
ValidValues:
- auto
- manual

class #

Specify any additional classes to insert into the class list for the tabs container element.

By default, the container element has the platen-tabs class. For more information about how classes affect the styling of content in this markup, see Styling.

If this option isn’t set in the markup, Platen uses the value of the platen.markup.tabs.classes setting defined in your site configuration. The site configuration default is an empty list. For more information, see Configuration.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String

custom #

Specify whether this tabs group should use a custom template instead of the default or legacy template. Set this option to true to use the custom templates stubbed in platen/markup/tabs/templates/custom. That folder has a template for the tab group (group.html) and one for the individual tabs (tab.html). If this value is false, Platen uses the default or (if legacy is true) legacy template.

If this value is a string, Platen uses the value as the name of the folder in platen/markup/tabs/templates to look for the group.html and tab.html templates for rendering the markup.

For more information, see Custom Templates.

Specify true or false without wrapping quotes.

Required: false
Type: Boolean

id #

Specify this option to add an id to the tabs container element.

If you’re using the legacy template, you must specify a value for id either as an attribute or an option. When you do, you’re specifying a unique name for this group of tabs. Specify the unique name for this group of tabs. If you use the legacy template without this value or with a non-unique value, the tab navigation will break unpredictably.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String

legacy #

Specify true to use the legacy template for the tabs markup, or false to use the <sl-tab-group> element from Shoelace. If this value isn’t set, Platen uses the value of the platen.markup.tabs.use_legacy setting defined in your site configuration. For more information, see Configuration.

When this setting is true, the following options are ignored:

Specify true or false without wrapping quotes.

Required: false
Type: Boolean

no_scroll_controls #

Specify whether the scroll arrows should be visible when tabs overflow. Set this value to true to disable the scroll arrows.

If this option isn’t set in the markup, Platen uses the value of the platen.markup.tabs.no_scroll_controls setting defined in your site configuration. The site configuration default is auto. For more information, see Configuration.

This option isn’t valid with the legacy template.

Specify true or false without wrapping quotes.

Required: false
Type: Boolean

placement #

Specify where the tabs should be located in the container relative to their content.

If this option isn’t set in the markup, Platen uses the value of the platen.markup.tabs.placement setting defined in your site configuration. The site configuration default is top. For more information, see Configuration.

This option isn’t valid with the legacy template.

You can see the various options below.

Placement: top #

In this example, the tabs are in the top position, displaying in the order they were specified in the Markdown.

The First Tab

This is the first tab.

The Second Tab

This is the second tab.

The Third Tab

This is the third tab.

The Fourth Tab

This is the fourth tab.

The Fifth Tab

This is the fifth tab.

The Sixth Tab

This is the sixth tab.

Placement: bottom #

In this example, the tabs are in the bottom position, beneath the rendered content. The order is the same.

The First Tab

This is the first tab.

The Second Tab

This is the second tab.

The Third Tab

This is the third tab.

The Fourth Tab

This is the fourth tab.

The Fifth Tab

This is the fifth tab.

The Sixth Tab

This is the sixth tab.

Placement: start #

In this example, the tabs are in the start position, before the rendered content. For languages written left-to-right, this puts them on the left. If this page was written in a right-to-left language, start would be on the right of the content.

The First Tab

This is the first tab.

The Second Tab

This is the second tab.

The Third Tab

This is the third tab.

The Fourth Tab

This is the fourth tab.

The Fifth Tab

This is the fifth tab.

The Sixth Tab

This is the sixth tab.

Placement: end #

In this example, the tabs are in the end position, after the rendered content. For languages written left-to-right, this puts them on the right. If this page was written in a right-to-left language, start would be on the left of the content.

The First Tab

This is the first tab.

The Second Tab

This is the second tab.

The Third Tab

This is the third tab.

The Fourth Tab

This is the fourth tab.

The Fifth Tab

This is the fifth tab.

The Sixth Tab

This is the sixth tab.

Required: false
Type: Enum
ValidValues:
- top
- bottom
- start
- end

standardize_height #

Specify whether the tabs in the group should have their height standardized to the same height as the tallest rendered tab in the group. This can help reduce how much the page layout updates when a reader switches between tabs.

If this option isn’t set in the markup, Platen uses the value of the platen.markup.tabs.standardize_height setting defined in your site configuration. The site configuration default is false. For more information, see Configuration.

This option isn’t valid with the legacy template. It’s ignored when the preset is applied to the markup for an individual tab.

Specify true or false without wrapping quotes.

Required: false
Type: Boolean

preset #

Specify the name of the preset to use, if any. If the preset is defined in a subfolder, specify the dot-path relative to data/platen/tabs. For example, the preset defined in data/platen/tabs/info/installing would be specified as info.installing.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String

Definition #

Inside a tabs codeblock you must use one or more tab codeblocks. These determine how the tabs themselves are rendered, while the attributes for the containing tabs codeblock control the behavior of the tab group overall.

tab Codeblocks #

Each tab codeblock you use inside a tabs codeblock adds another tab. You can control the name and styling for each tab independently.

Syntax #

With Attributes #
```tab { [.class [.class]] [#id] [name="name"] [preset="preset"] }
Markdown to _render_ for the tab
```
With Data #
```tab
---
class: class
closable: false
disabled: false
id: id
name: name
preset: preset
---

Markdown to _render_ for the tab
```

Attributes #

class #

Specify any additional classes to insert into the tab’s elements. By default, the elements have no classes.

When using the legacy template, the elements have the following default classes:

  • The <div> has the platen-tabs-content and markdown-inner classes.
  • The <label> has the toggle class.
  • The <input> has no classes.

For more information about how classes affect the styling of content in this markup, see Styling.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String
id #

Specify this attribute to add an id to the tab’s <sl-tab> element.

If you’re using the legacy template, individual tabs require an ID. If you specify this value, it’s used for the id of the tab’s [sref<input>] exactly as you specify it.

When you’re using the legacy template and don’t specify this value, you must specify the name attribute or option. When you do, Platen uses the down-cased and urlized form to build an automatic ID for the tab. For example, if id isn’t specified and name is specified as My Cool Tab, the generated id would be tabs-<groupID>-my-cool-tab.

You can use this attribute with the name attribute or option to set an easier-to-link-to ID for the tab. This is particularly useful if the tab name is long, uses inline HTML, or includes an icon.

Specify the ID as a bare string without any spaces and with a # prefix, like #my-id

Required: false
Type: String
name #

Specify the name of the tab. This is displayed as the label for the tab in the container.

If this value isn’t specified, Platen uses the titleized form of the id attribute or option as the name. For example, if name isn’t specified and id is specified as my-cool-tab, the generated name would be My Cool Tab.

You can use this attribute with the id attribute but you don’t have to. You must specify either name, id, or both.

This value is rendered as inline Markdown.

RendersMarkdown: true
Required: false
Type: String
preset #

Specify the name of the preset to use, if any. If the preset is defined in a subfolder, specify the dot-path relative to data/platen/tabs. For example, the preset defined in data/platen/tabs/info/installing would be specified as info.installing.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String

Options #

class #

Specify any additional classes to insert into the class list for this tab’s div, input, and label elements.

By default, the div has the platen-tabs-content and markdown-inner classes. The label has the toggle class. The input has no classes. For more information about how classes affect the styling of content in this markup, see Styling.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String
closable #

Specify whether this tab can be closed, removing it from view until the page is refreshed. Set this option to true to make the tab closable.

This option isn’t valid with the legacy template.

Specify true or false without wrapping quotes.

Required: false
Type: Boolean
disabled #

Specify whether this tab should be disabled, preventing users from selecting it. Set this option to true to make the tab disabled.

This option isn’t valid with the legacy template.

Specify true or false without wrapping quotes.

Required: false
Type: Boolean
id #

Specify this option to add an id to the tab’s <sl-tab> element.

If you’re using the legacy template, individual tabs require an ID. If you specify this value, it’s used for the id of the tab’s [sref<input>] exactly as you specify it.

When you’re using the legacy template and don’t specify this value, you must specify the name attribute or option. When you do, Platen uses the down-cased and urlized form to build an automatic ID for the tab. For example, if id isn’t specified and name is specified as My Cool Tab, the generated id would be tabs-<groupID>-my-cool-tab.

You can use this option with the name attribute or option to set an easier-to-link-to ID for the tab. This is particularly useful if the tab name is long, uses inline HTML, or includes an icon.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String
name #

Specify the name of the tab. This is displayed as the label for the tab in the container.

If this value isn’t specified, Platen uses the titleized form of the id attribute or option as the name. For example, if name isn’t specified and id is specified as my-cool-tab, the generated name would be My Cool Tab.

You can use this option with the id option but you don’t have to. You must specify either name, id, or both.

This value is rendered as inline Markdown.

RendersMarkdown: true
Required: false
Type: String
preset #

Specify the name of the preset to use, if any. If the preset is defined in a subfolder, specify the dot-path relative to data/platen/tabs. For example, the preset defined in data/platen/tabs/info/installing would be specified as info.installing.

Specify the text wrapped in quotes, like "this".

Required: false
Type: String
Definition #

Inside the tab codeblock you can write any valid Markdown you want.

Presets #

You can define any number of preset tab groups and tabs reusably in your site’s data. Any YAML files you add in the data/platen/tabs folder are available for use. You can use folders to group presets together.

The available properties you can specify for a preset are listed below and match the available attributes and inputs. When used together with attributes and inputs, any value specified as an attribute or input overrides the value specified in the preset’s definition.

Preset Definition

Here we define a preset for closable tabs in a task list: data/platen/tabs/task_list.yaml:

placement:  start
legacy:     false
activation: manual
closable:   true
Markdown Usage

Then, in our markdown, we use the tabs markup and reference the preset:

``````tabs { preset="task_list" }
---
activation: auto
---

```tab
---
name:   First Task
preset: task_list
---

Do the first thing.
```

```tab
---
name:   Second Task
preset: task_list
---

Do the next thing.
```

```tab
---
closable: false
name:     Third Task
preset:   task_list
---

Do the last thing.
```
``````

The tab group is processed to the equivalent YAML internally:

activation: auto
preset:     task_list

The individual tabs are processed to YAML that includes their name and the preset, except for the last tab, which is processed to:

closable: false
name:     Third Task
preset:   task_list
Merged Values

Now that we have both the values from the preset and Markdown, Platen combines them.

They become:

# Tab Group
placement:  start
legacy:     false
activation: auto

# First Tab
closable: true
name:     First Task

# Second Tab
closable: true
name:     Second Task

# Third Tab
closable: false
name:     Third Task

Because the tab group specifies activation as auto in its markup, that value is preferred over the manual value from the preset. The tab group ignores the value for closable altogether.

The first and second tabs take their values from the preset without overriding anything, making them closable.

The third tab overrides closable as false in the markup.

First Task

Do the first thing.

Second Task

Do the next thing.

Third Task

Do the last thing.

activation #

Specify the activation mode to use for the tab group. When the tab group is focused, keyboard users can press the kbd:Left and kbd:Right keys to select the desired tab.

When the value of this property is auto, the selected tab is shown immediately.

To require the user to press kbd:Space or kbd:Enter to show the tab, set this property to manual.

This property isn’t valid with the legacy template. This property is ignored when a preset is applied to tab markup. It’s effective when applied to a tab group.

class #

Specify any additional classes to insert into the class list for the markup.

You can specify this value either as a string (if you only need to add one class) or as a list of strings.

Single Class
class: sepia
Multiple Classes
class:
  - big
  - shadowed

closable #

Specify whether this tab can be closed, removing it from view until the page is refreshed. Set this option to true to make the tab closable.

This option isn’t valid with the legacy template. It’s ignored when the preset is applied to the markup for a tab group.

custom #

Specify whether the markup should use a custom template instead of the default or legacy template. Set this option to true to use the custom templates stubbed in platen/markup/tabs/templates/custom. That folder has a template for the tab group (group.html) and one for the individual tabs (tab.html). If this value is false, Platen uses the default or (if legacy is true) legacy template.

If this value is a string, Platen uses the value as the name of the folder in platen/markup/tabs/templates to look for the group.html and tab.html templates for rendering the markup.

For more information, see Custom Templates.

definition #

You can use this property to include the inner content of the codeblock for a tab group or tab. If you specify any content in the actual markup, it overriddes the value from the preset.

Be careful when using this option to predefine tabs. If you apply a preset with defined individual tabs to a tab codeblock instead of a tab group, Platen will raise an error.

Example Preset with Definition #

This preset defines both placement and definition:

placement: start
definition: |
  ```tab
  ---
  name: Normal
  ---
  This is a normal tab.
  ```
  ```tab
  ---
  name: Closable
  closable: true
  ---
  This is a normal tab.
  ```
  ```tab
  ---
  name: Disabled
  disabled: true
  ---
  This is a normal tab.
  ```  

Note that the definition includes three tabs as if writing normal Markdown. Also note the usage of the | character after the definition key declaration, and that the lines after are indented two spaces. That syntax indicates that the block of text should be treated as a single string, keeping the newlines. When you’re defining a definition in a preset, you should use that syntax.

The preset renders to this:

Normal

This is a normal tab.

Closable

This is a normal tab.

Disabled

This is a normal tab.

disabled #

Specify whether this tab should be disabled, preventing users from selecting it. Set this option to true to make the tab disabled.

This option isn’t valid with the legacy template. It’s ignored when the preset is applied to the markup for a tab group.

id #

Specify this property to add an id to the markup. Be careful not to use this value for more than one markup on a page, as sharing the same ID with multiple elements is invalid. You’ll need to override it by setting the ID attribute or option in the markup.

legacy #

Specify true to use the legacy template for the tabs markup, or false to use the <sl-tab-group> element from Shoelace. This preset property is ignored when applied to the markup for an individual tab.

If this value isn’t set, Platen uses the value of the platen.markup.tabs.use_legacy setting defined in your site configuration. For more information, see Configuration.

When this property is true, the following options are ignored:

name #

Specify the name of the tab. This is displayed as the label for the tab in the container. This property is ignored if the preset is applied to the markup for a tab group.

If this value isn’t specified, Platen uses the titleized form of the id attribute or option as the name. For example, if name isn’t specified and id is specified as my-cool-tab, the generated name would be My Cool Tab.

You can use this property with the id property but you don’t have to. You must specify either name, id, or both for an individual tab.

no_scroll_controls #

Specify whether the scroll arrows should be visible when tabs overflow. Set this value to true to disable the scroll arrows.

If this option isn’t set in the markup, Platen uses the value of the platen.markup.tabs.no_scroll_controls setting defined in your site configuration. The site configuration default is auto. For more information, see Configuration.

This option isn’t valid with the legacy template. It’s ignored when the preset is applied to the markup for an individual tab.

placement #

Specify where the tabs should be located in the container relative to their content.

If this option isn’t set in the markup, Platen uses the value of the platen.markup.tabs.placement setting defined in your site configuration. The site configuration default is top. For more information, see Configuration.

This option isn’t valid with the legacy template. It’s ignored when the preset is applied to the markup for an individual tab.

standardize_height #

Specify whether the tabs in the group should have their height standardized to the same height as the tallest rendered tab in the group. This can help reduce how much the page layout updates when a reader switches between tabs.

If this option isn’t set in the markup, Platen uses the value of the platen.markup.tabs.standardize_height setting defined in your site configuration. The site configuration default is false. For more information, see Configuration.

This option isn’t valid with the legacy template. It’s ignored when the preset is applied to the markup for an individual tab.

Specify true or false without wrapping quotes.

Required: false
Type: Boolean

Custom Templates #

If you want to use your own custom rendering for a tabs group without having to handle the markup parsing, attributes, and options yourself, you can use the custom option or configuration setting to use your own templates for rendering the details block.

Platen provides a pair of stubbed custom templates by default that include the available parameters you can use for rendering. The stubbed templates raise an error and return an empty string.

Legacy Template #

The legacy template uses standard HTML elements instead of the more customizable Shoelace elements. It doesn’t support as many options and will eventually be removed.

We strongly suggest you update your themes to use the new template.

When used, it creates a <div> HTML container. Each tab is added as an <input> and <label> representing the tab control and a child <div> for the tab content. The Markdown content in each tab is rendered as normal.

Currently, Platen uses the legacy template by default and warns on its use. You can override these behaviors in the configuration. To use the new template by default, set platen.markup.tabs.use_legacy to false. To continue using the legacy tabs element without warnings, set platen.markup.tabs.warn_on_legacy to false.

Configuration #

Several of the options for this markup can be configured in your site configuration or Platen’s parameter data. The most convenient option is to edit the data/_params/platen/markup.yaml file. Except for the warn_on_legacy setting, which is site-wide, every configuration setting can by overridden by the attributes or options in your markup.

The default values for this markup’s rendering options are defined below:

tabs:
  custom: false
  classes: []
  activation: auto
  no_scroll_controls: false
  placement: top
  standardize_height: false
  preset: null
  use_legacy: true
  warn_on_legacy: true
custom
If you set custom to true, Platen uses a custom template for rendering the details. By default, it uses the platen/markup/tabs/templates/custom.html template. If you set this value to a string, Platen uses a layout template by that name in the platen/markup/tabs folder. For more information, see Custom Templates.
classes
If you set classes to a list of strings, Platen adds them to the rendered tabs group (not the individual tab elements). If you specify any classes for a tabs codeblock as an attribute or option, those are used instead.
activation
Choose whether the tabs should require a manual keypress when navigating the tabs with a keyboard or if they should automatically display when cycling through them. Set this value to manual to require a keypress to activate. The default value is auto. If you specify the activation option in your markup, that value is used instead.
no_scroll_controls
Choose whether the scroll arrows are displayed by default when tabs in a group overflow. Set this value to false to remove the arrows. The default value is true. If you specify the no_scroll_controls option in your markup, that value is used instead.
placement
Choose where the tabs should be rendered relative to the content. The default value is top. If you specify the placement option in your markup, that value is used instead.
preset
Choose the default preset to apply to tabs markup. There is no default preset. For more information, see Presets.
standardize_height
Choose whether every tab group is rendered with the heights of its tabs standardized to the same as the tallest tab in the group. Set this value to true to standardize the height. If you specify the standardize_height option in your markup, that value is used instead.
use_legacy
If you want your tabs rendered with the new default template to use the full set of options, set this value to false. It defaults to true now, but will default to false in the future. Eventually, the legacy template will be removed entirely.
warn_on_legacy
If you want to silence the warnings Platen emits when you use the legacy template, set this value to false.

You can find the full set of options for this markup in the configuration reference.

Styling #

This markup uses the SCSS defined in the styles/markup/_tabs.scss file in your assets folder, which defaults to assets in your project root.

This section discusses styling the non-legacy template. Instead of applying custom styles to the legacy template, we strongly recommend you migrate to the non-legacy template. In the near future, it will become the default. Eventually, the legacy template will be removed entirely.

Tabs SCSS #

.markdown sl-tab-group.platen-tabs {
  &::part(body) {
    padding: 1rem;
  }
  sl-tab-panel {
    > :first-child {
      margin-top: 0;
    }
    > :last-child {
      margin-bottom: 0;
    }
  }
}

The SCSS for tabs only applies to <sl-tab-group> elements in a container that has the markdown class, and only when the element itself has the platen-tabs class. This keeps the style from being unintentionally applied anywhere else.

The style:

  • Adds a small amount of padding to the contents of the tabs to align with the design of the rest of Platen’s markup.
  • Trims the margin above the first element in the rendered content and after the last element to avoid overly large spaces in the page.

Extending the Style #

You can extend this style by adding SCSS into the styles/_custom.scss file in your assets folder or by copying the provided style into styles/markup/_tabs.scss and editing it.

When you do, make sure your styles use this selector as the base. Your styles should be contained in this selector or one of its children.

.markdown sl-tab-group.platen-tabs {
  // Your styles here
}

The rest of this section is a list of selectors you might find useful when styling the rendered tabs.

Tab Group
[slot="nav"]
This selector targets the <sl-tab> elements that make up the navigation for the rendered tabs.
&::part(base)
This selector targets the tab group’s base wrapper.
&::part(nav)
This selector targets the tab group’s navigation container where tabs are slotted in.
&::part(tabs)
This selector targets the container that wraps the tabs.
&::part(active-tab-indicator)
This selector targets the line that highlights the currently selected tab.
&::part(body)
This selector targets the tab group’s body where tab panels are slotted in.
&::part(scroll-button)
This selector targets the previous/next scroll buttons that show when tabs are scrollable, an <sl-icon-button>.
&::part(scroll-button--start)
This selector targets the starting scroll button.
&::part(scroll-button--end)
This selector targets the ending scroll button.
&::part(scroll-button__base)
This selector targets the scroll button’s exported base part.
Tab Navigation

To target the navigation elements, use the selector sl-tab inside of the tab-group selector, like this:

.markdown sl-tab-group.platen-tabs {
  sl-tab {
    // Your styles for the tabs themselves here
  }
}
&::part(base)
This selector targets the tab’s base wrapper.
&::part(close-button)
This selector targets the close button for closable tabs.
&::part(close-button__base)
This selector targets the close button’s base container.
Tab Content

To target the displayed contents for a tab, use the selector sl-tab-panel inside of the tab-group selector, like this:

.markdown sl-tab-group.platen-tabs {
  sl-tab-panel {
    // Your styles for the tabs themselves here
  }
}

Overriding the Style #

You can completely override the provided style by defining the styles/markup/_tabs.scss file in your assets folder.

You can also create a new style module in the styles/markup folder and set platen.markup.tabs.style in your site configuration to that module’s name. If you do, omit the leading _ and trailing .scss. For example, the name for the style module assets/styles/markup/_foo.scss is foo.

Edit this page