Transition doesn't work with border-image and gradient - html

I am using border-image with gradient and it works fine, but it seems transition is not supported for it.
Is it possible to achieve transition on hover for this example?
JsFiddle
div {
border:10px solid blue;
height:120px;
float:left;
transition:1s all;
border-image: linear-gradient(to bottom, white, blue) 1 100%;
}
div:hover {
border-image: linear-gradient(to bottom, skyblue, blue) 1 100%;
}
<div></div>

As the others already told you, it isn't possible to transition a gradient (yet). The best way to fake the effect would be to work with opacity, which can be transitioned. You don't need to add any elements however, the :before and :after pseudo elements will do just fine. have a look at the following css:
div {
height:120px;
width:10px;
padding: 0 10px;
background: salmon;
background-clip: content-box;
position: relative;
}
div:after, div:before {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
content:'';
}
div:after {
background: linear-gradient(to bottom, white 0%, blue 100%);
z-index: -1;
transition: opacity 1s;
}
div:before {
background: linear-gradient(to bottom, skyblue 0%, blue 100%);
z-index: -2;
}
div:hover:after {
opacity: 0;
}
And an example: https://jsfiddle.net/et0ffrqx/2/

Not Possible
That isn't possible yet because linear-gradient is calculated as an image, not actually colors.
Solution
Try putting the <div> within another <div> which can act as a border. Then the outer <div> can have an animated background
I've found this codepen demonstrating how this can be done with JavaScript.
My best bet for you would be to have two <div> stacked on top of each other. The bottom <div> would be the target gradient and the top being the start. Then just fade the top <div>
#start {
position:absolute;
width: 100px;
height: 100px;
z-index: 1;
opacity: 1;
background: linear-gradient(red,blue);
transition: opacity 0.5s ease;
}
#end {
position:absolute;
width: 100px;
height: 100px;
background: linear-gradient(green,orange);
z-index: -1;
}
#start:hover {
opacity: 0;
}
<div id="start">Start</div>
<div id="end">End</div>
The snippet demonstrates a simple way to fade between gradients. Not perfect but smoother and without JavaScript. Put your other stuff in side the <div> and adjust the width and height to your needs.
Also try using :before and :after to avoid having duplicate divs

No
Animations aren't supported for those properties.
You can however, think of another way to accomplish this visually.
maybe you have 2 wrappers around something, and they are 2 different gradients, and there is padding around them to simulate the look of a border... and then the elements with the gradients have opacity that fades to and from on hover.
https://jsfiddle.net/sheriffderek/5uoypaoo/
<div class="gradient-1">
<div class="gradient-2"></div>
<div class="thing"></div>
</div>
.thing {
position: relative;
width: 200px;
height: 200px;
background: white;
float: left;
}
.gradient-1 {
position: relative;
background: linear-gradient(45deg, pink, blue);
opacity: 1;
padding: 1rem;
float: left;
}
.gradient-1:hover .gradient-2 {
opacity: 1;
}
.gradient-2 {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: linear-gradient(45deg, lightgreen, orange);
opacity: 0;
transition: opacity 1s ease-in-out;
}

Related

CSS Gradient animation stutters on background-image property and does not fade out on background property

Want to get a simple hover on a button that animates a color on top of it. This color is a gradient that fades out about halfway of the button.
Problem is with the background-image property it will stutter on hovering out of the button, but does fade out properly.
With the background property it does not stutter, but does not fade out properly. The end of the gradient is still very visible. This is all happening on the :before sudo.
does not fade out, but no stutter:
background: linear-gradient(90deg, rgba(122,163,174,1) 0%, rgba(122,163,174,0) 100%);
fades out, but stutters:
background-image: linear-gradient(90deg, rgba(122,163,174,1) 0%, rgba(122,163,174,0) 100%);
Used in:
.app-drawer__button {
position: relative;
transition: all .2s ease;
margin-top:8px;
&:hover {
&:before {
width: 70%;
background: linear-gradient(90deg, rgba(122,163,174,1) 0%, rgba(122,163,174,0) 100%);
}
}
&:active {
transform: scale(.96);
}
}
.app-drawer__button:before {
content: "";
position: absolute;
top: 0;
left: 0;
display: block;
background: rgba(rgba(122,163,174,1),.5);
width: 3px;
height: 100%;
transition: all .3s ease;
}
.app-drawer__button span {
position: relative;
font-size: 14px;
line-height: 18px;
font-weight: 600;
letter-spacing: .25em;
text-transform: uppercase;
vertical-align: middle;
}
.app-drawer__button:active {
transform: scale(.96);
}
html
<div class='app-drawer__button'>
<span> test </span>
</div>
Made a JSFiddle here to demonstrate, toggle between the background and background-image of the .app-drawer__button in there to see the difference. :
Edit:
I noticed the fiddle was the wrong jsfiddle, did not save it properly, appologies. here is the correct fiddle
https://jsfiddle.net/gsqhr4zu/

Z-index problem with hover when dealing with clip-path objects

I'm having some problems I'm trying to have two clip path polygons overlap each other when hovered over by the mouse, I'm using z-index's and trying to change them depending on with overlay is being hovered over but I can't seem to get it to work. I've tried changing the z-index when the object is hovered over but that doesn't seem to change anything.
.banner {
position:relative;
bottom 0;
top: 0;
left:0;
right: 0;
width: 100%;
height: 700px;
}
.overlayleft {
position:absolute;
z-index:1;
bottom 0;
top: 0;
left:0;
right: 0;
width: 50%;
height: 100%;
overflow:hidden;
clip-path: polygon(0 0, 75% 0, 100% 100%, 0% 100%);
background: rgba(0,0,0,1);
transition: .5s ease;
}
.overlayright {
position:absolute;
z-index:2;
bottom: 0;
top 0;
left: 50%;
right: 0;
width: 50%;
height: 100%;
overflow:hidden;
clip-path: polygon(0 0, 100% 0, 100% 100%, 25% 100%);
background: rgba(0,0,0,0.6);
transition: .5s ease;
}
.overlayleft:hover{
z-index: 4;
width: 100%;
}
.overlayright:hover{
z-index: 4;
width: 100%;
left: 0;
}
<!DOCTYPE html>
<html>
<body>
<div class="banner">
<div class="overlayright"></div>
<div class="overlayleft"></div>
</div>
</body>
</html>
Its because of this "background: rgba(0,0,0,0.6);"
Its color with opacity, if you change the color to something else, lets say red color, you will see the difference.
Basically left div is black, and the second div is gray, when gray one is hovered its not visible that it is hovering the left one because of its opacity...

Is there a more efficient way to make background position change from left to right on hover?

This is the code I currently have to make it seem as though the left border expands on hover, even though it's just the background changing. Is there a more efficient way to write this code?
edit: Efficient meaning a better way to write it.
span {
padding: 5px;
text-align: center;
border-left: 5px solid black;
background: linear-gradient(to left, yellow 50%, black 50%);
background-size: 200%, 100%;
background-position: right;
transition: .5s ease;
}
span:hover {
background-position: left;
color: white;
}
<span>This is some example text.</span>
I prefer using pseudo elements for this stuff, as you can then add transforms and such to the pseudo element for better performance.
Only problem with this is that you need to wrap your span in another element, so that you can position the text over the pseudo element with z-index. Otherwise it will just cover your text.
span {
color: black;
transition: color .5s ease;
z-index: 2;
position: relative;
}
p {
padding: 5px;
text-align: center;
border-left: 5px solid black;
background-color: yellow;
position: relative;
overflow: hidden;
display: inline-block;
}
p::after {
content: '';
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background-color: black;
transition: transform .5s ease;
transform: translateX(-100%);
will-change: transform;
z-index: 1;
}
p:hover::after {
transform: translateX(0);
}
p:hover span {
color: white;
}
<p><span>This is some example text.</span></p>

slide down background transition

i am trying to get the background color to change on hover. Something like this.
I have tried various approaches but cannot get it to work, presumably it is the way my CSS and HTML is set up. I cannot figure out why it is not working, as it should be easy to implement
Please see code below.
CSS
.image-container {
position: relative;
}
.image-container .after {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
width: 100%;
height: 100%;
display: none;
color: #FFF;
background-size: 100% 200%;
background-image: linear-gradient(to bottom, red 50%, black 50%);
-webkit-transition: background-position 1s;
-moz-transition: background-position 1s;
transition: background-position 1s;
}
.image-container .after p {
position: relative;
text-align: center;
font-size: 26px;
text-transform: uppercase;
font-weight: 300;
line-height: 300px;
height: 300px;
}
.image-container:hover .after {
display: block;
background: rgba(0,0,0,0.3);
background-position: 0 -100%;
}
[class*='col-'] {
float: left;
}
.col-1-3 {
width: 33.33%;
}
HTML
<div class="col-1-3 image-container">
<img class="portrait-image geysir" src="images/geysir.jpg">
<div class="after">GEYSIR</div>
</div>
Remove the background declaration on the hover. It's overriding all the other backgrounds you declared previously.
.image-container:hover .after {
display: block;
background-position: 0 -100%;
}
It should then work.
Based on the given fiddle, I would use a transparent .png image as a second overlapping element like that. Not sure if that's your intention...
.container{
position:relative;
}
.box {
width: 400px; height: 200px;
background-size: 100% 200%;
background-image: linear-gradient(to bottom, red 50%, black 50%);
-webkit-transition: background-position 1s;
-moz-transition: background-position 1s;
transition: background-position 1s;
}
.box:hover {
background-position: 0 -100%;
}
.geysir{
position:absolute;
top:0px;
}
<div class="container">
<div class="box"></div>
<img class="portrait-image geysir" src="http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons-256/high-resolution-dark-blue-denim-jeans-icons-arrows/008776-high-resolution-dark-blue-denim-jeans-icon-arrows-hand-pointer1-right.png">
</div>
Do you want to have the background, including the text slide in from the top on hover? In which case you would be better transitioning a bottom move like this:
.image-container {
position: relative;
overflow: hidden;
}
.image-container .after {
position: absolute;
bottom: 100%;
margin: auto;
width: 100%;
height: 100%;
color: #fff;
background-color: black;
-webkit-transition: bottom 1s;
-moz-transition: bottom 1s;
transition: bottom 1s;
}
.image-container:hover .after {
bottom: 0;
}
Fiddle
If you're looking to have your text appear on a red background that shifts to black, try using a combination of the above with what you were using. Avoid using display: none/block as this stops the transistion from functioning.
.image-container {
position: relative;
overflow: hidden;
}
.image-container .after {
position: absolute;
bottom: 100%;
margin: auto;
width: 100%;
height: 100%;
color: #fff;
background-size: 100% 200%;
background-image: linear-gradient(to bottom, red 50%, black 50%);
-webkit-transition: background-position 2s;
-moz-transition: background-position 2s;
transition: background-position: 2s;
}
.image-container:hover .after {
bottom: 0;
background-position: 0 -100%;
}
Fiddle

CSS mask pseudo element by parent div?

I'm using a psuedo element to fade a gradient over another div which has an image as a background for that div.
My html layout is like so:
<div class='portfolio_thumb'>
<div class='portfolio_thumb_caption'></div
</div
and my CSS for those items
.portfolio_thumb {
position: relative;
width: 100%;
height: 300px;
background-size: cover;
}
.portfolio_thumb .portfolio_thumb_caption:before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, rgba(72,76,97,0) 0%, rgba(72,76,97,0.8) 75%);
content: '';
opacity: 0;
transform: translate3d(0,50%,0);
}
.portfolio_thumb:hover .portfolio_thumb_caption:before {
transform: translate3d(0,0,0);
opacity: 1;
}
Right now the gradient fades in and starts to slide, but it is shown past the parent div. I only want the gradient shown within the bounds of the portfolio_thumb div. Also, both divs in that html snippet are the same heights. Does anyone have any ideas? I'm going for this kind of approach. http://tympanus.net/Development/HoverEffectIdeas/
Thanks!
Use overflow: hidden on the container to cut-off the gradient.
Use transform: translateY(x%) to move the gradient up and down. As we are not creating 3d animations, there is no point using translate3d, which requires more grunt to run.
The transition smoothly shows and hides the overlay
Complete Example
.portfolio_thumb {
position: relative;
background: url(http://lorempixel.com/output/animals-q-c-640-300-1.jpg);
background-size: cover;
overflow: hidden;
height: 300px;
width: 100%;
max-width: 840px;
margin: 0 auto;
}
.portfolio_thumb .portfolio_thumb_caption:before {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(to bottom, rgba(72, 76, 97, 0) 0%, rgba(72, 76, 97, 0.8) 75%);
content: '';
transition: all 0.5s;
transform: translateY(50%);
opacity: 0;
}
.portfolio_thumb:hover .portfolio_thumb_caption:before {
transform: translateY(0);
opacity: 1;
}
<div class='portfolio_thumb'>
<div class='portfolio_thumb_caption'></div>
</div>