CSS: Animated button shown only when hovering image - css

I want to create a button that is hidden initially but then displays over an image when the image is hovered. I want the button to animate from the top of the image(initially hidden) to the middle(displayed on hover). Here is an example, scroll to the "latest from blog" section and hover the image.
The problems I'm having:
I want the button hidden completely when the image is not hovered. Setting the opacity to zero doesn't fully hide it and if the user hovers over the hidden button it twitches.
If the user hovers the image, the button animates down over the image like it should. I want it to animate back up and disappear when the user stops hovering.
I've used CSS filter and a transition to darken the image on hover. When the button animates down over the image on hover the image is still dark like it should be, but when the user hovers directly over the newly displayed button the image goes back to it's normal brightness. I want the image to stay dark (like in the example) when the user is directly over the button.
Here is my code. How can I make this button hover effect exactly like it is in the first example I showed?

You should really show us the code without react, as this would be a lot easier for everyone to check and debug. Regardless, I went to your source, and copied all the CSS used from the content given. It all activates when you hover over div.entry-image-attachment.
Pure CSS
#submit,
button,
.button,
input[type=submit] {
border: 0;
text-transform: uppercase;
cursor: pointer;
font-family: inherit;
font-weight: 400!important;
line-height: 1;
margin: 0;
position: relative;
text-decoration: none;
text-align: center;
display: inline-block;
padding-top: .9375em;
padding-right: 1.875em;
padding-bottom: 1em;
padding-left: 1.875em;
font-size: .875em;
background-color: #2ecc71;
border-color: #2ecc71;
transition: all .5s ease 0s;
-webkit-transition: all .5s ease 0s;
-moz-transition: all .5s ease 0s;
color: #fff;
-webkit-border-radius: 2px;
border-radius: 2px;
}
.text-center {
text-align: center!important;
}
.trans-button {
background-color: transparent!important;
font-weight: bolder;
border-width: 1px;
border-style: solid;
}
.entry-image {
position: relative;
margin: 10px 0 15px;
}
.nd-content {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
-webkit-transition: all .5s ease;
transition: all .5s ease;
}
.nd-content_inner {
display: table;
width: 100%;
height: 100%;
}
.nd-content_inner1 {
display: table-cell;
width: 100%;
height: 100%;
vertical-align: middle;
}
.nd-title {
position: relative;
top: -150px;
opacity: 0;
margin: 0 0 30px;
-webkit-transition: all .3s ease .01s;
transition: all 1s ease .01s; /*Animation happens with this*/
}
.button.white.trans-button {
color: #fff;
}
.entry-image-attachment:hover .nd-title {
-webkit-transition: all .5s cubic-bezier(1, -.53, .405, 1.425) .01s;
transition: all .5s cubic-bezier(1, -.53, .405, 1.425) .01s;
}
.entry-image-attachment:hover .nd-icon,
.entry-image-attachment:hover .nd-content,
.entry-image-attachment:hover .nd-title {
opacity: 1;
top: 0;
}
.button.trans-button {
padding: 15px;
}
#submit.white,
button.white,
.button.white,
input[type=submit].white {
background-color: #fff;
border-color: #fff;
transition: all .5s ease 0s;
-webkit-transition: all .5s ease 0s;
-moz-transition: all .5s ease 0s;
color: #333;
-webkit-border-radius: 2px;
border-radius: 2px;
}
.entry-image-attachment:hover .nd-icon,
.entry-image-attachment:hover .nd-content,
.entry-image-attachment:hover .nd-title {
opacity: 1;
top: 0;
}
.entry-image-attachment:hover .nd-content {
background: rgba(0, 0, 0, .5);
}
<div class="entry-image">
<div class="entry-image-attachment" style="max-height:200px;overflow:hidden;">
<img src="http://rosette.leetheme.com/wp-content/uploads/2014/12/02.jpg" width="296" height="180" />
<div class="nd-content text-center">
<div class="nd-content_inner">
<div class="nd-content_inner1">
<div class="button trans-button white nd-title"><span>Read more</span></div>
</div>
</div>
</div>
</div>
</div>

Related

max-height Transition keep child element always on bottom of parent

I'm fighting with quite easy problem.
Sections change their max-height on hover.
the small span article article__tag should always position at the bottom of its parent (the green line) no matter how much the row will grow and share its easing animation and delay.
This is what I have:
section{
background: #000;
color: #fff;
display: flex;
max-height: 150px;
border-bottom: 1px solid lightgreen;
transition: max-height .5s ease-in-out;
position: relative;
overflow: hidden;
}
section:hover {
max-height: 400px;
transition-delay: .3s;
}
article {
flex:1;
height: 200px
}
.article__tag {
background: white;
color: #000;
position: absolute;
padding: 10px;
top: 120px;
transition: all .5s ease-in-out;
transition-delay: .3s;
}
section:hover .article__tag {
bottom: 0;
top: inherit;
}
<section>
<article>A</article>
<article><span class="article__tag">tag</span></article>
</section>
<section>
<article>B</article>
<article><span class="article__tag">tag</span></article>
</section>
https://codepen.io/t-book/pen/LYpjVPz
My problem is, on mouse leave the white label jumps up quickly. Further, I've defined it's top with 165px a value which I cannot foresee as the rows have different content.
How can I position the label always on current max-height bottom?
Keep article_tag at bottom always:
section{
background: #000;
color: #fff;
display: flex;
max-height: 150px;
border-bottom: 1px solid lightgreen;
transition: max-height .5s ease-in-out;
position: relative;
overflow: hidden;
}
section:hover {
max-height: 400px;
transition-delay: .3s;
}
article {
flex:1;
height: 200px
}
.article__tag {
background: white;
color: #000;
position: absolute;
padding: 10px;
bottom: 0px;
transition: all .5s ease-in-out;
transition-delay: .3s;
}
<section>
<article>A</article>
<article><span class="article__tag">tag</span></article>
</section>
<section>
<article>B</article>
<article><span class="article__tag">tag</span></article>
</section>

Continue Transition from where Animation Ended

See the following button animation:
html {
background: white;
font-family: Arial;
}
.button {
position: relative;
display: inline-block;
color: #000;
border: 2px solid #000;
padding: 10px 24px;
font-size: 20px;
font-weight: 600;
text-align: center;
text-decoration: none;
transition-property: color, background, border-color;
transition-duration: 0.3s;
}
.button:hover {
color: #fff;
}
.button:hover ._background:after {
transform: translateX(0);
animation: fill-horizontal 0.3s linear 0s 1;
}
.button ._background {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
overflow: hidden;
}
.button ._background:after {
content: "";
position: absolute;
display: block;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: #000;
transform: translateX(100%);
transition: transform .3s;
}
#keyframes fill-horizontal {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
<a class="button" href="javascript:">
<div class="_background"></div>
Button
</a>
The intended animation is to sweep the ._background:after element in from the left, and then out to the right like so:
translateX(-100%)
translateX(0) - Hover
translateX(100%) - Remove Hover
Whilst the animation works as intended when the user hovers for the duration of the CSS animation (.3s), it looks terrible if the user 'unhovers' before the CSS animation completes.
I would like the transition to translateX(100%) to continue from where the animation finished. Is this even possible?
NOTE - I am aware that the div._background element is not necessary, this has additional functionality that is not relevant to this question.
You can consider the same effect differently in order to avoid this bad effect:
Here is an idea using background animation where the trick is to change the position only after the size has changed.
.button {
position: relative;
display: inline-block;
color: #000;
border: 2px solid #000;
padding: 10px 24px;
font-size: 20px;
font-weight: 600;
text-align: center;
text-decoration: none;
background-image:linear-gradient(#000,#000);
background-size:0% 100%;
background-position:left;
background-repeat:no-repeat;
background-origin:border-box;
transition:color 0.3s, background-size 0.3s, background-position 0s 0.3s;
}
.button:hover {
color:#fff;
background-size:100% 100%;
background-position:right;
}
<div class="button">Some text</div>
Using this method, you will have a transition back in case you unhover rapidly.
A hacky idea to force the animation to complete is to consider a pseudo element that will make the hover area bigger and be sure you will keep the hover until the end:
.button {
position: relative;
display: inline-block;
color: #000;
border: 2px solid #000;
padding: 10px 24px;
font-size: 20px;
font-weight: 600;
text-align: center;
text-decoration: none;
background-image:linear-gradient(#000,#000);
background-size:0% 100%;
background-position:left;
background-repeat:no-repeat;
background-origin:border-box;
transition:color 0.3s, background-size 0.3s, background-position 0s 0.3s;
}
.button:hover {
color:#fff;
background-size:100% 100%;
background-position:right;
}
.button:hover:before {
content:"";
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
z-index:99;
animation:remove 0s 0.3s forwards;
}
#keyframes remove {
to {
top:100%;
}
}
<div class="button">Some text</div>

How to create button scaling effect in CSS?

I need a button whose after selector expands and gets disappeared when clicked. I need this effect via CSS.
When i click this button it's after selector expands.
Like
#button::after{
transform: scale(2);
}
But this is not happening for me. Please help me. When clicked the after selector button should expand then should disappear. In a nutshell, i need button scaling effect.
Do you mean something like this?
As far as I know you can't get an onclick event with CSS only and without using JavaScript. You can use :active, but this will only apply the style when the mouse button is held down. See Bojangles answer on "Can I have an Onclick effect in CSS".
#button {
display: block;
border: none;
position: relative;
color: red;
background-color: white;
font-size: 30px;
padding: 15px 30px;
}
#button:after {
content: '';
position: absolute;
display: block;
height: 100%;
width: 100%;
top: 0;
left: 0;
border: 4px solid red;
color: black;
font-size: 8px;
opacity: 1;
transition: transform .3s ease, opacity .5s ease;
}
#button:active:after {
transform: scale(5);
opacity: 0;
}
<button id="button">BUTTON</button>
**The code snippet is built upon on benedikt's answer.
#button:after's border color is set to transparent, adds border-color during the animation. this creates the illusion that it disappears. I hope this helps.
#button {
display: block;
border: 4px solid red;
position: relative;
color: red;
background-color: white;
font-size: 30px;
padding: 15px 30px;
}
#button:after {
content: '';
position: absolute;
display: block;
width:100%;
height:100%;
top:0;
left:0;
border: 4px solid transparent;
color: black;
font-size: 8px;
opacity: 1;
transition: transform 0.3s ease, opacity 0.5s ease, border-color 0.1s ease;
}
#button:active:after {
transform: scale(2);
border-color:red;
opacity: 0;
}
<button id="button">BUTTON</button>

I want .tabcontent to appear from 0 center to full size animated over .3 seconds

Sample of hover effect
I want the hover effect to be animated starting from 0 center out to full size over 0.3s. The effect is what I want ,but the animation isn't working.The page I'm going to build will consist of eight different images (two columns four in each) I want this hover effect to work as you hove hover each image.
#tabbox{
height: 300px;
position: relative;
//border: 2px solid #888;
}
#tabbox img{
cursor: pointer;
display: block;
width: 240px;
height: 240px;
}
.tab {
float: left;
}
.tabcontent{
position: absolute;
padding:10px;
top:0;
width: 0px;
height: 0px;
background:rgba(0, 0, 0, .5);
border:1px solid #fff;
margin:10px;
color:#fff;
display:none;
overflow:hidden;
-webkit-transition: height 0.3s ease-in-out;
-moz-transition: height 0.3s ease-in-out;
-o-transition: height 0.3s ease-in-out;
transition: height 0.3s ease-in-out;
}
.tabcontent:before{
content: "";
position: absolute;
z-index: -1;
top: 0;
left: 0;
right: 0;
bottom: 0;
-webkit-transform: scale(0);
transform: scale(0);
-webkit-transition-property: transform;
transition-property: transform;
-webkit-transition-duration: 0.3s;
transition-duration: 0.3s;
-webkit-transition-timing-function: ease-out;
transition-timing-function: ease-out;
}
.tab:hover > .tabcontent{
display: block;
width: 200px;
height: 200px;
}
.tab:hover:before, .tab:active:before{
-webkit-transform: scale(1);
transform: scale(1);
}
<div id="tabbox">
<div class="tab">
<img src="http://zone1.gingermartinco.netdna-cdn.com/wp-content/uploads/2012/04/Napa-Real-Estate-Realtor.jpg" />
<div class="tabcontent">
<p>Text box to describe the images around when you hover over them, this description will change depending on what image you hover over.</p>
</div><!--tabcontent-->
</div><!--tab-->
</div><!--tabbox-->
Just remove the display: none; from .tabcontent as this property can't be animated, only number properties can be animated.
Fiddle:
https://jsfiddle.net/uxouomoy/
Your fiddle and your question code is not the same.
But taking the code from the fiddle you should put the transition only in .tabcontent style. Use top and left properties to animate from the center position to the left corner position.
See the fiddle
Here's the css it is using:
#tabbox {
height: 300px;
position: relative;
//border: 2px solid #888;
}
#tabbox img {
cursor: pointer;
display: block;
width: 240px;
height: 240px;
}
.tab {
float: left;
}
.tabcontent {
position: absolute;
padding: 10px;
width: 0px;
height: 0px;
background: rgba(0, 0, 0, .5);
border: 1px solid #fff;
margin: 10px;
color: #fff;
display: block;
overflow: hidden;
top: 100px;
left: 100px;
visibility: hidden;
transition-timing-function: ease-in-out;
transition-duration: 0.3s;
transition: width top left;
}
.tab:hover > .tabcontent {
visibility: visible;
width: 200px;
height: 200px;
top: 0px;
left: 0px;
}
<div id="tabbox">
<div class="tab">
<img src="http://zone1.gingermartinco.netdna-cdn.com/wp-content/uploads/2012/04/Napa-Real-Estate-Realtor.jpg" />
<div class="tabcontent">
<p>Text box to describe the images around when you hover over them, this description will change depending on what image you hover over.</p>
</div>
<!--tabcontent-->
</div>
<!--tab-->
</div>
<!--tabbox-->

CSS3 Transition: Animate child to 100% width, parent jumps to 100% width instantly

I am trying to create a delete button, that once you click it, expands to show the delete option, so you won't delete anything by mistake. The problem is that the parent container jumps to full size right away while I would like it to grow gradually.
This can be overcome when I set the fixed pixel width for the parent container, but the problem is that I don't always know the width of the contents. Therefor I used a percentage to get it dynamic.
I don't really know how to explain it clearly so I've made a fiddle to show you: http://jsfiddle.net/cgHcP/
HTML:
<div class="right">
<div style="background-color: #000; display: inline-block;">
<div class="roll-button">
<div class="icon">x</div>
<div class="text">Remove</div>
</div>
</div>
<div style="background-color: #000; display: inline-block;">
<div class="roll-button">
<div class="icon">x</div>
<div class="text">Remove</div>
</div>
</div>
</div>
CSS:
/* Roll Button */
div.roll-button {
float: right;
display: inline;
position: relative;
height: 24px;
width: 24px;
-webkit-box-shadow: 0 0 0 2px #fff;
-webkit-border-radius: 12px;
text-align: center;
vertical-align: middle;
background-color: #fff;
overflow: hidden;
-webkit-transition: width .5s ease-in-out;
transition: width .5s ease-in-out;
}
div.roll-button .icon {
left: 0;
display: inline;
position: absolute;
font-size: 24px;
width: 24px;
height: 24px;
background-color: #ff3e3e;
-webkit-border-radius: 12px;
-webkit-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
text-align: center;
vertical-align: middle;
color: #fff;
line-height: .7;
}
div.roll-button .text {
float: left;
display: inline;
position: relative;
height: 24px;
overflow: hidden;
-webkit-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
vertical-align: middle;
line-height: 24px;
color: #ff3e3e;
font-weight: 700;
padding: 0 0 0 24px;
font-size: 12px;
}
div.roll-button:hover .text {
padding: 0 5px 0 29px;
}
div.roll-button:hover .icon {
-webkit-transform: rotateZ(-180deg);
}
div.roll-button:hover {
width: 100%;
}
.right {
float: right;
margin-right: 200px;
}
When you look at the fiddle, you'll notice the parent container (black), jumps to full size when hovered. Even though the child seems to grow gradually. This behavior causes trouble when you put multiple items inline (like in the fiddle, and exactly what I want to do).
I'm, trying to make this button purely with CSS, but this is where I get stuck. Does anyone have a suggestion how this can be done by using purely CSS?
The trick to achieving what you want is using width:auto on the .text and limiting the max-width of it.. the new working jsFiddle
div.roll-button .text {
width: auto;
max-width:0px;
}
div.roll-button:hover .text {
max-width:100px; /* set this to the maximum allowed value.. */
}
Ok, it seemed to much of a hassle to get this to work without using javascript, so I decided to go the javascript way using jQuery.
I now set the width in real pixels to bypass the problem that still occurs in most browsers when you make a transition from a pixel width to auto or percentage. I did it by creating a wrapper element with a overflow:hidden and summed up the width of the children. This sum I used to set the button width in real pixels.
Furthermore i've added a timer to close the button within a preset amount of time. My idea for this button was to not have to show a delete dialog asking if the content should really be deleted. Maybe this fiddle will be useful to someone else.
Check my latest fiddle for the final result.
HTML
<div class="roll-button">
<div class="icon">x</div>
<div class="label">Short Label</div>
</div>
<div class="roll-button">
<div class="icon">x</div>
<div class="label">This is a very long label</div>
</div>
CSS
body {
background-color: #ff3e3e;
}
.roll-button {
margin-right: 12px;
float: right;
display: inline-block;
width: 24px;
height: 24px;
overflow: hidden;
-webkit-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
-o-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
white-space: nowrap;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
background-color: rgba(255,255,255,1);
-webkit-box-shadow: 0 0 0 2px rgba(255,255,255,1);
-moz-box-shadow: 0 0 0 2px rgba(255,255,255,1);
box-shadow: 0 0 0 2px rgba(255,255,255,1);
}
.roll-button .icon {
display: inline-block;
-webkit-transition: all .5s ease-in-out;
-moz-transition: all .5s ease-in-out;
-o-transition: all .5s ease-in-out;
transition: all .5s ease-in-out;
width: 24px;
height: 24px;
background-color: #ff0000;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
border-radius: 12px;
-webkit-box-shadow: 0 0 0 2px rgba(255,255,255,1);
-moz-box-shadow: 0 0 0 2px rgba(255,255,255,1);
box-shadow: 0 0 0 2px rgba(255,255,255,1);
text-align: center;
vertical-align: middle;
}
.roll-button .label {
display: inline-block;
height: 24px;
padding: 0 15px 0 5px;
}
.roll-button.open .icon {
-webkit-transform: rotateZ(-180deg);
}
javascript/jquery
$(function() {
$('.roll-button').bind('click',function() {
var iconWidth = $(this).find('.icon').outerWidth();
var newWidth = 0;
var timer = [];
var $elm = $(this);
$(this).children().each(function(){ newWidth += $(this).outerWidth(); });
if(!$(this).hasClass('open')) {
$(this).addClass('open').css({'width':newWidth+'px'});
setTimeout(function() {
$elm.removeClass('open').css({'width':iconWidth+'px'});
},5000);
}
});
});

Resources