Blazor Offcanvas
Build hidden sidebars into your project for navigation, shopping carts, and more with Blazor Bootstrap offcanvas component.
Parameters
Name | Type | Default | Required | Description | Added Version |
---|---|---|---|---|---|
BodyCssClass | string | null | Gets or sets the body CSS class. | 1.0.0 | |
BodyTemplate | RenderFragment | null | Gets or sets the body template. | 1.0.0 | |
CloseOnEscape | bool | true | If true, offcanvas closes when escape key is pressed. | 1.0.0 | |
FooterCssClass | string | null | Gets or sets the footer CSS class. | 1.0.0 | |
FooterTemplate | RenderFragment | null | Gets or sets the footer template. | 1.0.0 | |
HeaderCssClass | string | null | Gets or sets the header CSS class. | 1.0.0 | |
HeaderTemplate | RenderFragment | null | Gets or sets the header template. | 1.0.0 | |
IsScrollable | bool | false | Indicates whether body (page) scrolling is allowed while offcanvas is open. | 1.0.0 | |
Placement | Placement | Placement.End | Gets or sets the offcanvas placement. | 1.0.0 | |
ShowCloseButton | bool | true | If true, modal shows close button in the header. | 1.0.0 | |
Size | OffcanvasSize | OffcanvasSize.Regular | Gets or sets the offcanvas size. | 1.0.0 | |
TabIndex | int | -1 | Gets or sets the tab index. | 1.6.0 | |
Title | string | null | Gets or sets the offcanvas title. | 1.0.0 | |
UseStaticBackdrop | bool | false | When UseStaticBackdrop is set to true, the offcanvas will not close when clicking outside of it. | 1.8.0 |
Methods
Method | Description | Added Version |
---|---|---|
ShowAsync | Shows an offcanvas element. Returns to the caller before the offcanvas element has actually been shown (i.e. before the OnShown event occurs). | 1.0.0 |
HideAsync | Hides an offcanvas element. Returns to the caller before the offcanvas element has actually been hidden (i.e. before the OnHidden event occurs). | 1.0.0 |
All API methods are asynchronous and start a transition. They return to the caller as soon as the transition is started but before it ends. In addition, a method call on a transitioning component will be ignored.
Callback Events
Event | Description |
---|---|
OnShowing | This event fires immediately when the show instance method is called. |
OnShown | This event is fired when an offcanvas element has been made visible to the user (will wait for CSS transitions to complete). |
OnHiding | This event is fired immediately when the hide method has been called. |
OnHidden | This event is fired when an offcanvas element has been hidden from the user (will wait for CSS transitions to complete). |
How it works
Offcanvas is a sidebar component that can be toggled to appear from the left, right, or bottom edge of the viewport.
- Conceptually, they are quite similar to the Modal component, but they are separate components.
- When shown, offcanvas includes a default backdrop that can be clicked to hide the offcanvas.
- Similar to modals, only one offcanvas can be shown at a time.
Examples
Offcanvas
Below is an offcanvas example that is shown by default.
<Button Color="ButtonColor.Primary" @onclick="(async () => { await ShowOffcanvasAsync(); })">Show Offcanvas</Button>
<Offcanvas @ref="offcanvas">
... design your header and body
</Offcanvas>
@code {
private Offcanvas offcanvas;
private async Task ShowOffcanvasAsync()
{
await offcanvas?.ShowAsync();
}
private async Task HideOffcanvasAsync()
{
await offcanvas?.HideAsync();
}
}
Default placement for the offcanvas component is right.
Dynamic component as offcanvas
Render different components dynamically within the offcanvas without iterating through possible types or using conditional logic.
If dynamically-rendered components have component parameters, pass them as an IDictionary
. The string
is the parameter's name, and the object
is the parameter's value.
<Offcanvas @ref="offcanvas" />
<Button Color="ButtonColor.Primary" @onclick="ShowEmployeeComponent">Show Employee Component</Button>
@code {
private Offcanvas offcanvas = default!;
private string? message;
private async Task ShowEmployeeComponent()
{
var parameters = new Dictionary<string, object>();
parameters.Add("EmployeeId", 321);
await offcanvas.ShowAsync<EmployeeDemoComponent1>(title: "Employee Details", parameters: parameters);
}
}
EmployeeDemoComponent1.razor
<div class="row">
<div class="col-5 col-md-4 text-end">Employee Id :</div>
<div class="col-7 col-md-8">@EmployeeId</div>
</div>
<div class="row">
<div class="col-5 col-md-4 text-end">First Name :</div>
<div class="col-7 col-md-8">@employee.FirstName</div>
</div>
<div class="row">
<div class="col-5 col-md-4 text-end">Last Name :</div>
<div class="col-7 col-md-8">@employee.LastName</div>
</div>
@code {
private Employee employee = default!;
[Parameter] public int EmployeeId { get; set; }
protected override void OnInitialized()
{
// get employee with {EmployeeId} from DB
employee = new Employee { FirstName = "Vikram", LastName = "Reddy" };
base.OnInitialized();
}
}
Pass event callbacks to a dynamic component
Event callbacks can be passed in its parameter dictionary.
In the following parent component example, the ShowDTMessage
method assigns a string with the current time to message
, and the value of message
is rendered. The parent component passes the callback method, ShowDTMessage in the parameter dictionary:
- The
string
key is the callback method's name,OnClickCallback
. - The
object
value is created byEventCallbackFactory.Create
for the parent callback method,ShowDTMessage
.
<Offcanvas @ref="offcanvas" />
<Button Color="ButtonColor.Primary" @onclick="ShowEmployeeComponent">Show Employee Component</Button>
<div class="mt-3 bg-success text-white bg-opacity-75">
@message
</div>
@code {
private Offcanvas offcanvas = default!;
private string? message;
private async Task ShowEmployeeComponent()
{
var parameters = new Dictionary<string, object>();
parameters.Add("EmployeeId", 322);
parameters.Add("OnclickCallback", EventCallback.Factory.Create<MouseEventArgs>(this, ShowDTMessage));
await offcanvas.ShowAsync<EmployeeDemoComponent2>(title: "Employee Details", parameters: parameters);
}
private void ShowDTMessage(MouseEventArgs e) => message = $"The current date time is: {DateTime.Now}.";
}
EmployeeDemoComponent2.razor
<div class="row">
<div class="col-5 col-md-4 text-end">Employee Id :</div>
<div class="col-7 col-md-8">@EmployeeId</div>
</div>
<div class="row">
<div class="col-5 col-md-4 text-end">First Name :</div>
<div class="col-7 col-md-8">@employee.FirstName</div>
</div>
<div class="row">
<div class="col-5 col-md-4 text-end">Last Name :</div>
<div class="col-7 col-md-8">@employee.LastName</div>
</div>
<Button class="mt-3" Color="ButtonColor.Success" Type="ButtonType.Button" @onclick="OnClickCallback">
Trigger a Parent component method
</Button>
@code {
private Employee employee = default!;
[Parameter] public int EmployeeId { get; set; }
[Parameter] public EventCallback<MouseEventArgs> OnClickCallback { get; set; }
protected override void OnInitialized()
{
// get employee with {EmployeeId} from DB
employee = new Employee { FirstName = "Sagar", LastName = "Reddy" };
base.OnInitialized();
}
}
Placement
Try the top, bottom, and left examples out below.
<Offcanvas @ref="offcanvas" Title="Offcanvas top" Placement="Placement.Top">
<BodyTemplate>...</BodyTemplate>
</Offcanvas>
<Button Color="ButtonColor.Primary" @onclick="OnShowOffcanvasClick">Show top offcanvas</Button>
@code {
private Offcanvas offcanvas;
private async Task OnShowOffcanvasClick()
{
await offcanvas?.ShowAsync();
}
}
Static backdrop
When UseStaticBackdrop is set to true, the offcanvas will not close when clicking outside of it.
<Offcanvas @ref="offcanvas" Title="Offcanvas title" UseStaticBackdrop="true">
<BodyTemplate>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt blandit mauris. Aliquam sit amet lorem laoreet, laoreet elit ut, placerat tellus. In mollis ultricies elit, volutpat maximus ipsum sodales interdum. Suspendisse eget tellus mollis, rutrum mauris ac, vulputate enim. Cras porta neque vitae lacinia elementum. Nunc sit amet pulvinar nibh. Curabitur interdum eget odio in tempor. Nulla dictum orci quis ligula auctor fermentum. Pellentesque finibus tellus ac massa convallis malesuada. Nam id pharetra velit, sed eleifend mi. Sed sed justo lorem. Quisque et nulla ut dolor feugiat vestibulum. Nunc at porttitor orci, at dignissim metus. Donec vitae metus vitae felis semper placerat.</p>
<p>Proin quis congue enim, ut ultricies erat. Nulla facilisi. Fusce pretium, metus eget tempor vehicula, nisl lorem tincidunt metus, consectetur molestie lorem leo vel lectus. Vivamus pellentesque pharetra mattis. Aenean dignissim quam non velit ultrices rutrum. Aliquam lacinia faucibus sapien vel pretium. Nullam libero massa, ultricies id lacinia nec, scelerisque ut felis. Vivamus ac egestas urna, sit amet condimentum odio. Suspendisse ultrices, libero sed interdum pulvinar, lectus felis pellentesque enim, eu finibus magna massa id augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eget tempor libero. Cras ut interdum purus. Donec eu pulvinar urna, ut porttitor purus. Suspendisse sed sodales nunc. Quisque posuere augue sed luctus placerat.</p>
<p>Morbi ullamcorper risus turpis, et ullamcorper nulla semper vitae. Proin pharetra dolor dui, non condimentum ex fermentum in. Vestibulum pharetra, risus et pulvinar eleifend, nulla tortor blandit risus, ac imperdiet elit massa quis leo. Vivamus urna lacus, luctus eget felis id, eleifend tristique nisl. Sed dignissim mollis ligula vitae laoreet. Vestibulum eget magna nisi. Aenean auctor elit et turpis blandit, eget porttitor felis suscipit. Duis placerat, sapien a sodales tempus, odio orci malesuada neque, ac molestie ipsum nisi vel eros. Integer sem lectus, luctus vitae sapien ut, efficitur aliquam sem. Praesent placerat est eros, vulputate rutrum nunc imperdiet vitae. Fusce sed felis eget purus aliquet convallis eu eget lacus. Sed finibus nec magna et accumsan. Donec vitae tellus eros. Nullam et ex vitae est sagittis malesuada. Vivamus molestie malesuada libero, a consequat magna dapibus pellentesque. Cras molestie tortor vitae congue pretium.</p>
<p>Pellentesque nec iaculis justo, sed pretium sem. Mauris finibus lacus at mollis fringilla. Etiam auctor in justo ac bibendum. Vestibulum at lorem accumsan, maximus erat suscipit, suscipit ex. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris dignissim id quam sit amet varius. Etiam pretium ultrices dignissim. Cras at tortor hendrerit metus ultrices lobortis at ac est. Suspendisse consectetur pellentesque nunc sit amet scelerisque. Maecenas feugiat nunc laoreet, auctor erat eget, ultricies ex. Aliquam nisi nulla, cursus et ante ut, interdum volutpat leo. Phasellus laoreet aliquam maximus. Vestibulum eu neque porta, consectetur ipsum non, euismod enim. Vestibulum euismod purus elit, ultrices imperdiet nisl porttitor eget. Vivamus eros turpis, tincidunt a vulputate vel, malesuada tristique nulla.</p>
<p>Vestibulum sed aliquam urna. Ut ullamcorper erat vitae velit mattis commodo. Phasellus dignissim rhoncus dapibus. Quisque congue egestas tellus id finibus. Suspendisse nibh felis, mattis et finibus vel, tempor in lectus. Nullam eget eros dui. Mauris eget vestibulum nibh. Nullam mattis malesuada lorem vel condimentum. Mauris id odio ac est feugiat condimentum.</p>
</BodyTemplate>
<FooterTemplate>
<Button Color="ButtonColor.Secondary" @onclick="() => offcanvas?.HideAsync()">Close</Button>
</FooterTemplate>
</Offcanvas>
<Button Color="ButtonColor.Primary" @onclick="OnShowOffcanvasClick">Show offcanvas</Button>
@code {
private Offcanvas offcanvas;
private async Task OnShowOffcanvasClick()
{
await offcanvas?.ShowAsync();
}
}
Sizes
Set the size of the Offcanvas
with the Size parameter. The default value is OffcanvasSize.Regular
.
Small Offcanvas
<Offcanvas @ref="offcanvas" Title="Offcanvas title" Size="OffcanvasSize.Small">
<BodyTemplate>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt blandit mauris. Aliquam sit amet lorem laoreet, laoreet elit ut, placerat tellus. In mollis ultricies elit, volutpat maximus ipsum sodales interdum. Suspendisse eget tellus mollis, rutrum mauris ac, vulputate enim. Cras porta neque vitae lacinia elementum. Nunc sit amet pulvinar nibh. Curabitur interdum eget odio in tempor. Nulla dictum orci quis ligula auctor fermentum. Pellentesque finibus tellus ac massa convallis malesuada. Nam id pharetra velit, sed eleifend mi. Sed sed justo lorem. Quisque et nulla ut dolor feugiat vestibulum. Nunc at porttitor orci, at dignissim metus. Donec vitae metus vitae felis semper placerat.</p>
<p>Proin quis congue enim, ut ultricies erat. Nulla facilisi. Fusce pretium, metus eget tempor vehicula, nisl lorem tincidunt metus, consectetur molestie lorem leo vel lectus. Vivamus pellentesque pharetra mattis. Aenean dignissim quam non velit ultrices rutrum. Aliquam lacinia faucibus sapien vel pretium. Nullam libero massa, ultricies id lacinia nec, scelerisque ut felis. Vivamus ac egestas urna, sit amet condimentum odio. Suspendisse ultrices, libero sed interdum pulvinar, lectus felis pellentesque enim, eu finibus magna massa id augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eget tempor libero. Cras ut interdum purus. Donec eu pulvinar urna, ut porttitor purus. Suspendisse sed sodales nunc. Quisque posuere augue sed luctus placerat.</p>
<p>Morbi ullamcorper risus turpis, et ullamcorper nulla semper vitae. Proin pharetra dolor dui, non condimentum ex fermentum in. Vestibulum pharetra, risus et pulvinar eleifend, nulla tortor blandit risus, ac imperdiet elit massa quis leo. Vivamus urna lacus, luctus eget felis id, eleifend tristique nisl. Sed dignissim mollis ligula vitae laoreet. Vestibulum eget magna nisi. Aenean auctor elit et turpis blandit, eget porttitor felis suscipit. Duis placerat, sapien a sodales tempus, odio orci malesuada neque, ac molestie ipsum nisi vel eros. Integer sem lectus, luctus vitae sapien ut, efficitur aliquam sem. Praesent placerat est eros, vulputate rutrum nunc imperdiet vitae. Fusce sed felis eget purus aliquet convallis eu eget lacus. Sed finibus nec magna et accumsan. Donec vitae tellus eros. Nullam et ex vitae est sagittis malesuada. Vivamus molestie malesuada libero, a consequat magna dapibus pellentesque. Cras molestie tortor vitae congue pretium.</p>
<p>Pellentesque nec iaculis justo, sed pretium sem. Mauris finibus lacus at mollis fringilla. Etiam auctor in justo ac bibendum. Vestibulum at lorem accumsan, maximus erat suscipit, suscipit ex. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris dignissim id quam sit amet varius. Etiam pretium ultrices dignissim. Cras at tortor hendrerit metus ultrices lobortis at ac est. Suspendisse consectetur pellentesque nunc sit amet scelerisque. Maecenas feugiat nunc laoreet, auctor erat eget, ultricies ex. Aliquam nisi nulla, cursus et ante ut, interdum volutpat leo. Phasellus laoreet aliquam maximus. Vestibulum eu neque porta, consectetur ipsum non, euismod enim. Vestibulum euismod purus elit, ultrices imperdiet nisl porttitor eget. Vivamus eros turpis, tincidunt a vulputate vel, malesuada tristique nulla.</p>
<p>Vestibulum sed aliquam urna. Ut ullamcorper erat vitae velit mattis commodo. Phasellus dignissim rhoncus dapibus. Quisque congue egestas tellus id finibus. Suspendisse nibh felis, mattis et finibus vel, tempor in lectus. Nullam eget eros dui. Mauris eget vestibulum nibh. Nullam mattis malesuada lorem vel condimentum. Mauris id odio ac est feugiat condimentum.</p>
</BodyTemplate>
<FooterTemplate>
<Button Color="ButtonColor.Secondary" @onclick="() => offcanvas?.HideAsync()">Close</Button>
</FooterTemplate>
</Offcanvas>
<Button Color="ButtonColor.Primary" @onclick="OnShowOffcanvasClick">Show small offcanvas</Button>
@code {
private Offcanvas offcanvas;
private async Task OnShowOffcanvasClick()
{
await offcanvas?.ShowAsync();
}
}
Large Offcanvas
<Offcanvas @ref="offcanvas" Title="Offcanvas title" Size="OffcanvasSize.Large">
<BodyTemplate>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec tincidunt blandit mauris. Aliquam sit amet lorem laoreet, laoreet elit ut, placerat tellus. In mollis ultricies elit, volutpat maximus ipsum sodales interdum. Suspendisse eget tellus mollis, rutrum mauris ac, vulputate enim. Cras porta neque vitae lacinia elementum. Nunc sit amet pulvinar nibh. Curabitur interdum eget odio in tempor. Nulla dictum orci quis ligula auctor fermentum. Pellentesque finibus tellus ac massa convallis malesuada. Nam id pharetra velit, sed eleifend mi. Sed sed justo lorem. Quisque et nulla ut dolor feugiat vestibulum. Nunc at porttitor orci, at dignissim metus. Donec vitae metus vitae felis semper placerat.</p>
<p>Proin quis congue enim, ut ultricies erat. Nulla facilisi. Fusce pretium, metus eget tempor vehicula, nisl lorem tincidunt metus, consectetur molestie lorem leo vel lectus. Vivamus pellentesque pharetra mattis. Aenean dignissim quam non velit ultrices rutrum. Aliquam lacinia faucibus sapien vel pretium. Nullam libero massa, ultricies id lacinia nec, scelerisque ut felis. Vivamus ac egestas urna, sit amet condimentum odio. Suspendisse ultrices, libero sed interdum pulvinar, lectus felis pellentesque enim, eu finibus magna massa id augue. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis eget tempor libero. Cras ut interdum purus. Donec eu pulvinar urna, ut porttitor purus. Suspendisse sed sodales nunc. Quisque posuere augue sed luctus placerat.</p>
<p>Morbi ullamcorper risus turpis, et ullamcorper nulla semper vitae. Proin pharetra dolor dui, non condimentum ex fermentum in. Vestibulum pharetra, risus et pulvinar eleifend, nulla tortor blandit risus, ac imperdiet elit massa quis leo. Vivamus urna lacus, luctus eget felis id, eleifend tristique nisl. Sed dignissim mollis ligula vitae laoreet. Vestibulum eget magna nisi. Aenean auctor elit et turpis blandit, eget porttitor felis suscipit. Duis placerat, sapien a sodales tempus, odio orci malesuada neque, ac molestie ipsum nisi vel eros. Integer sem lectus, luctus vitae sapien ut, efficitur aliquam sem. Praesent placerat est eros, vulputate rutrum nunc imperdiet vitae. Fusce sed felis eget purus aliquet convallis eu eget lacus. Sed finibus nec magna et accumsan. Donec vitae tellus eros. Nullam et ex vitae est sagittis malesuada. Vivamus molestie malesuada libero, a consequat magna dapibus pellentesque. Cras molestie tortor vitae congue pretium.</p>
<p>Pellentesque nec iaculis justo, sed pretium sem. Mauris finibus lacus at mollis fringilla. Etiam auctor in justo ac bibendum. Vestibulum at lorem accumsan, maximus erat suscipit, suscipit ex. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris dignissim id quam sit amet varius. Etiam pretium ultrices dignissim. Cras at tortor hendrerit metus ultrices lobortis at ac est. Suspendisse consectetur pellentesque nunc sit amet scelerisque. Maecenas feugiat nunc laoreet, auctor erat eget, ultricies ex. Aliquam nisi nulla, cursus et ante ut, interdum volutpat leo. Phasellus laoreet aliquam maximus. Vestibulum eu neque porta, consectetur ipsum non, euismod enim. Vestibulum euismod purus elit, ultrices imperdiet nisl porttitor eget. Vivamus eros turpis, tincidunt a vulputate vel, malesuada tristique nulla.</p>
<p>Vestibulum sed aliquam urna. Ut ullamcorper erat vitae velit mattis commodo. Phasellus dignissim rhoncus dapibus. Quisque congue egestas tellus id finibus. Suspendisse nibh felis, mattis et finibus vel, tempor in lectus. Nullam eget eros dui. Mauris eget vestibulum nibh. Nullam mattis malesuada lorem vel condimentum. Mauris id odio ac est feugiat condimentum.</p>
</BodyTemplate>
<FooterTemplate>
<Button Color="ButtonColor.Secondary" @onclick="() => offcanvas?.HideAsync()">Close</Button>
</FooterTemplate>
</Offcanvas>
<Button Color="ButtonColor.Primary" @onclick="OnShowOffcanvasClick">Show large offcanvas</Button>
@code {
private Offcanvas offcanvas;
private async Task OnShowOffcanvasClick()
{
await offcanvas?.ShowAsync();
}
}
Callback Events
BlazorBootstrap's offcanvas component exposes a few events for hooking into offcanvas functionality.
<Offcanvas @ref="offcanvas"
title="Offcanvas title"
OnShowing="OnOffcanvasShowingAsync"
OnShown="OnOffcanvasShownAsync"
OnHiding="OnOffcanvasHidingAsync"
OnHidden="OnOffcanvasHiddenAsync">
<BodyTemplate>
<div>Some text as placeholder. In real life you can have the elements you have chosen. Like, text, images, lists, etc.</div>
</BodyTemplate>
<FooterTemplate>
<Button Color="ButtonColor.Primary" @onclick="OnHideOffcanvasClick">Hide Offcanvas</Button>
</FooterTemplate>
</Offcanvas>
<Button Color="ButtonColor.Primary" @onclick="OnShowOffcanvasClick">Show offcanvas</Button>
@code {
private Offcanvas offcanvas;
private async Task OnShowOffcanvasClick()
{
await offcanvas?.ShowAsync();
}
private async Task OnHideOffcanvasClick()
{
await offcanvas?.HideAsync();
}
private async Task OnOffcanvasShowingAsync()
{
await Task.Run(() => { Console.WriteLine("Event: Showing"); });
}
private async Task OnOffcanvasShownAsync()
{
await Task.Run(() => { Console.WriteLine("Event: Shown"); });
}
private async Task OnOffcanvasHidingAsync()
{
await Task.Run(() => { Console.WriteLine("Event: Hiding"); });
}
private async Task OnOffcanvasHiddenAsync()
{
await Task.Run(() => { Console.WriteLine("Event: Hidden"); });
}
}