Reputation: 6610
I am using bootstrap generic offcanvas which is working fine. However, I want to expand collapse the sidebar
when the screen width is more than 768px with css3 synchronized animation on both the div
s. I want css only method to do this, if css not working, then jquery also fine.
Here is what I tried so far and here is a fullscreen view.
Since I used width: 0;
and height: 0;
for #sidebar
div, it is not animating nicely. Is there any way to do so with the existing offcanvas method? I don't want to change the HTML markup.
HTML
<!-- Navbar Tag Removed to reduce space -->
<!-- /.navbar -->
<div class="container">
<div class="row row-offcanvas row-offcanvas-left">
<div class="col-xs-8 col-sm-3 sidebar-offcanvas" id="sidebar" role="navigation">
<h4>Menu</h4>
<!-- Content Removed -->
</div>
<!--/span-->
<div class="col-xs-12 col-sm-9 col-main">
<p>
<button type="button" class="btn btn-primary btn-xs" data-toggle="offcanvas">Toggle
nav</button>
</p>
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>This is an example to show the potential of an offcanvas layout pattern in Bootstrap.
Try some responsive-range viewport sizes to see it in action.</p>
</div>
<!-- Content Removed -->
<!--/row-->
</div>
<!--/span-->
</div>
<!--/row-->
</div>
<!--/.container-->
CSS
html, body {
overflow-x: hidden; /* Prevent scroll on narrow devices */
}
@media (min-width: 768px) {
html, body {
overflow-x: auto; /* allow scroll */
}
.container {
max-width: 100%;
width: 100%;
}
/*Off Canvas */
.sidebar-offcanvas, .col-main {
position: relative;
-webkit-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.side-toggle .sidebar-offcanvas {
left: -100%;
width: 0;
height: 0;
}
.side-toggle .col-main {
width:100%;
}
}
JQUERY
$(document).ready(function () {
if ($(window).width() < 768) {
$('[data-toggle="offcanvas"]').click(function () {
$('.row-offcanvas').toggleClass('active');
});
}
if ($(window).width() > 768){
$('[data-toggle="offcanvas"]').click(function () {
$('.row-offcanvas').toggleClass('side-toggle');
});
}
});
$(window).resize(function () {
if ($(window).width() < 768) {
$('[data-toggle="offcanvas"]').click(function () {
$('.row-offcanvas').toggleClass('active');
});
}
if ($(window).width() > 768){
$('[data-toggle="offcanvas"]').click(function () {
$('.row-offcanvas').toggleClass('side-toggle');
});
}
});
Update
#sidebar
and .col-main
divs. The #sidebar
needed to be hidden with linear animation whereas the .col-main'
div's width should be expanded to 100% width and vice versa when clicking again.Upvotes: 2
Views: 8693
Reputation: 6610
Finally I got to manage the desired output with the help of the answer given by @matty. I also used jquery cookie to retain the viewstate of the sidebar after refreshing the page (post back).
HTML markup is as it is. However, I used the following CSS:
html, body {
overflow-x: hidden; /* Prevent scroll on narrow devices */
}
@media (min-width: 768px) {
html, body {
overflow-x: auto; /* allow scroll */
}
.container {
max-width: 100%;
width: 100%;
}
/** Off Canvas **/
.sidebar-offcanvas, .col-main {
position: relative;
}
.animate .sidebar-offcanvas, .animate .col-main {
-webkit-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.side-toggle .sidebar-offcanvas {
width: 0;
padding: 0;
overflow: hidden;
}
.side-toggle .col-main {
width: 100%;
}
}
@media screen and (max-width: 767px) {
/** Off Canvas **/
.row-offcanvas {
position: relative;
-webkit-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.row-offcanvas-right {
right: 0;
}
.row-offcanvas-left {
left: 0;
}
.row-offcanvas-right .sidebar-offcanvas {
right: -66.66666667%; /* 8 columns */
}
.row-offcanvas-left .sidebar-offcanvas {
left: -66.66666667%; /* 8 columns */
}
.row-offcanvas-right.active {
right: 66.66666667%; /* 8 columns */
}
.row-offcanvas-left.active {
left: 66.66666667%; /* 8 columns */
}
.sidebar-offcanvas {
position: absolute;
top: 0;
width: 66.66666667%; /* 8 columns */
}
.row-offcanvas-left .sidebar-offcanvas {
margin-left: 15px;
}
}
Also, I used jquery Cookie plugin to store the collapsed or expanded state of the sidebar in browser cookies. The script I used is:
$(document).ready(function () {
var toggle = $.cookie('toggle');
if ($(window).width() > 768 && toggle === "hide") {
$('.row-offcanvas').addClass('side-toggle');
}
$('[data-toggle="offcanvas"]').click(function () {
$('.row-offcanvas').toggleClass('active').toggleClass('side-toggle');
if ($('#sidebar').parent().hasClass('active')) {
$.cookie('toggle', 'hide');
}
if (toggle === "hide") {
$.removeCookie('toggle');
}
});
$(window).resize(function () {
if ($(window).width() < 768) {
$('.row-offcanvas').removeClass('animate');
} else {
$('.row-offcanvas').addClass('animate');
}
if ($(window).width() > 768 && toggle === "hide") {
$('.row-offcanvas').addClass('side-toggle');
}
});
$(window).trigger('resize');
});
JsBin Edit is here and Full screen preview is here. Please let me know, if you've any doubts/clarifications.
Thanks again matty to bring me in the right direction.
Upvotes: 1
Reputation: 1427
Is it what you want? http://jsbin.com/yageheruludo/4/edit
I changed JS:
$('[data-toggle="offcanvas"]').click(function () {
$('.row-offcanvas').toggleClass('active').toggleClass('side-toggle');
});
$(window).resize(function () {
if ($(window).width() < 768) {
$('.row-offcanvas').removeClass('animate');
} else {
$('.row-offcanvas').addClass('animate');
}
});
and CSS:
.sidebar-offcanvas, .col-main {
position: relative;
}
.animate .sidebar-offcanvas, .animate .col-main {
-webkit-transition: all .25s ease-out;
-o-transition: all .25s ease-out;
transition: all .25s ease-out;
}
.side-toggle .sidebar-offcanvas {
width: 0;
padding: 0;
overflow: hidden;
}
edit
Before first window resize the animation doesn't work.
http://jsbin.com/yageheruludo/6/edit
Change js to this:
$('[data-toggle="offcanvas"]').click(function () {
$('.row-offcanvas').toggleClass('active').toggleClass('side-toggle');
});
$(window).resize(function () {
if ($(window).width() < 768) {
$('.row-offcanvas').removeClass('animate');
} else {
$('.row-offcanvas').addClass('animate');
}
});
$(window).trigger('resize'); // added this line
What do you mean "not animating (...) after change the duration"? You mean "orientation"?
Upvotes: 6
Reputation: 43728
Part of the problem is your resize
handler. Every time the window is resized, you add another click handler, so if you resize the window twice, there will be 2 click handlers that will toggle the class twice, putting it right back where it was.
Should be closer to:
$(window).resize(function () {
if ($(window).width() < 768) {
$('.row-offcanvas').toggleClass('active');
}
if ($(window).width() > 768){
$('.row-offcanvas').toggleClass('side-toggle');
}
});
But even that isn't quite right, because it will toggle the class on each resize event, so as the user tries to resize the window, the div will keep changing as they drag the window to resize it.
Maybe what you actually want is:
$(window).resize(function () {
if ($(window).width() < 768) {
$('.row-offcanvas').addClass('active');
$('.row-offcanvas').removeClass('side-toggle');
} else {
$('.row-offcanvas').removeClass('active');
$('.row-offcanvas').addClass('side-toggle');
}
});
I don't know if that is the entire problem, but it is definitely part of it.
Upvotes: 1