In this tutorial we will use the Bootstrap 3 grid system and some CSS and jQuery to create three separate solutions:
This approach works with both fixed and fluid containers.
Collapsible left sidebar
Bootstrap 3 has a responsive grid system with 12 columns. Our sidebar will occupy 3 columns and the remaining 9 columns will be used for the content.
It’s important to know this as it will influence the implementation. You should adapt the solution to your desired size.
<div class="container">
<div class="row" id="row-main">
<div class="col-md-3" id="sidebar">
...
</div>
<div class="col-md-9" id="content">
...
</div>
</div>
</div>
The following will happen when collapsing the sidebar:
- The sidebar will be hidden
- The content container will occupy the space left available by the sidebar
In our case the content container will go from occupying 9 columns to occupying all 12.
Another consideration is how the sidebar will be hidden. We’ll implement it in two ways:
- For large displays we’ll use a negative left margin (with the same width as the sidebar) so we can animate the transition
- For small displays, since each column is broken into its own line, we’ll just hide the sidebar when collapsed
.collapsed {
display: none; /* hide it for small displays */
}
@media (min-width: 992px) {
.collapsed {
display: block;
margin-left: -25%; /* same width as sidebar */
}
}
Notice the media query breakpoint. We are using the appropriate min-width breakpoint for medium-sized columns (.col-md-
). You need to adapt this if you are using columns of a different size.
Since we are assigning a negative left margin, the sidebar will be pushed off the container. We need to hide it. We do that by setting the overflow on the main row.
#row-main {
overflow-x: hidden; /* necessary to hide collapsed sidebar */
}
Now the only thing left to do is to handle the animation.
#content {
-webkit-transition: width 0.3s ease;
-moz-transition: width 0.3s ease;
-o-transition: width 0.3s ease;
transition: width 0.3s ease;
}
#sidebar {
-webkit-transition: margin 0.3s ease;
-moz-transition: margin 0.3s ease;
-o-transition: margin 0.3s ease;
transition: margin 0.3s ease;
}
And when we want to toggle the sidebar, we just switch the appropriate CSS classes:
$("#sidebar").toggleClass("collapsed");
$("#content").toggleClass("col-md-12 col-md-9");
Collapsible right sidebar
As you can imagine, having the sidebar on the right doesn’t require a very different solution.
The HTML will have a small adjustment – the sidebar will appear after the content container.
<div class="container">
<div class="row" id="row-main">
<div class="col-md-9" id="content">
...
</div>
<div class="col-md-3" id="sidebar">
...
</div>
</div>
</div>
The only other thing that changes in the solution is that the margin will be applied to the right side:
@media (min-width: 992px) {
.collapsed {
display: block;
margin-right: -25%; /* same width as sidebar */
}
}
The rest will remain the same.
Collapsible sidebar on both sides
Having sidebars on both sides makes the solution just a little bit trickier.
The HTML structure now includes two sidebars.
<div class="container">
<div class="row" id="row-main">
<div class="col-md-3 sidebar" id="sidebar-left">
...
</div>
<div class="col-md-6" id="content">
...
</div>
<div class="col-md-3 sidebar" id="sidebar-right">
...
</div>
</div>
</div>
We accommodate the CSS to take into account the different collapsed states.
@media (min-width: 992px) {
.collapsed {
display: block;
}
#sidebar-left.collapsed {
margin-left: -25%; /* same width as sidebar */
}
#sidebar-right.collapsed {
margin-right: -25%; /* same width as sidebar */
}
}
Since both sidebars now share a common class, we also need to update the transition code.
.sidebar {
-webkit-transition: margin 0.3s ease;
-moz-transition: margin 0.3s ease;
-o-transition: margin 0.3s ease;
transition: margin 0.3s ease;
}
On the Javascript side things get more complicated since now we have to consider 3 different widths for the content container.
To collapse or expand a sidebar we need to:
- Toggle the
collapsed
class on the sidebar - Find the number of open sidebars
- Determine the appropriate content class according to the number of open sidebars
- Apply the correct class to the content container
The content container will switch between 6, 9, or 12 columns, since each sidebar occupies 3 columns exactly.
function toggleSidebar(side) {
if (side !== "left" && side !== "right") {
return false;
}
var left = $("#sidebar-left"),
right = $("#sidebar-right"),
content = $("#content"),
openSidebarsCount = 0,
contentClass = "";
// toggle sidebar
if (side === "left") {
left.toggleClass("collapsed");
} else if (side === "right") {
right.toggleClass("collapsed");
}
// determine number of open sidebars
if (!left.hasClass("collapsed")) {
openSidebarsCount += 1;
}
if (!right.hasClass("collapsed")) {
openSidebarsCount += 1;
}
// determine appropriate content class
if (openSidebarsCount === 0) {
contentClass = "col-md-12";
} else if (openSidebarsCount === 1) {
contentClass = "col-md-9";
} else {
contentClass = "col-md-6";
}
// apply class to content
content.removeClass("col-md-12 col-md-9 col-md-6")
.addClass(contentClass);
}
We can toggle the sidebar by calling the above function with the appropriate parameter.
toggleSidebar("left");
Conclusion
With Bootstrap 3, jQuery and some CSS magic we built a collapsible sidebar with expandable content.
You can find the source code at GitHub or in the 3 examples: