Tabs

    Tabs allow to simply switch between different content.

    Let’s look at Tabs layout:

    Where:

    • - required wrapper for all tabs. If you miss this element, tabs will not work!
    • div class="tab" - single tab. Should have unique id attribute
    • div class="tab tab-active" - single active tab. Tab which is active (visible) by default, should have additional **tab-active** class

    If you put tabs inside of scrollable <div class="page-content"> then they will have mutual scrolling - scrolling one tab will basically scroll the all tabs as well. To avoid this (if this is a case), it is recommended to make each tab as page-content, in this case each tab will have own scrolling:

    1. <div class="page">
    2. <div class="navbar">...</div>
    3. <!-- tabs is a direct child of page -->
    4. <div class="tabs">
    5. <!-- each tabs is a "page-content" -->
    6. <div class="page-content tab tab-active" id="tab1">
    7. ... Tab 1 content goes here ...
    8. </div>
    9. <div class="page-content tab" id="tab2">
    10. ... Tab 2 content goes here ...
    11. </div>
    12. <!-- Third tab, should have "tab" class and unique id attribute -->
    13. <div class="page-content tab" id="tab3">
    14. ... Tab 3 content goes here ...
    15. </div>
    16. </div>
    17. </div>

    Switching Between Tabs

    After we have our tabs layout we need some contoller so user can switch between them.

    To make it work we need to create links (<a> tags) with **tab-link** class and href attribute equal to the id attribute of target tab:

    1. <!-- Link that activates first tab, has the same href attribute (#tab1) as the id attribute of first tab (tab1) -->
    2. <a href="#tab1" class="tab-link tab-link-active">Tab 1</a>
    3. <!-- Link that activates 2nd tab, has the same href attribute (#tab2) as the id attribute of 2nd tab (tab2) -->
    4. <a href="#tab2" class="tab-link">Tab 2</a>
    5. <!-- Link that activates 3rd tab, has the same href attribute (#tab2) as the id attribute of 3rd tab (tab3) -->
    6. <a href="#tab3" class="tab-link">Tab 3</a>

    As you may see, first link also has **tab-link-active** class. It is not required, but if all such links will be on the same DOM tree level (the same-level children of mutual parent), then script will also change this tab-link-active class on link related to the active tab. It is useful when your “active” link has different visual style (like buttons in or links in Tabbar)

    Switch Multiple Tabs

    Such notation as above uses ID attributes to specify tabs we need to switch to. But sometimes we may have situation when we need to switch few tabs using one tab-link, for this case we may use classes instead of IDs and **data-tab** attribute for tab-link. For example:

    1. <!-- Top Tabs -->
    2. <div class="tabs tabs-top">
    3. <div class="tab tab1 tab-active">...</div>
    4. <div class="tab tab2">...</div>
    5. <div class="tab tab3">...</div>
    6. </div>
    7. <!-- Bottom Tabs -->
    8. <div class="tabs tabs-bottom">
    9. <div class="tab tab1 tab-active">...</div>
    10. <div class="tab tab2">...</div>
    11. <div class="tab tab3">...</div>
    12. </div>
    13. <!-- Tabs links -->
    14. <div>
    15. <!-- This links will switch top and bottom tabs to .tab1 -->
    16. <a href="#" class="tab-link tab-link-active" data-tab=".tab1">Tab 1</a>
    17. <!-- This links will switch top and bottom tabs to .tab2 -->
    18. <a href="#" class="tab-link" data-tab=".tab2">Tab 2</a>
    19. <!-- This links will switch top and bottom tabs to .tab3 -->
    20. <a href="#" class="tab-link" data-tab=".tab3">Tab 3</a>
    21. </div>

    Why single Tab could not be a seprate View with its own navigation and layout? It can, so you can just switch Views as tabs. In this case we will have kind of Tabbed app structure, where each tab represents separate View:

    Animated Tabs

    It is also possible to switch tabs with simple transition. This requires additional **div class="tabs-animated-wrap"** wrapper for div class="tabs":

    1. <!-- Tabs animated wrapper, required to switch tabs with transition -->
    2. <div class="tabs-animated-wrap">
    3. <!-- Tabs, tabs wrapper -->
    4. <div class="tabs">
    5. <!-- Tab 1, active by default -->
    6. <div id="tab1" class="tab tab-active">
    7. ... Tab 1 content ...
    8. </div>
    9. <!-- Tab 2 -->
    10. <div id="tab2" class="tab">
    11. ... Tab 2 content ...
    12. </div>
    13. <!-- Tab 3 -->
    14. <div id="tab3" class="tab">
    15. ... Tab 3 content ...
    16. </div>
    17. </div>
    18. </div>

    Note that animted tabs wrapper div class="tabs-animated-wrap" must have fixed height. By default, it is 100% height of its parent

    Swipeable Tabs

    It is also possible to switch tabs with swipes. This requires additional **div class="tabs-swipeable-wrap"** wrapper for div class="tabs".

    In this example let’s put tab links in Subnavbar and we will use page-content as tab to keep scrolling position for each tab separately:

    1. <!-- Tabs swipeable wrapper, required to switch tabs with swipes -->
    2. <div class="tabs-swipeable-wrap">
    3. <!-- Tabs, tabs wrapper -->
    4. <div class="tabs">
    5. <!-- Tab 1, active by default -->
    6. <div id="tab1" class="tab tab-active">
    7. ... Tab 1 content ...
    8. </div>
    9. <!-- Tab 2 -->
    10. <div id="tab2" class="tab">
    11. ... Tab 2 content ...
    12. </div>
    13. <!-- Tab 3 -->
    14. <div id="tab3" class="tab">
    15. </div>
    16. </div>
    17. </div>

    To achieve swipeable effect, swipeable tabs are actually will be converted to Swiper, so it is possible to tweak their behavior by passing using data- attributes.

    We can control tabs using the following app methods:

    app.tab.show(tabEl, animate)

    • tabEl - HTMLElement or string (with CSS Selector) of Tab to show. Requred
    • animate - boolean - Should it become visible with animation or not (in case of animated or swipeable tabs). Optional
    • This method returns object with and oldTabEl properties with shown and hidden tabs HTML elements
    • tabEl - HTMLElement or string (with CSS Selector) of Tab to show. Requred
    • tabLinkEl - HTMLElement or string (with CSS Selector) of Tab link/button to be activated with this tab. Useful to pass in case you have a complex layout to tell Framework7 which tab link/button must be activated
    • animate - boolean - Should it become visible with animation or not (in case of animated or swipeable tabs). Optional
    • This method returns object with newTabEl and oldTabEl properties with shown and hidden tabs HTML elements

    Tabs Events

    Tabs will fire the following DOM events on tab elements and events on app instance:

    DOM Events

    There are app instance events as well:

    Routable Tabs

    Tabs can be routable. What routable tabs means and why is it good?

    • First of all, it provides opportunity to navigate to tabs by usual links instead of so called special tab-links.
    • Second, when navigating to such tab routes you can load a page with required tab opened.
    • Third, with enabled Push State, the same tab will be opened when you navigate back and forward in history.
    • And the last but not least, when using routable tabs you can load tab content in the same ways as for pages, i.e. using url, content, template, templateUrl, component or componentUrl

    First of all we need to specify tabs routes in app routes. Let’s assume we have a page with routable tabs on /tabs/ route:

    1. routes = [
    2. {
    3. // Page main route
    4. path: '/tabs/',
    5. // Will load page from tabs/index.html file
    6. url: './pages/tabs/index.html',
    7. // Pass "tabs" property to route, must be array with tab routes:
    8. tabs: [
    9. // First (default) tab has the same url as the page itself
    10. {
    11. // Tab path
    12. path: '/',
    13. // Tab id
    14. id: 'tab-1',
    15. // Fill this tab content from content string
    16. content: `
    17. <div class="block">
    18. <h3>About Me</h3>
    19. <p>...</p>
    20. </div>
    21. `
    22. },
    23. // Second tab
    24. {
    25. path: '/tab-2/',
    26. id: 'tab-2',
    27. // Fill this tab content with Ajax request:
    28. url: './pages/tabs/tab-2.html',
    29. },
    30. // Third tab
    31. {
    32. path: '/tab-3/',
    33. id: 'tab-3',
    34. // Load this tab content as a component with Ajax request:
    35. componentUrl: './pages/tabs/tab-3.html',
    36. },
    37. ],
    38. }
    39. ]

    On the /tabs/index.html page we may have the following structure, for example:

    Almost the same as with usual tabs but with the difference that there is no more “tab-link-active” and “tab-active” classes on tab links and tabs. These classes and tabs will be switched by router. And there is a new attribute and class:

    • data-route-tab-id - additional tab link attribute which is required for tabs switcher to understand which link related to the required route
    • tabs-routable - required additional class on tabs element

    Note that Views can not be used as Routable Tabs. Routable Tabs can be used only inside of View/Router!

    Routable Tabs Events

    Router will fire the following DOM events on tab elements and events on router/view/app instance when routable tab content is loaded:

    DOM Events

    Router Instance Events

    1. <div class="page">
    2. <div class="navbar">
    3. <div class="navbar-inner sliding">
    4. <div class="left">
    5. <a href="#" class="link back">
    6. <i class="icon icon-back"></i>
    7. <span class="ios-only">Back</span>
    8. </a>
    9. </div>
    10. <div class="title">Static Tabs</div>
    11. </div>
    12. </div>
    13. <div class="toolbar tabbar">
    14. <div class="toolbar-inner">
    15. <a href="#tab-1" class="tab-link tab-link-active">Tab 1</a>
    16. <a href="#tab-2" class="tab-link">Tab 2</a>
    17. <a href="#tab-3" class="tab-link">Tab 3</a>
    18. </div>
    19. </div>
    20. <div class="tabs">
    21. <div id="tab-1" class="page-content tab tab-active">
    22. <div class="block">
    23. <p>Tab 1 content</p>
    24. ...
    25. </div>
    26. </div>
    27. <div id="tab-2" class="page-content tab">
    28. <div class="block">
    29. <p>Tab 2 content</p>
    30. ...
    31. </div>
    32. </div>
    33. <div id="tab-3" class="page-content tab">
    34. <div class="block">
    35. <p>Tab 3 content</p>
    36. ...
    37. </div>
    38. </div>
    39. </div>
    40. </div>

    Animated Tabs

    1. <div class="page">
    2. <div class="navbar">
    3. <div class="navbar-inner sliding">
    4. <div class="left">
    5. <i class="icon icon-back"></i>
    6. <span class="ios-only">Back</span>
    7. </a>
    8. </div>
    9. <div class="title">Animated Tabs</div>
    10. </div>
    11. </div>
    12. <div class="toolbar tabbar">
    13. <div class="toolbar-inner">
    14. <a href="#tab-1" class="tab-link tab-link-active">Tab 1</a>
    15. <a href="#tab-2" class="tab-link">Tab 2</a>
    16. <a href="#tab-3" class="tab-link">Tab 3</a>
    17. </div>
    18. </div>
    19. <div class="tabs-animated-wrap">
    20. <div class="tabs">
    21. <div id="tab-1" class="page-content tab tab-active">
    22. <div class="block">
    23. <p>Tab 1 content</p>
    24. ...
    25. </div>
    26. </div>
    27. <div id="tab-2" class="page-content tab">
    28. <div class="block">
    29. <p>Tab 2 content</p>
    30. ...
    31. </div>
    32. </div>
    33. <div id="tab-3" class="page-content tab">
    34. <div class="block">
    35. <p>Tab 3 content</p>
    36. ...
    37. </div>
    38. </div>
    39. </div>
    40. </div>
    41. </div>
    1. <div class="page">
    2. <div class="navbar">
    3. <div class="navbar-inner sliding">
    4. <div class="left">
    5. <a href="#" class="link back">
    6. <i class="icon icon-back"></i>
    7. <span class="ios-only">Back</span>
    8. </a>
    9. </div>
    10. <div class="title">Swipeable Tabs</div>
    11. </div>
    12. </div>
    13. <div class="toolbar tabbar">
    14. <div class="toolbar-inner">
    15. <a href="#tab-1" class="tab-link tab-link-active">Tab 1</a>
    16. <a href="#tab-2" class="tab-link">Tab 2</a>
    17. <a href="#tab-3" class="tab-link">Tab 3</a>
    18. </div>
    19. </div>
    20. <div class="tabs-swipeable-wrap">
    21. <div class="tabs">
    22. <div id="tab-1" class="page-content tab tab-active">
    23. <div class="block">
    24. <p>Tab 1 content</p>
    25. ...
    26. </div>
    27. </div>
    28. <div id="tab-2" class="page-content tab">
    29. <div class="block">
    30. <p>Tab 2 content</p>
    31. ...
    32. </div>
    33. </div>
    34. <div id="tab-3" class="page-content tab">
    35. <div class="block">
    36. <p>Tab 3 content</p>
    37. ...
    38. </div>
    39. </div>
    40. </div>
    41. </div>
    42. </div>

    Routable Tabs

    1. <div class="page">
    2. <div class="navbar">
    3. <div class="navbar-inner sliding">
    4. <div class="left">
    5. <a href="#" class="link back">
    6. <i class="icon icon-back"></i>
    7. <span class="ios-only">Back</span>
    8. </a>
    9. </div>
    10. <div class="title">Tabs Routable</div>
    11. </div>
    12. </div>
    13. <div class="toolbar tabbar">
    14. <div class="toolbar-inner">
    15. <a href="./" class="tab-link" data-route-tab-id="tab1">Tab 1</a>
    16. <a href="tab2/" class="tab-link" data-route-tab-id="tab2">Tab 2</a>
    17. <a href="tab3/" class="tab-link" data-route-tab-id="tab3">Tab 3</a>
    18. </div>
    19. </div>
    20. <div class="tabs tabs-routable">
    21. <div class="page-content tab" id="tab1"></div>
    22. <div class="page-content tab" id="tab2"></div>
    23. <div class="page-content tab" id="tab3"></div>
    24. </div>
    25. </div>