Reputation: 3083
I simply want the contents of the HTML5 details tag to 'glide'/animate open rather than just pop open/appear instantly. Is this possible with jQuery/Javascript?
HTML:
<details>
<summary>Show/Hide</summary>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum laoreet metus auctor tempor dignissim. Nunc tempor ligula malesuada, adipiscing justo quis, ultrices libero. Curabitur pretium odio sagittis lorem euismod, a ultrices sem ultrices. Integer sapien nibh, mollis id pretium id, dignissim ut dui. Nam sit amet lectus lectus. Cras scelerisque risus a dui accumsan, in dignissim dolor sodales. Nunc aliquam pharetra dui, a consectetur velit lobortis vel.</p>
<p>Mauris convallis orci in semper aliquam. Ut mollis laoreet nibh pretium tincidunt. Donec aliquam at odio sit amet dictum. Phasellus sapien leo, feugiat sit amet sagittis in, congue vel lectus. Donec elementum est vitae nulla interdum laoreet. Curabitur fringilla a tellus non laoreet. Aliquam vel lectus convallis massa pulvinar pellentesque. Mauris laoreet pharetra turpis vel tristique. Sed ligula ligula, sodales sed auctor in, aliquam sit amet lorem. Etiam vestibulum, libero vel dignissim ultrices, lacus mauris lacinia enim, quis aliquam nibh mauris eu mauris. Etiam sapien leo, dapibus et libero sed, laoreet ornare tellus.</p>
<p>Sed placerat vehicula magna et adipiscing. Nam euismod nibh ut tellus tempor, eget lobortis metus iaculis. In laoreet, enim in dignissim pellentesque, felis augue tincidunt massa, vestibulum fringilla mauris sapien in diam. Duis interdum molestie fermentum. Aenean dictum varius augue, id luctus neque viverra id. Nam eleifend tempus mauris in mattis. Sed id risus non magna semper blandit in vel arcu. Suspendisse quis nisi ligula. Fusce vestibulum at enim eu.</p>
</details>
Upvotes: 3
Views: 3585
Reputation: 2740
Based on @JoshCrozier's answer, I've made a solution that uses the open
attribute instead of the extra open
class. This way you don't have to change the css.
If you would like to use css to change the appearance of the <details>
element, you can use the same style rules regardless of whether the browser supports the <details>
element, and regardless of whether javascript is enabled in the browser, since you only have to consider the open
attribute, and no special classes.
In addition, there is no special id
on the wrapper element, making the solution slightly more robust and generic.
Also, this solutions takes <details>
elements that should be open by default into account.
$('details summary').each(function() {
var $Wrapper = $(this).nextAll().wrapAll('<div></div>').parent();
// Hide elements that are not open by default
if(!$(this).parent('details').attr('open'))
$Wrapper.hide();
$(this).click(function(Event) {
Event.preventDefault();
if($(this).parent('details').attr('open')) {
$Wrapper.slideUp(function() {
// Remove the open attribute after sliding so, so the animation is visible in browsers supporting the <details> element
$(this).parent('details').removeAttr('open');
});
} else {
// Add the open attribute before sliding down, so the animation is visible in browsers supporting the <details> element
$(this).parent('details').attr('open', true);
$Wrapper.slideDown();
}
});
});
Upvotes: 3
Reputation: 240948
Too bad a simple CSS transition can't be used.
I'd therefore suggest wrapping the sibling elements of the summary
element and then using .slideToggle()
on them. It isn't that simple though, you need to add the open
attribute to details
, and hide the inner wrapped elements by default.
This only works if you use e.preventDefault()
to prevent the default functionality; however, you then need to rewrite the arrow indicators, (►
,▼
).
You would use summary::-webkit-details-marker
and display:none
to remove the marker that is no longer working, and add your own custom markers via the :before
/:after
pseudo elements.
$('details summary').each(function(){
$(this).nextAll().wrapAll('<div id="wrap"></div>');
});
$('details').attr('open','').find('#wrap').css('display','none');
$('details summary').click(function(e) {
e.preventDefault();
$(this).siblings('div#wrap').slideToggle(function(){
$(this).parent('details').toggleClass('open');
});
});
CSS:
summary::-webkit-details-marker {
display: none;
}
summary:before {
content: "►";
}
details.open summary:before {
content: "▼";
}
If you want the details
element to be open by default, add class="open"
as opposed to the attribute open
, and then use this: $('details.open div#wrap').css('display','block');
ALTERNATIVE EXAMPLE - (open by default)
Upvotes: 6