Optimize hover overlay animation - html

I created a specific hover effect only with HTML and CSS.
.cont {
background: blue;
position: relative;
width: 400px;
height: 200px;
margin: 50px;
}
.pre {
background: green;
position: absolute;
height: 0;
width: 100%;
bottom: 0;
clip-path: polygon(100% 100%, 100% 0, 0 100%);
transition: height 0.5s 0.5s;
}
.pre ~ .pre {
background: red;
bottom: auto;
clip-path: polygon(0 0, 100% 0, 0 100%);
}
.cont:hover .pre {
height: 100%;
transition: height 0.5s;
}
.post {
position: absolute;
height: 100%;
width: 100%;
transition: opacity 0s 0.5s, clip-path 0.5s;
background: green;
opacity: 0;
}
.post ~ .post {
background: red;
position: absolute;
height: 100%;
width: 100%;
clip-path: polygon(0 0, 100% 0, 50% 50%, 0 100%);
}
.cont:hover .post {
opacity: 1;
transition: opacity 0s 0.5s, clip-path 0.5s 0.5s;
}
.post ~ .post:hover {
clip-path: polygon(0 0, 100% 0, 90% 80%, 0 100%);
}
.post:hover ~ .post {
clip-path: polygon(0 0, 100% 0, 10% 20%, 0 100%);
}
<div class="cont">
<div class="pre">
<div style="position:absolute;bottom:80px;right:80px;">
some complex html content
</div>
</div>
<div class="pre">
<div style="position:absolute;top:80px;left:80px;">
different complex html content
</div>
</div>
<div class="post">
<div style="position:absolute;bottom:80px;right:80px;">
some complex html content
</div>
</div>
<div class="post">
<div style="position:absolute;top:80px;left:80px;">
different complex html content
</div>
</div>
</div>
The snippet shows the fully working hover effect, but the implementation is pretty awkward.
It uses two divs (class="pre") for creating the "overlay" effect and two separate divs (class="post"), which are only set to opacity: 1 after the "overlay" effect has completed, for creating the "toggle" effect. Also the "toggle" effect is delayed, thus feels kind of sluggish.
I am looking for an implementation (only HTML+CSS) that only uses two divs (+container div) to create the same effects and/or an implementation that removes the "toggle"-delay.
I've already tried using animation to do the "overlay" effect but to no avail.
Any ideas on how a two-div (no pseudo elements) implementation of this effect could be accomplished?

Related

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...

Diagonal split of 2 images with transition

I was wondering if it was possible to split a screen into 2 parts diagonally as shown on the picture. Once I'd hover over Picture A, the diagonal line would shift a bit to the right, revealing more of picture A while hiding a bit of picture B (I'm thinking transition?), and when I'd hover over picture B the opposite would happen.
Thanks in advance,
Martin
The diagonal image transition effect is unique request. I tried my best, Can you please check revealing effect.
section {
border: 1px solid black;
display: flex;
width: 400px;
box-sizing: border-box;
}
.diagonalHover {
position: absolute;
width: 66%;
height: 200px;
transition: all 0.3s ease-out;
}
.diagonalHover.first,
.diagonalHover.second {
background-image: url(https://cdn.pixabay.com/photo/2016/07/20/22/33/vajdahunyadvar-1531470_960_720.jpg);
background-repeat: no-repeat;
background-size: cover;
}
.diagonalHover.second {
background-image: url(https://cdn.pixabay.com/photo/2020/02/05/22/17/vendetta-4822543__340.jpg);
}
.diagonalHover.first:hover {
width: 75%;
z-index: 1;
}
.diagonalHover.second:hover {
width: 75%;
z-index: 1;
}
.diagonalHover.first:hover + .second {
}
.diagonalHover.first {
left: 0;
top: 0;
-webkit-clip-path: polygon(0 0, 100% 0%, 50% 100%, 0% 100%);
clip-path: polygon(0 0, 100% 0%, 50% 100%, 0% 100%);
}
.diagonalHover.second {
right: 0;
top: 0;
-webkit-clip-path: polygon(50% 0, 100% 0%, 100% 100%, 0% 100%);
clip-path: polygon(50% 0, 100% 0%, 100% 100%, 0% 100%);
}
<section>
<div class="diagonalHover first">
</div>
<div class="diagonalHover second">
</div>
</section>

How to fix clip-path cutting off a small part of a wrapped image?

I'm trying to have an image inside a clip-path'd container display correctly. I wanted to add a slight zoom effect on hover as well.
A small part at the bottom is being cut off when not hovered.
However, once you hover the image and it zooms in, everything looks fine.
I cannot set a fixed height, which would solve the problem more easily since I want to add the image to a responsive flex container later.
I reduced the problem to its core in this jsfiddle: https://jsfiddle.net/pzf459cd/1/
.Image-Wrapper {
width: 50%;
}
.Image-Zoom-Wrapper {
clip-path: polygon(100% 0, 100% 91%, 62% 100%, 0 91%, 0 0, 62% 9%);
object-fit: contain;
}
.Image {
transition: all 0.5s linear;
}
.Image-Wrapper:hover .Image {
transform: scale(1.05, 1.05);
transition: all 0.5s linear;
}
body {
background-color: #000;
}
<div class="Image-Wrapper">
<div class="Image-Zoom-Wrapper">
<img class="Image" src="https://picsum.photos/id/304/500/300">
</div>
</div>
See my solution for a similiar task below. It works, but there might be an easier/better one.
jsfiddle: https://jsfiddle.net/fj5z7bue/
.wrap{
position: relative;
width: 50%;
filter: drop-shadow(3px 4px 8px rgba(38, 50, 56, 0.4));
}
.clip{
position: relative;
display: block;
overflow: hidden;
clip-path: polygon(60% 5%, 100% 0, 100% 95%, 60% 100%, 0 95%, 0 0);
height: 100%;
width: 100%;
background-color: rgb(240, 240, 240);
}
.pseudoimg{
width: 100%;
opacity: 0;
}
.img{
position: absolute;
top: 0;
left: 0;
z-index: 2;
background-image: url('https://picsum.photos/id/304/500/300');
background-size: cover;
background-position: center center;
background-repeat: no-repeat;
min-height: 100%;
min-width: 100%;
transform: scale(1);
transition: all 0.4s ease-out;
}
.wrap:hover{
cursor: pointer;
}
.wrap:hover .img{
transform: scale(1.4);
transition: all 12s ease-out;
}
.button{
position: absolute;
height: 60px;
width: 60px;
border-radius: 30px;
background-color: rgb(255, 255, 255);
z-index: 3;
right: -15px;
bottom: -5px;
filter: drop-shadow(3px 4px 8px rgba(38, 50, 56, 0.4));
}
<div class="wrap">
<div class="button"></div>
<div class="clip">
<img class="pseudoimg" src="https://picsum.photos/id/304/500/300"/>
<div class="img"></div>
</div>
</div>

Strange behaviour in CSS3 transition with linear gradient

I am trying to make a progress bar and using css3 transition to give it a fill effect.
jsfiddle here
When I give it a fixed size, it works as usual, but Problem is when I set the background-size:100% the fill becomes stretch.
How can I create fill effect using background-size:100%?
Progressbar1 is with fixed width and background-size
Progressbar2 is with 100% width and background-size
/* PROGRESS */
.progress {
background-color: #e5e9eb;
height: 0.25em;
position: relative;
width: 24em;
}
.progress-bar {
animation-duration: 3s;
animation-name: width;
background-image: repeating-linear-gradient(to right, transparent, #000 50px, #fff 100px, transparent 150px);
background-size: 24em 0.25em;
height: 100%;
position: relative;
width:100%
}
.progress2 {
background-color: #e5e9eb;
height: 0.25em;
position: relative;
width: 100%;
}
.progress-bar2 {
animation-duration: 3s;
animation-name: width;
background-image: repeating-linear-gradient(to right, transparent, #000 50px, #fff 100px, transparent 150px);
background-size: 100% 0.25em;
height: 100%;
position: relative;
width:100%
}
/* ANIMATIONS */
#keyframes width {
0%, 100% {
transition-timing-function: cubic-bezier(1, 0, 0.65, 0.85);
}
0% {
width: 0%;
}
100% {
width: 100%;
}
}
<div class="progress">
<div class="progress-bar">
</div>
</div>
<br>
<div class="progress2">
<div class="progress-bar2">
</div>
</div>

Transition doesn't work with border-image and gradient

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;
}