AMP
  • email

Tab Panels with amp-selector

Introduction

This is an implementation of tab panels that uses amp-selector. Tabs and tab panels are positioned via flexbox and amp-selector uses the selected attribute to show/hide the correct tab panel and style the selected tab.

Setup

Import amp-selector component in the header which we'll use to implement the tab switching.

<script async custom-element="amp-selector" src="https://cdn.ampproject.org/v0/amp-selector-0.1.js"></script>

There's just a bit of CSS that's needed.

<style amp-custom>
    :root {
      --color-primary: #005AF0;
      --space-1: .5rem;  /* 8px */
      --space-4: 2rem;   /* 32px */
    }

    /* Styles for the flex layout based tabs */
    amp-selector[role=tablist].tabs-with-flex {
        display: flex;
        flex-wrap: wrap;
    }
    amp-selector[role=tablist].tabs-with-flex [role=tab] {
        flex-grow: 1;
        /* custom styling, feel free to change */
        text-align: center;
        padding: var(--space-1);
    }
    amp-selector[role=tablist].tabs-with-flex [role=tab][selected] {
        outline: none;
        /* custom styling, feel free to change */
        border-bottom: 2px solid var(--color-primary);
    }
    amp-selector[role=tablist].tabs-with-flex [role=tabpanel] {
        display: none;
        width: 100%;
        order: 1; /* must be greater than the order of the tab buttons to flex to the next line */
        /* custom styling, feel free to change */
        padding: var(--space-4);
    }
    amp-selector[role=tablist].tabs-with-flex [role=tab][selected] + [role=tabpanel] {
        display: block;
    }

    /* Styles for the selector based tabs */
    amp-selector[role=tablist].tabs-with-selector {
        display: flex;
    }
    amp-selector[role=tablist].tabs-with-selector [role=tab][selected] {
        outline: none;
        /* custom styling, feel free to change */
        border-bottom: 2px solid var(--color-primary);
    }
    amp-selector[role=tablist].tabs-with-selector {
        display: flex;
    }
    amp-selector[role=tablist].tabs-with-selector [role=tab] {
      /* custom styling, feel free to change */
      width: 100%;
      text-align: center;
      padding: var(--space-1);
    }
    amp-selector.tabpanels [role=tabpanel] {
      display: none;
      /* custom styling, feel free to change */
      padding: var(--space-4);
    }
    amp-selector.tabpanels [role=tabpanel][selected] {
      outline: none;
      display: block;
    }

</style>

Simple tabs using a flex layout

This is the most basic example with three panels. Each tabpanel is defined below it's tab and is hidden by default. Only if a tab is selected, the tabpanel is set to visible via the following CSS rule:

amp-selector[role=tablist] [role=tab][selected] + [role=tabpanel] {
  display: block;
}

The tab content is positioned below the tab button using a flex layout.

Tab one content...
Tab two content...
Tab three content...
<amp-selector class="tabs-with-flex"
  role="tablist"
  keyboard-select-mode="focus">
  <div id="tab1"
    role="tab"
    aria-controls="tabpanel1"
    option
    selected>Tab one</div>
  <div id="tabpanel1"
    role="tabpanel"
    aria-labelledby="tab1">Tab one content... </div>
  <div id="tab2"
    role="tab"
    aria-controls="tabpanel2"
    option>Tab two</div>
  <div id="tabpanel2"
    role="tabpanel"
    aria-labelledby="tab2">Tab two content... </div>
  <div id="tab3"
    role="tab"
    aria-controls="tabpanel3"
    option>Tab three</div>
  <div id="tabpanel3"
    role="tabpanel"
    aria-labelledby="tab3">Tab three content... </div>
</amp-selector>

Selecting a tab via a button

We can use the amp-selector's toggle action to activate specific tabs: on="tap:myTabs.toggle(index=0, value=true)".

Tab one content...
Tab two content...
Tab three content...
<button on="tap:myTabs.toggle(index=0, value=true)">Select tab 1</button>
<button on="tap:myTabs.toggle(index=1, value=true)">Select tab 2</button>
<button on="tap:myTabs.toggle(index=2, value=true)">Select tab 3</button>

<amp-selector id="myTabs"
  class="tabs-with-flex"
  role="tablist"
  keyboard-select-mode="focus">
  <div id="sample2-tab1"
    role="tab"
    aria-controls="sample2-tabpanel1"
    option
    selected>Tab one</div>
  <div id="sample2-tabpanel1"
    role="tabpanel"
    aria-labelledby="sample2-tab1">Tab one content... </div>
  <div id="sample2-tab2"
    role="tab"
    aria-controls="sample2-tabpanel2"
    option>Tab two</div>
  <div id="sample2-tabpanel2"
    role="tabpanel"
    aria-labelledby="sample2-tab2">Tab two content... </div>
  <div id="sample2-tab3"
    role="tab"
    aria-controls="sample2-tabpanel3"
    option>Tab three</div>
  <div id="sample2-tabpanel3"
    role="tabpanel"
    aria-labelledby="sample2-tab3">Tab three content... </div>
</amp-selector>

A more flexible tab layout with two amp-selectors

If for any reason, the flex layout based approach is not feasible, it's possible to implement tabs and tabpanels using two different amp-selectors.

Tab one content...
Tab two content...
Tab three content...
<amp-selector class="tabs-with-selector"
  role="tablist"
  on="select:myTabPanels.toggle(index=event.targetOption, value=true)"
  keyboard-select-mode="focus">
  <div id="sample3-tab1"
    role="tab"
    aria-controls="sample3-tabpanel1"
    option="0"
    selected>Tab one</div>
  <div id="sample3-tab2"
    role="tab"
    aria-controls="sample3-tabpanel2"
    option="1">Tab two</div>
  <div id="sample3-tab3"
    role="tab"
    aria-controls="sample3-tabpanel3"
    option="2">Tab three</div>
</amp-selector>

<amp-selector id="myTabPanels"
  class="tabpanels">
  <div id="sample3-tabpanel1"
    role="tabpanel"
    aria-labelledby="sample3-tab1"
    option
    selected>Tab one content... </div>
  <div id="sample3-tabpanel2"
    role="tabpanel"
    aria-labelledby="sample3-tab2"
    option>Tab two content... </div>
  <div id="sample3-tabpanel3"
    role="tabpanel"
    aria-labelledby="sample3-tab3"
    option>Tab three content... </div>
</amp-selector>
需要进一步说明?

如果此页面的说明未能涵盖您的所有问题,欢迎与其他 AMP 用户取得联系,讨论您的具体用例。

前往 Stack Overflow
一项无法解释的功能?

AMP 项目强烈鼓励您参与其中并作出贡献!我们希望您能成为我们开源社区的持续参与者,但我们也欢迎您对热衷问题做出单次贡献。

在 GitHub 上编辑实例