accordion
by Joe Dooley
HTML
<div class="big-container">
<div class="foo">
<h2>Hello World</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure</p>
<p>dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
<p>dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
<button id="open-nested">openinner</button>
<button id="close-nested">close inner</button>
<div class="inner-container">
<div class="bar">
<p>dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
</div>
</div>
</div>
</div>
<button id="open-main">open</button>
<button id="close-main">close</button>hello blah bljld jlj jlk
SCSS
.big-container {
width : 400px;
overflow : hidden;
opacity : 0;
transition : height 1s, opacity 1s;
}
.foo {
padding : 10px;
}
.inner-container {
height : 0;
overflow : hidden;
transition : height 1s, opacity 1s;
opacity : 0;
}
.bar {
}
#open {
background : cornflowerblue;
padding : 10px 10px;
border : none;
margin : 12px 0;
outline : none;
position : relative;
}
JavaScript
// main and nested container elements
var $main = $('.big-container');
var $nested = $('.inner-container');
// this has to be done at initialisation
var mainHeight = getMainHeight();
// flags for open/close state of containers
var mainOpen = false;
var nestedOpen = false;
// open main container
function openMain() {
if (!mainOpen) {
mainOpen = true;
$main.css({
height: mainHeight,
opacity: 1
});
}
}
// close main: have to also close nested container if it is open
function closeMain() {
if (mainOpen) {
nestedOpen = false;
// need to close nested container too
$nested.css({
height: 0,
opacity: 0
});
mainOpen = false;
// set height and opacity to 0
$main.css({
'height': 0,
opacity: 0
});
}
}
// have to work out initial height before opening
function getMainHeight() {
// set height to auto value, measure, then reset to 0
$main.css({
height: 'auto'
});
var height = $main.height();
$main.css({
height: 0
});
return height;
}
// open nested. Set height of main container to 'auto' to allow it resize when nested
// container opens. After nested container has opened, reset main container height
// back to numeric value.
function openNested() {
if (!nestedOpen) {
nestedOpen = true;
function afterTransition() {
var mainHeight = $main.height();
$main.css({
height: mainHeight
});
$nested[0].removeEventListener("transitionend", afterTransition);
}
$main.css({
height: 'auto'
});
$nested[0].addEventListener("transitionend", afterTransition, false);
$nested.css({
height: 100,
opacity: 1
});
}
}
// close nested container. Set main container height to 'auto'...