Layout
Layouts are the elements that wrap page content, like a navigational bar or drawer. Multiple pages can share the same Layout, so the code is reusable, which is one of their key points.
Quasar Layouts are NOT mandatory, but they do help you better structure your website/app. They have a number of features which offer you major benefits in simplifying your app’s layout design, right out of the box.
Installation
Edit /quasar.conf.js
to embed the components (only add what you need from below):framework: {
components: [
'QLayout',
'QPageContainer',
'QPage',
'QLayoutHeader',
'QLayoutFooter',
'QLayoutDrawer',
'QPageSticky'
]
}
Basic Usage
Below is a scaffolding of a Layout so you can understand the structure. We’ll discuss about properties later<!-- main wrapping component -->
<q-layout>
<!-- optional -->
<q-layout-header>
<!-- content; any -->
</q-layout-header>
<!-- optional -->
<q-layout-drawer side="left">
<!-- content; any -->
</q-layout-drawer>
<!-- optional -->
<q-layout-drawer side="right">
<!-- content; any -->
</q-layout-drawer>
<!-- REQUIRED -->
<q-page-container>
<!--
Here it's where Vue Router injects children
Page components.
<router-view/> tag below can be replaced by an
actual page content should you wish to do so.
-->
<router-view />
<!--
First child of QPageContainer must be a QPage,
so make sure that your layout route children components
encapsulate a QPage.
-->
</q-page-container>
<!-- optional -->
<q-layout-footer>
<!-- content; any -->
</q-layout-footer>
</q-layout>
Below is another example of a Layout, which contains some useful elements:
- a QToolbar (used for both header and footer, you can specify as many as you want)
- a navigation with QTabs
- a left side drawer panel (which is shown alongside page content on wide screens)
- and a right side drawer panel
<q-layout view="hHr LpR lFf"> |
You can also use QScrollArea for the left or right sides of the layout, if you want to control the scrollbar (but it’s not mandatory):<!-- notice style tag -->
<q-layout-drawer side="left">
<q-scroll-area class="fit">
<q-item to="/test-layout/toolbar">Toolbar</q-item>
<q-item to="/test-layout/tabs">Tabs</q-item>
<q-item to="/test-layout/drawer">Drawer</q-item>
</q-scroll-area>
</q-layout-drawer>
Tips to Understanding QLayout
Using margin CSS will break the layout
QLayout depends on taking up the whole screen and so QPageContainer, QLayoutHeader, QLayoutFooter and QLayoutDrawer positions are managed by it (throughview
prop). You cannot use CSS margins as a style neither on QLayout itself nor on any of the components mentioned above. However you can safely use CSS padding.
Routing
If your layout uses Vue Router sub-routes (recommended), then it makes sense to use Vue’s <router-view />
component, which is just a placeholder where sub-routes are injected.
Toolbar Placement
A great place to use the Toolbars component is within the QLayoutHeader and QLayoutFooter.<q-layout-header>
<q-toolbar color="green">
... toolbar content ...
</q-toolbar>
</q-layout-header>
Search example
Below is an example of placing a Search bar in the header:<q-layout>
...
<!-- We place it on header -->
<q-layout-header>
<q-toolbar color="primary">
<q-search inverted v-model="search" color="none" />
</q-toolbar>
</q-layout-header>
...
</q-layout>
Fixed Positioning & FABs
Also, read about the smart Page Sticky which helps you fix position DOM elements or components on a Layout page and learn how you can use it to also place a Floating Action Button.
QLayout Vue Properties
Vue Property | Type | Description |
---|---|---|
view | String | Configuration string which defines how different parts of the layout get displayed on screen. |
Configuring the “view” prop
Quasar introduces a unique and excellent layout concept, which allows you to easily structure layouts to work in certain ways, by simply changing a short string notation.
To explain how this works, imagine your Layout is a 3x3 matrix of containers. The first row of containers would be the header and the last row would be the footer. The first column of containers would be the “left” and last column would be the “right”. The center of the matrix, below the header and above the footer, would be the page or main content container.
Now think about this. This matrix of containers or “QLayout View” can be represented by a string. This string contains only 11 characters:
- 3 defining the header row
- then a space
- 3 defining the middle row
- a space
- then 3 defining the footer
The picture below offers a visual representation of the QLayout View, to help you understand how to configure its 3x3 matrix.
The letters shown above are also case sensitive. For example, using at least one “L” (uppercase character instead of lowercase) will make your layout left side (drawer) be in a fixed position. Same applies for “H” (header), “F” (footer) and finally “R” (right side / drawer).
For example, if you want your layout’s right side / drawer to be placed on the right of the header, page and footer, you’d use hhr lpr ffr
. If you’d like to also make it fixed, just transform one r
character to uppercase, like this: hhR lpr ffr
, or hhr lpR ffr
or hhr lpr ffR
.
These settings are completely up to you to use as you’d like. You could even go wild with a setup like this: Lhh lpR ffr
. Try it out! Make sure you also go to the desktop view, to see it work properly.
NOTE
It is important that you specify all sections of a layout, even if you don’t use them. For example, even if you don’t use footer or right side drawer, specify them within your layout’sview
prop.
QLayout Vue Events
Event Name | Description |
---|---|
@resize | Event emitted on window resize. |
@scroll | Event emitted on page scroll. |
@scrollHeight | Event emitted on page scroll height change. |
Containerized QLayout
v0.17.9+
WARNING
Not supported in IE11.
Please note that it requires a CSS height/width (or min-height/min-width) being set explicitly, otherwise it can’t work.
Example:<q-layout view="LHh lpR fff" container style="height: 500px; width: 300px" class="shadow-2">
<q-layout-header reveal>
<q-toolbar>
<q-btn flat @click="drawer = !drawer" round dense icon="menu" />
<q-toolbar-title>Header</q-toolbar-title>
</q-toolbar>
</q-layout-header>
<q-layout-footer>
<q-toolbar>
<q-btn flat @click="drawer = !drawer" round dense icon="menu" />
<q-toolbar-title>Footer</q-toolbar-title>
</q-toolbar>
</q-layout-footer>
<q-layout-drawer v-model="drawer" :width="200" :breakpoint="300">
<div v-for="n in 50" :key="n">Drawer</div>
</q-layout-drawer>
<q-page-container>
<q-page style="padding-top: 50px">
<div v-for="n in 50" :key="n">My page</div>
</q-page>
</q-page-container>
</q-layout>
Example in a QModal:<q-modal v-model="modal">
<q-layout view="LHh lpR fff" container style="min-height: 60vh; min-width: 60vw;">
<q-layout-header reveal>
<q-toolbar>
<q-btn flat @click="drawer2 = !drawer2" round dense icon="menu" />
<q-toolbar-title>Header</q-toolbar-title>
<q-btn flat @click="modal = false" round dense icon="close" />
</q-toolbar>
</q-layout-header>
<q-layout-footer>
<q-toolbar>
<q-btn flat @click="drawer2 = !drawer2" round dense icon="menu" />
<q-toolbar-title>Footer</q-toolbar-title>
</q-toolbar>
</q-layout-footer>
<q-layout-drawer v-model="drawer2" :width="200" :breakpoint="900">
<div v-for="n in 50" :key="n">Drawer</div>
</q-layout-drawer>
<q-page-container>
<q-page style="padding-top: 50px">
<div v-for="n in 50" :key="n">My page</div>
</q-page>
</q-page-container>
</q-layout>
</q-modal>