Show div on hover on same position - javascript

I am trying to show div on mouseover, but it's flickering, how do I show/hide without any jerk and smooth with the transition?
I have tried the fade in/out using jquery as well but still blinking.
Here is the code
body {
margin: 0;
}
.row {
float: left;
width: 100%;
}
.col {
float: left;
width: 25%;
position: relative;
margin: 0 10px 0 0;
}
.front {
width: 100%;
height: 300px;
background-color: #999
}
.back {
position: absolute;
left: 0;
top: 0;
height: 300px;
opacity: 0;
visibility: hidden;
background-color: #ff0;
z-index: 2;
width: 100%;
}
.front:hover + .back {
opacity: 1;
visibility: visible;
}
<div class="row">
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
</div>

It flickers because every time .back becomes visible, hover on .front is no longer valid. To solve for this you can set visibility of .back as visible on .back:hover which can be done by using the same css style for .back:hover as for .front:hover + .back
body {
margin: 0;
}
.row {
float: left;
width: 100%;
}
.col {
float: left;
width: 25%;
position: relative;
margin: 0 10px 0 0;
}
.front {
width: 100%;
height: 300px;
background-color: #999
}
.back {
position: absolute;
left: 0;
top: 0;
height: 300px;
opacity: 0;
visibility: hidden;
background-color: #ff0;
z-index: 2;
width: 100%;
}
.front:hover + .back,
.back:hover {
opacity: 1;
visibility: visible;
}
<div class="row">
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
</div>

body {
margin: 0;
}
.row {
float: left;
width: 100%;
}
.col {
float: left;
width: 25%;
position: relative;
margin: 0 10px 0 0;
}
.front {
width: 100%;
height: 300px;
background-color: #999
}
.back {
position: absolute;
left: 0;
top: 0;
height: 300px;
opacity: 0;
visibility: hidden;
background-color: #ff0;
z-index: 2;
width: 100%;
}
.col:hover > .back {
opacity: 1;
visibility: visible;
}
<div class="row">
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
</div>
.col:hover > .back {
opacity: 1;
visibility: visible;
}
I have a simple solution.
Change .front:hover + .back => .col:hover > .back.

The problem is that when you hover .front div the .back div appears, so now you're hovering the .back div not the .front so it disappears again, and the loop continues.
To fix this, add the hover effect to the .back div too.
Add transition to .back for smooth effect.
body {
margin: 0;
}
.row {
float: left;
width: 100%;
}
.col {
float: left;
width: 25%;
position: relative;
margin: 0 10px 0 0;
}
.front {
width: 100%;
height: 300px;
background-color: #999
}
.back {
position: absolute;
left: 0;
top: 0;
height: 300px;
opacity: 0;
visibility: hidden;
background-color: #ff0;
z-index: 2;
width: 100%;
transition: 0.2s ease;
}
.front:hover + .back, .back:hover {
opacity: 1;
visibility: visible;
}
<div class="row">
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
<div class="col">
<div class="front">This is front div</div>
<div class="back">This is back div</div>
</div>
</div>

What if you put .back element inside .col element, move .front element styles to .col element and add transition to .col element? I think it's a better solution in view of browsers support.
body {
margin: 0;
}
.row {
float: left;
width: 100%;
}
.col {
float: left;
width: 25%;
position: relative;
margin: 0 10px 0 0;
height: 300px;
background-color: #999
}
.back {
position: absolute;
left: 0;
top: 0;
height: 300px;
opacity: 0;
visibility: hidden;
background-color: #ff0;
z-index: 2;
width: 100%;
transition: all 0.2s;
}
.col:hover .back {
opacity: 1;
visibility: visible;
}
<div class="row">
<div class="col">
This is front part
<div class="back">This is back part</div>
</div>
<div class="col">
This is front part
<div class="back">This is back part</div>
</div>
<div class="col">
This is front part
<div class="back">This is back part</div>
</div>
</div>

The main problem is that you have not been able to tell who really "shoots" the "animation".
Both front and back are at the same level, so it is not possible to do it from that level, but if you shoot it through the parent element, it should work.
The approach would be as follows:
.col:hover .back {
opacity: 1;
visibility: visible;
}

Related

Show nested button above overlay

I have an HTML page where I need to make a deeply nested element appear above a neighboring ancestor.
Here is an example JSFiddle: https://jsfiddle.net/nLa607g5/1/
This HTML structure can’t be changed. Using CSS (preferably) or JavaScript, is there any way I can make the red button appear on top of the overlay, but the blue portion appear behind the overlay?
The following are the two main classes that deal with the overlay and button:
.overlay {
background-color: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(2px);
border-radius: 5px;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
#cntrl {
float: left;
}
.modal {
overflow: auto;
display: block;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
}
.dialog {
background: blue;
width: 100px;
height: 100px;
display: block;
}
.btn {
margin-top: 20px;
position: relative;
background: red;
}
<div class="overlay"></div>
<div id="app">
<div id="cntrl">
<div>
<div>
<div class="modal">
<div class="dialog">
<span>should appear behind overlay</span>
<div class="content">
<div class="footer">
<button class="btn">
Should appear on top of overlay
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Impossible with CSS and no HTML. JavaScript is the only option. Basically, you append the overlay to the footer and the button to the overlay -- exactly what you'd do with HTML.
const overlay = document.querySelector('.overlay');
const footer = document.querySelector('.footer');
const button = document.querySelector('.btn');
footer.append(overlay);
overlay.append(button);
.overlay {
background-color: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(2px);
border-radius: 5px;
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
#cntrl {
float: left;
}
.modal {
overflow: auto;
display: block;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1050;
}
.dialog {
background: blue;
width: 100px;
height: 100px;
display: block;
}
.btn {
margin-top: 20px;
position: relative;
background: red;
}
<div class="overlay"></div>
<div id="app">
<div id="cntrl">
<div>
<div>
<div class="modal">
<div class="dialog">
<span>should appear behind overlay</span>
<div class="content">
<div class="footer">
<button class="btn">
Should appear on top of overlay
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

Why target of click event is incorrect in mobile devices?

As you can observe in the enclosed picture(https://i.ibb.co/yQSTK0H/test-section.jpg), I have divided specified area into 3 sections. now the problem is that when i toggle to mobile device in chrome developer tools and I'm trying to click in the blue area event fires as if I have clicked in red section.
Why is this happening?
https://codepen.io/anon/pen/xNxZKe
$(".time-filter").click(function (e) {
alert(e.target.className)
});
.time-filter {
position: fixed;
bottom: -100px;
right: -100px;
height: 200px;
width: 200px;
z-index: 99;
}
.time-filter-content {
position: relative;
height: 100%;
width: 100%;
border-radius: 50% !important;
overflow: hidden;
}
.section {
height: 100px;
width: 100px;
position: absolute;
top: 0;
right: 100px;
}
.red {
transform-origin: bottom right;
z-index: 3;
transform: rotate(59deg);
background-color:red
}
.blue {
transform-origin: bottom right;
z-index: 2;
transform: rotate(28deg);
background-color:blue
}
.black {
border-bottom: 0;
z-index: 1;
background-color:black
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="time-filter">
<div class="time-filter-content">
<div class="section red">
</div>
<div class="section blue">
</div>
<div class="section black">
</div>
</div>
</div>

HTML/CSS Animation - JavaScript

I've been trying to animate a sliding door that is triggered on the click of a button.
Here is my fiddle
I've got two sides of the sliding door. Left side is blue, right side is red. The left side should slide to the left and the right door should slide to the right.
First of all, I'm trying to position the button to the middle of the door. I'm using
#button {
z-index: 2;
position: absolute;
top: 50%;
left: 50%;
}
but still the button appears kind of sideways
But secondly when the button is clicked, both sides of the door should slide out at the same time, but unfortunately only the red door functions correctly.
The blue door is stuck. What am I doing wrong?
You can use simple JQuery animation to do what you require.
FIDDLE
Here is the code:
$("button").click(function() {
$(".one").animate({
left: '0'
});
$(".three").animate({
left: '200px'
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="one" style="background:#98bf21;height:100px;width:100px;position:absolute;left:100px;"></div>
<div class="two" style="background:blue;height:100px;width:100px;position:absolute;left:100px;">
</div>
<div class="three" style="background:red;height:100px;width:100px;position:absolute;left:100px;"></div>
<button style="position:absolute;left:110px;top:50px;">
CLICK ME
</button>
It should be like this
function myMove() {
var elem = document.getElementById("myAnimationRight");
var elem_l = document.getElementById("myAnimationLeft");
var elem_R = document.getElementById("myAnimationRight");
elem_l.className += " opened";
elem_R.className += " opened";
}
#container {
width: 800px;
}
#button {
z-index: 2;
position: absolute;
top: 50%;
left: 50%;
}
#wrapper {
z-index: 1;
position: absolute;
display:inline-block;
width: 810px;
overflow:hidden;
}
#left {
display:inline-block;
width: 400px;
}
#right {
display:inline-block;
width: 400px;
}
#myContainer {
width: 400px;
height: 300px;
position: relative;
background: yellow;
}
#myAnimationLeft {
width: 400px;
height: 300px;
position: absolute;
background-color: blue;
transition:linear all 0.5s;
left:0;
}
#myAnimationRight {
width: 400px;
height: 300px;
position: absolute;
background-color: red;
transition:linear all 0.5s;
right:0;
}
#myAnimationRight.opened{
right:-100%;
transition:linear all 0.5s;
}
#myAnimationLeft.opened{
left:-100%;
transition:linear all 0.5s;
}
<div id="container">
<div id ="button">
<button onclick="myMove()">Click Me</button>
</div>
<div id="wrapper">
<div id ="left">
<div id ="myContainer">
<div id ="myAnimationLeft"></div>
</div>
</div>
<div id ="right">
<div id ="myContainer">
<div id ="myAnimationRight"></div>
</div>
</div>
</div>
</div>
You can handle animation via CSS and just add class opened to elements on button click.
You need to minus half the button width and height to bring it to the center.
If button's width is fixed, its correct to use calc(50% - 50px) as Icewine's answer.
For elements with dynamic widths and heights u can always use:
position: absolute;
top: 50%;
left: 50%;
transform:translateX(-50%) translateY(-50%);
The above code will center the element even if you dont know the height and width of the element.
Example:
body {
padding: 0px;
margin: 0px;
}
div {
width: 100px;
height: 100px;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
background: red;
}
<div></div>
As for animation, why not use classes and let the CSS handle the animation?
function myMove() {
document.getElementById("myAnimationLeft").className = "DoorOpenLeft";
document.getElementById("myAnimationRight").className = "DoorOpenRight";
}
* {
box-sizing: border-box;
}
body {
margin: 0px;
}
#container {
width: 100%;
}
#button {
z-index: 2;
position: absolute;
top: 50%;
left: 50%;
display: inline-block;
transform: translateX(-50%) translateY(-50%);
}
#wrapper {
z-index: 1;
position: absolute;
width: 100%;
overflow-x: hidden;
clear: both;
}
#left {
display: inline-block;
width: 50%;
float: left;
}
#right {
display: inline-block;
width: 50%;
float: right;
}
#myContainer {
width: 100%;
height: 300px;
position: relative;
background: yellow;
}
#myAnimationLeft {
width: 100%;
height: 300px;
left: 0px;
position: absolute;
background-color: blue;
transition: all 1s ease;
}
#myAnimationRight {
width: 100%;
height: 300px;
left: auto;
right: 0px;
position: absolute;
background-color: red;
transition: all 1s ease;
}
.DoorOpenLeft {
left: -100% !important;
}
.DoorOpenRight {
right: -100% !important;
}
<div id="container">
<div id="button">
<button onclick="myMove()">Click Me</button>
</div>
<div id="wrapper">
<div id="left">
<div id="myContainer">
<div id="myAnimationLeft"></div>
</div>
</div>
<div id="right">
<div id="myContainer">
<div id="myAnimationRight"></div>
</div>
</div>
</div>
</div>
Defining same vars causing issues and for the left door you need to decrease value _pos--
Solution for button
left: calc(50% - 38px);
#container {
width: 810px;
}
#button {
z-index: 2;
position: absolute;
top: 50%;
left: 50%;
}
#wrapper {
z-index: 1;
position: absolute;
display: inline-block;
width: 810px;
}
#left {
display: inline-block;
width: 400px;
}
#right {
display: inline-block;
width: 400px;
}
#myContainer {
width: 400px;
height: 300px;
position: relative;
background: yellow;
}
#myAnimationLeft {
width: 400px;
height: 300px;
position: absolute;
background-color: blue;
}
#myAnimationRight {
width: 400px;
height: 300px;
position: absolute;
background-color: red;
}
<div id="container">
<div id="button">
<button onclick="myMove()">Click Me</button>
</div>
<div id="wrapper">
<div id="left">
<div id="myContainer">
<div id="myAnimationLeft"></div>
</div>
</div>
<div id="right">
<div id="myContainer">
<div id="myAnimationRight"></div>
</div>
</div>
</div>
</div>
<script>
function myMove() {
var _elem = document.getElementById("myAnimationLeft");
var _pos = 0;
var _id = setInterval(_frame, 5);
function _frame() {
if (_pos == 410) {
clearInterval(_id);
} else {
_pos--;
_elem.style.right = _pos + 'px';
_elem.style.left = _pos + 'px';
}
}
var elem = document.getElementById("myAnimationRight");
var pos = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos == 410) {
clearInterval(id);
} else {
pos++;
elem.style.left = pos + 'px';
elem.style.right = pos + 'px';
}
}
}
</script>
JQuery Solution created on #shubhamagrawal's answer.
$(document).ready(function() {
$('button').click(function() {
$("#myAnimationLeft").offset({
left: 0
})
$("#myAnimationRight").offset({
left: $("#myAnimationRight").width()
})
$("#myAnimationLeft").animate({
left: -$("#myAnimationLeft").width()
}, 2000);
$("#myAnimationRight").animate({
left: $("#myAnimationRight").width()
}, 2000);
})
})
body,
html {
margin: 0;
padding: 0;
}
#container {
width: 810px;
position:relative;
overflow:hidden;
height:300px;
}
#button {
z-index: 2;
position: absolute;
top: calc(50% - 11px);
left: calc(50% - 34px);
}
#wrapper {
z-index: 1;
position: absolute;
display: inline-block;
width: 810px;
}
#left {
display: inline-block;
width: 400px;
}
#right {
display: inline-block;
width: 400px;
}
#myContainer {
width: 400px;
height: 300px;
position: relative;
background: yellow;
}
#myAnimationLeft {
width: 400px;
height: 300px;
position: absolute;
background-color: blue;
}
#myAnimationRight {
width: 400px;
height: 300px;
position: absolute;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<div id="button">
<button>Click Me</button>
</div>
<div id="wrapper">
<div id="left">
<div id="myContainer">
<div id="myAnimationLeft"></div>
</div>
</div>
<div id="right">
<div id="myContainer">
<div id="myAnimationRight"></div>
</div>
</div>
</div>
</div>
For the button, you need to minus the width and height of the button to center it.
left: calc(50% - 50px); if button width is 100px;
Also, you need to set the parent div above button to position: relative; or the absolute wont work. You should also set a height of the parent div while you are at it.

CSS translateY to animate slide down behind a parent element

I'm trying to use transformY to animate the sliding down of an element when you click on a link in the header. The issue i'm having is that the element being displayed is nested a few levels deep and this is what I think is causing the problem - I need the element to slide down from behind the parent elements. Setting z-index doesn't appear to work in this context. I've created a JS Fiddle below - grateful for any help! In this demo, the green parent container should be sitting on top of the yellow hidden element.
jQuery('.test-link').on('click', function(e) {
e.preventDefault();
jQuery('.container').toggleClass('active');
});
.outer-container {
background: green;
width: 100%;
position: relative;
z-index: 5;
}
.container .hidden-content {
transition: all 0.2s ease;
transform: translateY(-100%);
position: absolute;
z-index: -1;
z-index: 1;
width: 100vw;
left: 0;
right: 0;
background: yellow;
}
.test-link {
margin-left: 100px;
display: block;
position: relative;
z-index: 3;
width: 200px;
background: red;
}
.container.active .hidden-content {
transform: translateY(0%);
}
.other-content {
position: relative;
z-index: 4;
background: blue;
}
.test-content {
position: relative;
z-index: 5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="outer-container">
<div class="test-content">
<div class="container">
TEST LINK
<div class="hidden-content">
<h1>My Hidden Content</h1>
<h1>My Hidden Content</h1>
</div>
</div>
</div>
<div class="other-content">
<h2>This should be overlaid by the sliding out content</h2>
</div>
</div>
You can do that with a negative z-index
jQuery('.test-link').on('click', function(e) {
e.preventDefault();
jQuery('.container').toggleClass('active');
});
.another-container {
position: relative;
z-index: 1;
}
.outer-container {
background: green;
width: 100%;
position: relative;
}
.container .hidden-content {
transition: all 0.2s ease;
transform: translateY(-100%);
position: absolute;
background: yellow;
z-index: -1;
}
.test-link {
display: block;
position: relative;
width: 200px;
background: red;
}
.container.active .hidden-content {
transform: translateY(0%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="another-container">
<div class="outer-container">
<div class="test-content">
<div class="container">
TEST LINK
<div class="hidden-content">
<h1>My Hidden Content</h1>
<h1>My Hidden Content</h1>
</div>
</div>
</div>
</div>
</div>
<div>yellow box should be on top</div>

Need to change position of element on slideToggle

$("button.filters").click(function(){
$("div.second").slideToggle("slow");
});
.main {
position: relative;
display:block;
height: 320px;
color: #fff;
background-color: grey;
}
.first {
position: absolute;
bottom: 15%;
height: 70px;
background-color: white;
}
.second {
position: absolute;
bottom: 0%;
height: 30px;
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<div class="first">
<p>some content</p>
<button class="filters">filters</button>
</div>
<div class="second">
<p>other content</p>
</div>
</div>
Please check this fiddle
https://jsfiddle.net/6d1t5jr8/
I need help to make .second div to .slideToggle from bottom border of .first div.
The problem:
Because of the bottom:0 in that way, the the height of the .second div start from the bottom.
The solution:
Try to wrap the .second with wrapper. So the slide animation will start from the top.
Like this:
jQuery(document).ready(function () {
$("button.filters").click(function(){
$("div.second").slideToggle("slow");
});
});
.main {
position: relative;
display:block;
height: 320px;
color: #fff;
background-color: grey;
}
.first {
position: absolute;
bottom: 15%;
height: 70px;
background-color: white;
}
.second-wrapper {
position: absolute;
bottom: 0%;
height: 30px;
}
.second {
display:none;
background-color: green;
}
.second p {
margin:0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main">
<div class="first">
<p>some content</p>
<button class="filters">filters</button>
</div>
<div class="second-wrapper">
<div class="second">
<p>other content</p>
</div>
</div>
</div>

Categories