🎄🎅 Holiday Sale: Up to 50% OFF on UI Initiative, Swiper Studio and t0ggles 🎅🎄

Page

Page is one of the main components (containers) used to display app content.

Page Layout

<div class="page" data-name="home">
  <div class="page-content">
    ... scrollable page content goes here ...
  </div>
</div>

Page Name

As you may note, each page has a data-name attribute with a unique page name. It's not required but can be useful within "page events" or "page callbacks". It can help us to define which page is loaded and available so you can make required manipulations to the page.

Page Content

All visual content (like list views, forms, etc.) should put inside of <div class="page-content"> which should be a child of <div class="page">. It's required for correct styling, layout and scrolling.

Page Events

Now lets look at one of the most important parts of page navigation, "page events". Page Events allow us to manipulate just loaded pages by executing JavaScript for those specific pages:

EventTargetDescription
page:mountedPage Element<div class="page">Event will be triggered when new page just inserted to DOM. Or when page with keepAlive route is mounted/attached to DOM
page:initPage Element<div class="page">Event will be triggered after Framework7 initialize required page's components and navbar
page:reinitPage Element<div class="page">This event will be triggered in case of navigating to the page that was already initialized.
page:beforeinPage Element<div class="page">Event will be triggered when everything initialized and page is ready to be transitioned into view (into active/current position)
page:afterinPage Element<div class="page">Event will be triggered after page transitioned into view
page:beforeoutPage Element<div class="page">Event will be triggered right before page is going to be transitioned out of view
page:afteroutPage Element<div class="page">Event will be triggered after page transitioned out of view
page:beforeunmountPage Element<div class="page">Event will be triggered when page with keepAlive route is going to be unmounted/detached from DOM
page:beforeremovePage Element<div class="page">Event will be triggered right before Page will be removed from DOM. This event could be very useful if you need to detach some events / destroy some plugins to free memory. This event won't be triggered for keepAlive routes.
page:tabshowPage Element<div class="page">Event will be triggered when page's parent View as Tab becomes visible
page:tabhidePage Element<div class="page">Event will be triggered when page's parent View as Tab becomes hidden

Lets see how we can use these events. There are two ways to add page event handlers:

// Option 1. Using one 'page:init' handler for all pages
$$(document).on('page:init', function (e) {
  // Do something here when page loaded and initialized
})

// Option 2. Using live 'page:init' event handlers for each page
$$(document).on('page:init', '.page[data-name="about"]', function (e) {
  // Do something here when page with data-name="about" attribute loaded and initialized
})

Page Loading Sequence Classes

When a new page is loading and transitioned into the view (main visible part of the app) it has different classes on page element.

When we load/open new page the following happens:

  1. Currently active page has page-current class.
  2. If page we load not in DOM (e.g. loaded via Ajax or using template or from component) it will be added to DOM.
  3. Page that we load/open will have additional page-next class set on its element.
  4. Router element (<div class="view">) will have additional router-transition-forward class that does the following:
    • page with page-next (new page) class moves into the view
    • page with page-current (current page) class moves out of the view
  5. After transition completed, the new page that we loaded will have page-current class
  6. And the page that was previously active will have page-previous class

When we load/open previous page (go back) the following happens:

  1. Currently active page has page-current class.
  2. If page we go back to not in DOM (e.g. loaded via Ajax or using template or from component) it will be added to DOM.
  3. Page that we go back to will have additional page-previous class set on its element.
  4. Router element (<div class="view">) will have additional router-transition-backward class that does the following:
    • page with page-previous (page that we go back to) class moves into the view
    • page with page-current (current page) class moves out of the view
  5. After transition completed, the new page that we returned to will have page-current class
  6. And the page that was previously active will have page-next class. In case this page was added to DOM dynamically, it will be removed from DOM.

Page Data

As you may see it is pretty easy, but how do you determine which page is loaded when we use only one handler? For this case we have Page Data in the event details:

// In page events:
$$(document).on('page:init', function (e) {
  // Page Data contains all required information about loaded and initialized page
  var page = e.detail;
})

Or in case the event handler was assigned using Dom7 like in example above then it will be passed in second argument:

// In page events:
$$(document).on('page:init', function (e, page) {
  console.log(page);
})

Now, in the example above we have page data in page variable. It is an object with the following properties:

page.appobjectInitialized app instance
page.viewobjectView instance that contains this page (if this View was initialized)
page.routerobjectRouter instance that contains this page (if this View was initialized). Same as page.view.router
page.namestringValue of page's data-name attribute
page.elHTMLElementPage element
page.$elobjectDom7 instance with Page element
page.fromstringPage position before transition or direction of where this Page comes from. It will be next if you load new page, previous - if you go back to this page, or current if this page replaces the currently active one.
page.tostringNew page position or where this page goes to. Can be same next, previous or current
page.positionstringAlias for page.from
page.directionstringDirection of page transition (if applicable). Can be forward or backward
page.routeobjectRoute associated with this page, object with current route data that was used to load this page. It has the following properties
  • url - route URL
  • path - route path
  • query - object with route query. If the url is /page/?id=5&foo=bar then it will contain the following object {id: '5', foo: 'bar'}
  • params - route params. If we have matching route with /page/user/:userId/post/:postId/ path and url of the page is /page/user/55/post/12/ then it will be the following object {userId: '55', postId: '12'}
  • name - route name
  • hash - route URL hash
  • route - object with matching route from available routes
  • context - context that was passed to the route
page.pageFromobjectPage data of the page that was currently active before this new page.

Access To Page Data

If you don't use page events/callbacks and need to access to page data, it is possible via the f7Page property on its HTMLElement:

var $$ = Dom7;

var page = $$('.page[data-name="somepage"]')[0].f7Page;

// do something with page data

CSS Variables

Below is the list of related CSS variables (CSS custom properties).

Note that commented variables are not specified by default and their values is what they fallback to in this case.

:root {
  --f7-page-master-width: 320px;
  --f7-page-master-border-color: rgba(0, 0, 0, 0.1);
  --f7-page-master-border-width: 1px;
  --f7-page-swipeback-transition-duration: 300ms;
  --f7-page-parallax-transition-duration: 500ms;
  --f7-page-cover-transition-duration: 450ms;
  --f7-page-dive-transition-duration: 500ms;
  --f7-page-fade-transition-duration: 500ms;
  --f7-page-flip-transition-duration: 700ms;
  --f7-page-push-transition-duration: 500ms;
  /*
  --f7-page-content-extra-padding-top: 0px;
  --f7-page-content-extra-padding-bottom: 0px;
  */
  --f7-page-title-line-height: 1.2;
  --f7-page-title-text-color: inherit;
  --f7-page-title-padding-left: 16px;
  --f7-page-title-padding-right: 16px;
}
.ios {
  --f7-page-transition-duration: 400ms;
  --f7-page-title-font-size: 34px;
  --f7-page-title-font-weight: 700;
  --f7-page-title-letter-spacing: -0.03em;
  --f7-page-title-padding-vertical: 6px;
  --f7-page-bg-color: #efeff4;
}
.ios .dark,
.ios.dark {
  --f7-page-bg-color: #000;
}
.md {
  --f7-page-transition-duration: 400ms;
  --f7-page-title-font-size: 34px;
  --f7-page-title-font-weight: 500;
  --f7-page-title-letter-spacing: 0;
  --f7-page-title-padding-vertical: 8px;
}
.md,
.md .dark,
.md [class*='color-'] {
  --f7-page-bg-color: var(--f7-md-surface);
}
.dark {
  --f7-page-master-border-color: rgba(255, 255, 255, 0.2);
}