I'm playing with the Bootstrap 5 off-canvas feature. I am trying to get a button to attach to the side of the off-canvas slide out drawer. So when the drawer is off-canvas, the button is visible. When the button is clicked, the drawer slides out but instead of overlaying the drawer content over the button, the button acts as if it's attached to the slide out drawer and moves with it. Like this:
I'm not sure if this is possible. If so, how would I go about doing this?
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<div class="offcanvas offcanvas-start" id="demo">
<div class="offcanvas-header">
<h1 class="offcanvas-title">Heading</h1>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
<p>Some text lorem ipsum.</p>
</div>
</div>
<div class="container-fluid mt-3">
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#demo">
Open
</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
You could apply sideward translation with transition to match that of the sidebar when the panel is open. I'm using a div around the button because the button has transitions on it already, and I'm raising its stacking order to be above the sidebar mask.
.offcanvas-btn-box {
transition: transform .3s ease-in-out; /* same as what's on the panel */
}
.offcanvas.show + div .offcanvas-btn-box {
transform: translateX(400px);
position: relative;
z-index: 1100;
}
/* optional junk to toggle the button text */
.offcanvas-btn-box .btn span:last-child,
.offcanvas.show + div .offcanvas-btn-box .btn span:first-child {
display: none;
}
.offcanvas.show + div .offcanvas-btn-box .btn span:last-child {
display: inline;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<div class="offcanvas offcanvas-start" id="demo">
<div class="offcanvas-header">
<h1 class="offcanvas-title">Heading</h1>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
<p>Some text lorem ipsum.</p>
</div>
</div>
<div class="container-fluid mt-3">
<div class="offcanvas-btn-box">
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#demo">
<span>Open</span><span>Close</span>
</button>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
Alternatively, put the button inside the panel and position it absolutely. This has the benefit of not cluttering your main page layout.
.offcanvas-btn {
left: 420px;
visibility: visible;
}
/* optional junk to toggle the button text */
.offcanvas-btn span:last-child,
.offcanvas.show .offcanvas-btn span:first-child {
display: none;
}
.offcanvas.show .offcanvas-btn span:last-child {
display: inline;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<div class="offcanvas offcanvas-start" id="demo">
<button class="btn btn-primary offcanvas-btn position-absolute mt-2" type="button" data-bs-toggle="offcanvas" data-bs-target="#demo">
<span>Open</span><span>Close</span>
</button>
<div class="offcanvas-header">
<h1 class="offcanvas-title">Heading</h1>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
</div>
<div class="offcanvas-body">
<p>Some text lorem ipsum.</p>
</div>
</div>
<div class="container-fluid mt-4 pt-4">
Some page content.
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With