Reputation: 13511
I have a button with a background color, and text color set. What I like to do, is when the user hover the mouse on the button, the background to animate from bottom to top and change the color of the text to the color of the background.
For terms of simplicity of the code, I didn't put the transient I like to apply on the CSS properties. I know it's much easyer to change the button background code, but I plan to use transient for changing the :before
height on hover.
So I have the following code, but when I hover the mouse on the button, the :before
overlapping my button text.
I have also try to play with the z-index
but no luck. Do you think is there any solution to this problem ?
body {
background: #111;
}
.btn {
color: #FFF;
background: #333;
border: none;
font-size: 18px;
font-weight: bold;
padding: 18px 60px;
position: relative;
}
.btn:before {
display: block;
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 0;
background: #FFF;
}
.btn:hover {
color: #333;
}
.btn:hover:before {
height: 100%;
}
<br />
<a href="#" class="btn">Do Stuff</a>
Upvotes: 0
Views: 4119
Reputation: 246
The effect you desire can also be achieved without adding the additional span. By utilising the before and after pseudo elements for background colours and positioning them correctly.
To position the pseudo elements behind the text, set a positive z-index on the element and a negative z-index on the pseudo-element.
.btn {z-index: 1}
.btn:before {z-index: -1;}
Reference this article by Nicolas Gallagher which explains in more detail, see section 'Pseudo background-position' http://nicolasgallagher.com/an-introduction-to-css-pseudo-element-hacks/.
Also see fiddle with it in action: https://jsfiddle.net/j9whmcmz/2/
This technique does not work if you apply a background color to the .btn itself.
Choose your poison I guess, both solutions do the trick.
Upvotes: 4
Reputation: 116
Try this:
body {
background: #333;
}
.btn {
color: #FFF;
background: #333;
display: inline-block;
position: relative;
overflow: hidden;
-webkit-transition: color 0.3s ease-in-out;
transition: color 0.3s ease-in-out;
}
.btn span {
display: inline-block;
padding: 18px 60px;
border: none;
font-size: 18px;
font-weight: bold;
z-index: 10;
position: relative;
}
.btn:after {
display: block;
content: '';
position: absolute;
top: 100%;
left: 0;
width: 100%;
max-height: 0;
background: #FFF;
height: 100%;
z-index: 9;
-webkit-transition: all 0.3s ease-in-out;
transition: all 0.3s ease-in-out;
}
.btn:hover {
color: #333;
}
.btn:hover:after {
max-height: 100%;
top: 0;
}
<a href="#" class="btn"><span>Do Stuff</span></a>
Upvotes: 2
Reputation: 3677
You need to add additional <span>
element which would stay above the ::before pseudoelement:
span {
position: relative;
z-index: 1;
}
Upvotes: 4
Reputation: 11779
Solution if pretty obvious - content of the button should be also absolute positioned. Then browser order them properly behind each other.
EDIT: Maybe my formatting and styling is not the best for the case, but it was quick update of your code to get the idea
body {
background: #111;
}
.btn {
color: #FFF;
background: #333;
border: none;
font-size: 18px;
font-weight: bold;
padding: 18px 60px;
position: relative;
}
.btn span {
display: block;
content: '';
position: absolute;
top: 18px;
left: 0px;
width: 100%;
text-align: center;
}
.btn:before {
display: block;
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 0;
background: #FFF;
}
.btn:hover {
color: #333;
}
.btn:hover:before {
height: 100%;
}
<br />
<a href="#" class="btn"><span>Do Stuff</span></a>
Upvotes: 1