I want to reproduce YouTube's "Show More" functionality on my site. Below each video, there's a "Show More" link. If you click on that link, it moves down, and some previously-hidden text is shown. How can I do this?
One of the tags indicates you're willing to use jQuery. The following link explains how this effect can be achieved with slideToggle. The style of the div or other element should be set display: none;
if you want it to be hidden on the first page load.
http://www.mkyong.com/jquery/jquery-slideup-slidedown-and-slidetoggle-example/
$("#slideToggle").click(function () {
$('.slideTogglebox').slideToggle();
});
Official documentation: http://api.jquery.com/slideToggle/
A CSS-only version I just did: http://dabblet.com/gist/3157489
It works in Chrome, Firefox, Safari, Opera, IE9+. Show/ hide is functional in IE9, though transitions are missing (gradient fade is emulated using an additional element).
The HTML structure is something like:
<div class="info-wrapper">
<input type="checkbox" id="showhide">
<label for="showhide">
<div class="more">Show more</div>
<div>Show less</div>
</label>
<div class="info">
<p><!-- text, text, more text --></p>
<!--[if lte IE 9]><div class="aftershadow"></div><![endif]-->
</div>
</div>
The CSS:
body {
background: #ccc;
}
.info-wrapper {
height: auto;
width: 500px;
margin: 4em auto;
padding: 0 0 2em 0;
position: relative;
}
.info {
max-height: 120px;
height: auto;
padding: .5em 0;
border-bottom: solid 1px #fff;
border-radius: 0 0 1em 1em;
overflow: hidden;
position: relative;
transition: 1s;
}
p { margin: 1em; }
.info:after, .aftershadow {
bottom: 0;
width: 100%;
height: 3em;
border-radius: 0 0 1em 1em;
position: absolute;
background: linear-gradient(rgba(192,192,192,0), #ccc);
content: '';
}
.aftershadow {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00cccccc, endColorstr=#ffcccccc);
}
.info-wrapper input[type=checkbox] {
display: none;
}
.info-wrapper label {
left: 50%;
bottom: 1.5em;
width: 9em;
height: 1.25em;
margin: 0 0 0 -2.5em;
border-bottom: solid 1px #fff;
border-radius: 0 0 1em 1em;
overflow: hidden;
position: absolute;
font: 700 .67em/1.25em Arial;
text-align: center;
text-shadow: 0 1px 0 #fff;
cursor: pointer;
}
.info-wrapper label .more { margin: -.1em 0 .35em; transition: 1s; }
.info-wrapper input[type=checkbox]:checked ~ .info {
max-height: 15em;
}
.info-wrapper input[type=checkbox]:checked + label .more {
margin-top: -1.65em;
}
The idea is the following: in the HTML structure, you have a checkbox which is hidden, but can be checked/ unchecked by clicking its label
.
Initially, the info is compacted and the checkbox is unchecked. Clicking on "Show more" (which is inside the label
) ticks the checkbox and you can now change the style of the elements that are its siblings and come after it in the HTML (the label
and the .info
in this case) using the :checked
pseudo-class and the the general sibling selector.
This is the part that does it:
.info-wrapper input[type=checkbox]:checked ~ .info {
max-height: 15em;
}
.info-wrapper input[type=checkbox]:checked + label .more {
margin-top: -1.65em;
}
Another method that would also work in IE8 would be to use links and their :focus
/ :active
pseudo-classes instead of a checkbox and its :checked
pseudo-class. The disadvantage of this method is that as soon as you click anywhere else in the page, the .info
gets compacted again.
Demo: http://jsfiddle.net/thebabydino/U7Cyk/
HTML doesn't change much, I'm just replacing the checkbox and the label with two links
<div class="info-wrapper">
<a href="#" tabindex="1" class="more">Show more</a>
<a href="#" tabindex="1" class="less">Show less</a>
<div class="info">
<p><!--stuff, not wasting space here with it--></p>
<!--[if lte IE 9]><div class="aftershadow"></div><![endif]-->
</div>
</div>
The CSS is mostly the same. Everything related to input
& label
is out and instead there is:
.info-wrapper a {
left: 50%;
bottom: 1.5em;
width: 9em;
height: 1.25em;
margin: -.1em 0 .35em -4.5em;
border-bottom: solid 1px #fff;
border-radius: 0 0 1em 1em;
display: block;
overflow: hidden;
position: absolute;
color: #000;
font: 700 .67em/1.25em Arial;
text-align: center;
text-decoration: none;
text-shadow: 0 1px 0 #fff;
transition: 1s;
cursor: pointer;
}
.info-wrapper a:focus { outline: none; }
.info-wrapper .less {
margin-top: -1.5em;
opacity : 0;
z-index: -1;
}
.info-wrapper .more:focus ~ .info,
.info-wrapper .more:active ~ .info {
max-height: 15em;
}
.info-wrapper .less:focus ~ .info,
.info-wrapper .less:active ~ .info {
max-height: 120px;
}
.info-wrapper .more:focus,
.info-wrapper .more:active {
opacity: 0;
}
.info-wrapper .more:focus + .less,
.info-wrapper .more:active + .less {
opacity: 1;
z-index: 1;
}
Using jQuery - demo http://jsfiddle.net/thebabydino/yDfTq/
$('.more').click(function(){
$(this).animate({'opacity': '0'}, 1000);
$('.less').animate({
'opacity': '1',
'z-index': '1'
}, 1000);
$('.info').animate({'height': '15em'}, 1000);
});
$('.less').click(function(){
$(this).animate({
'opacity': '0',
'z-index': '-1'
}, 1000);
$('.more').animate({'opacity': '1'}, 1000);
$('.info').animate({'height': '120px'}, 1000);
});
The HTML is the same and the CSS is also mostly the same:
.info {
height: 120px;
padding: .5em 0;
border-bottom: solid 1px #fff;
border-radius: 0 0 1em 1em;
overflow: hidden;
position: relative;
}
p { margin: 1em; }
.info:after, .aftershadow {
bottom: 0;
width: 100%;
height: 3em;
border-radius: 0 0 1em 1em;
position: absolute;
background: linear-gradient(rgba(192,192,192,0), #ccc);
content: '';
}
.aftershadow {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00cccccc, endColorstr=#ffcccccc);
}
.info-wrapper a {
left: 50%;
bottom: 1.5em;
width: 9em;
height: 1.25em;
margin: -.1em 0 .35em -4.5em;
border-bottom: solid 1px #fff;
border-radius: 0 0 1em 1em;
display: block;
overflow: hidden;
position: absolute;
color: #000;
font: 700 .67em/1.25em Arial;
text-align: center;
text-decoration: none;
text-shadow: 0 1px 0 #fff;
cursor: pointer;
}
.info-wrapper a:focus { outline: none; }
.info-wrapper .less { margin-top: -1.5em; opacity: 0; z-index: -1; }