JSFiddle - React, Tailwind, and code Playground
by lollero
HTML
<script src="https://fonts.googleapis.com/css?family=Libre+Franklin:200,400,600,700|Nunito:300,400"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.4.1/jquery.easing.min.js"></script>
<!-- Used libraries/services -->
<!-- http://lesscss.org/ -->
<!-- https://fonts.google.com/ -->
<!-- http://gsgd.co.uk/sandbox/jquery/easing/ -->
<!-- https://material.io/icons/ -->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<img
class="caption"
data-heading-one="Nam at accumsan urna"
data-heading-two="Curabitur pulvinar."
data-caption="Consectetur adipisicing elit. Autem, consequuntur 1."
src="http://joonas.me/1/dribbble-images/dribbble-1.png" alt=""
>
<img
class="caption"
data-color="#333, #fff"
data-heading-one="Maecenas faucibus convallis"
data-heading-two="Nam vitae."
data-caption="Aliquam volutpat odio vitae lectus feugiat venenatis. Curabitur id consectetur felis, ut ultricies orci. Nunc viverra quis nisl a consectetur. Ut pellentesque at ante ac porta. Mauris condimentum consequat congue. Phasellus sit amet tristique lacus. Donec commodo tristique sem."
src="http://joonas.me/1/dribbble-images/dribbble-2.png" alt=""
>
<img
class="caption"
data-overlay="true"
data-heading-one="Mauris vulputate dignissim odio"
data-heading-two="Pellentesque pharetra."
data-caption="Consectetur adipisicing elit. Autem, consequuntur 3."
src="http://joonas.me/1/dribbble-images/dribbble-3.png" alt=""
>
<img
class="caption"
data-heading-one="Sed pellentesque ligula"
data-heading-two="Cras nam dapibus feugiat."
data-caption="Aliquam posuere, ex sed fringilla fermentum, diam diam tempor enim, egestas laoreet nisl ante sit amet odio. Praesent urna enim, lobortis sed tristique quis, cursus non erat. In tempus, libero feugiat gravida rutrum, nunc mauris facilisis erat, eget blandit risus nulla at dolor. <br><br> Donec a dolor vel felis maximus gravida a eu enim. Donec...
SCSS
.caption-wrapper {
position: relative;
float: left;
width: 430px; // With this we don't need to wait for the images to load before initiating the javascript.
height: 450px;
margin: 20px;
box-shadow: 0 1px 5px rgba(0,0,0, .1);
overflow: hidden;
background-clip: padding-box;
border-radius: 2px;
cursor: pointer;
img {
position: relative;
z-index: 0;
display: block;
}
.caption-overlay {
position: absolute;
z-index: 1;
top: 0px;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
background: #fff;
opacity: .65;
display: none;
}
.caption {
position: absolute;
z-index: 2;
left: 0;
right: 0;
bottom: 0px;
width: 100%;
background: #fff;
color: #000;
> div {
padding: 35px 25px;
}
.material-icons {
vertical-align: sub;
float: right;
opacity: .5;
}
&:hover .material-icons {
opacity: 1;
}
.caption-h1 {
font-family: 'Libre Franklin', sans-serif;
font-weight: 100;
font-size: 12px;
opacity: .5;
}
.caption-h2 {
font-family: 'Libre Franklin', sans-serif;
font-weight: 300;
font-size: 18px;
opacity: .95;
}
.caption-text {
width: 100%;
overflow: hidden;
font-family: 'nunito', sans-serif;
font-weight: 300;
font-size: 13px;
opacity: .6;
.divider {
margin-top: 20px;
height: 1px;
background: #f1f1f1;
margin-bottom: 20px;
}
}
}
}
JavaScript
$('.caption').each(function() {
var _this = $(this),
_thisD = _this.data();
_this.wrap('<div class="caption-wrapper"></div>');
_this.removeClass('caption');
var caption = $('<div class="caption"><div></div></div>').insertAfter( _this ).find('div');
$('\
<div class="caption-heading">\
<div class="caption-h1">'+ _thisD.headingOne +'</div>\
<div class="caption-h2">\
<span>'+ _thisD.headingTwo +'</span>\
<i class="material-icons"></i>\
</div>\
</div>\
').appendTo( caption );
$('\
<div class="caption-text">\
<div class="divider"></div>\
<span>'+ _thisD.caption +'</span>\
</div>\
').appendTo( caption );
var wrapper = _this.parent();
if ( _thisD.overlay ) {
$('<div class="caption-overlay"></div>').appendTo( wrapper );
}
var overlay = wrapper.find('.caption-overlay');
if ( _thisD.overlay ) {
overlay.css({
background: _thisD.overlay
});
}
if ( _thisD.color ) {
var color = _thisD.color.split(', ');
caption.css({
background: color[0],
color: color[1]
});
}
// Clear data.
_this
.attr( 'data-heading-one', '' )
.attr( 'data-heading-two', '' )
.attr( 'data-caption', '' );
var captionT = wrapper.find('.caption-text'),
captionT_height = captionT.height();
captionT.height(0);
wrapper.on("mouseenter mouseleave", function( e ) {
if ( e.type === "mouseenter" ) {
captionT.animate({
height: captionT_height
}, 180, "easeOutBack");
overlay.stop().fadeIn( 600 );
}
else {
captionT.animate({
height: 0
}, 300, "easeOutBack");
overlay.stop().fadeOut( 300 );
}
});
});