AMP
  • websites

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>
Precisa de explicações mais detalhadas?

Se as explicações nesta página não respondem a todas as suas perguntas, entre em contato com outros usuários de AMP para discutir seu caso de uso específico.

Ir para o Stack Overflow
Falta explicar algum recurso?

O projeto AMP incentiva fortemente sua participação e contribuições! Esperamos que você se torne um participante assíduo de nossa comunidade de código aberto, mas também agradecemos contribuições pontuais para problemas que você tenha particular interesse.

Editar amostra no GitHub