Based on my understanding of my question, I believe that your requirements are as such:
- Use accordion to allow hiding of column contents when screen sizes are mobile (in bootstrap terms, that will be a width less than the
md
designation).
- Use normal grid layout when width is wider than mobile (width greater than the
md
designation).
Note that the md
designation refers to a width of 992px :) that will come into handy in our solution.
There are several ways to tackle your issue: we can use a pure JS-based solution where we dynamically create and destroy an accordion based on viewport width, listened on by the $(window).resize()
event, but that is highly inefficient and extremely unperformant (unless you throttle the event, which brings around another host of issues such as responsiveness).
The solution I have explored will be simply to use a standard bootstrap accordion/collapsible markup, with some simple CSS tricky to get it to work:
- We assume a default layout of accordions, but built in some grid classes for use in wider viewports
- We use
@media (min-width: <md-width>)
, a.k.a. @media (min-width: 992px)
to override certain styles in the accordion panels so that they do not interfere with grid layout at wider viewports.
With that in mind, we can look into structuring your markup as such:
.container
.row
.panel-group
, which houses all your accordion things
.panel
, which houses your panel content. This can be repeated for as many columns/panels you want
.panel-heading
+ .visible-xs .visible-sm
so that the nested panel controls are visible only at narrow viewports (sizes < md
)
.panel-collapse
+ .col-md-4
, the content of your individual panel/columns with the appropriate width for grid layout
With this structure in mind, here is a template that can be reused for all panels:
<!-- First panel/column -->
<div class="panel">
<!-- Panel heading, visible at screen sizes < md (i.e. xs and sm only) -->
<div class="panel-heading visible-xs visible-sm">
<h1 class="panel-title">
<a href="#col1" data-parent="#accordion" data-toggle="collapse" aria-expanded="true" aria-controls="col1">Column 1</a>
</h1>
</div>
<!-- Panel content -->
<div id="col1" class="col-md-4 panel-collapse collapse in" role="tabpanel" aria-labelledby="col1">
<!-- Insert content here -->
</div>
</div>
Note: I do not see a utility for a nav-toggle here, because it is typically used to stash additional navigation links away when the viewport is too narrow. However, if you insist on using it, you can modify your markup within .panel-heading
as such:
<h1 class="panel-title navbar navbar-default">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#col1" aria-expanded="true" aria-controls="col1">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#col1" data-parent="#accordion" data-toggle="collapse" aria-expanded="true" aria-controls="col1">Column 1</a>
</div>
</h1>
Remember the default panel styles? They add a margin and border to the .panel
elements which interferes with grid layout, and the .panel-collapse
are hidden when the .collapse
class is present. For that, we simply want a media query that disables these styles at width greater than or equals to the md
designation, i.e. @media (min-width: 992px)
, so that
.panel-collapse.collapse
will be forced to display (i.e. panels should be displayed regardless if they have been collapsed or not in narrow viewports)
.panel
should not have margins and borders that interfere with grid layout
Therefore, we do this:
@media (min-width: 992px) {
#accordion .panel-collapse.collapse {
display: block !important;
height: auto !important;
overflow: visible !important;
}
#accordion .panel {
margin: 0;
border: none;
}
}
With all these in mind, here is a proof-of-concept example (you can also refer to an example on jsfiddle). Note that you will have to run the code snippet and then open/expand it in full view, so that you can play around with different viewport sizes :)
@media (min-width: 992px) {
#accordion .panel-collapse.collapse {
display: block !important;
height: auto !important;
overflow: visible !important;
}
#accordion .panel {
margin: 0;
border: none;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="false">
<!-- First panel/column -->
<div class="panel">
<div class="panel-heading visible-xs visible-sm">
<h1 class="panel-title">
<a href="#col1" data-parent="#accordion" data-toggle="collapse" aria-expanded="true" aria-controls="col1">Column 1</a>
</h1>
</div>
<div id="col1" class="col-md-4 panel-collapse collapse in" role="tabpanel" aria-labelledby="col1">
<h2>Column/Panel header 1</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Soluta dignissimos unde nemo sed necessitatibus vitae ipsum, maxime quaerat dolorum dolorem</p>
</div>
</div>
<!-- Second panel/column -->
<div class="panel">
<div class="panel-heading visible-xs visible-sm">
<h1 class="panel-title">
<a href="#col2" data-parent="#accordion" data-toggle="collapse" aria-expanded="false" aria-controls="col2">Column 2</a>
</h1>
</div>
<div id="col2" class="col-md-4 panel-collapse collapse" role="tabpanel" aria-labelledby="col2">
<h2>Column/Panel header 2</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Soluta dignissimos unde nemo sed necessitatibus vitae ipsum, maxime quaerat dolorum dolorem</p>
</div>
</div>
<!-- Third panel/column -->
<div class="panel">
<div class="panel-heading visible-xs visible-sm">
<h1 class="panel-title">
<a href="#col3" data-parent="#accordion" data-toggle="collapse" aria-expanded="false" aria-controls="col3">Column 3</a>
</h1>
</div>
<div id="col3" class="col-md-4 panel-collapse collapse" role="tabpanel" aria-labelledby="col3">
<h2>Column/Panel header 3</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Soluta dignissimos unde nemo sed necessitatibus vitae ipsum, maxime quaerat dolorum dolorem</p>
</div>
</div>
</div>
</div>