CSS translateY to animate slide down behind a parent element - javascript

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>

Related

How to make element on top on hover (after transition)

i have a problem for css guru I'm not able to untangle.
This is the html:
<div class="container">
<div class="around">
<img class="depiction around-depiction"/>
<div class="label">A label</div>
</div>
<div class="around">
<img class="depiction around-depiction" />
<div class="label">Another label</div>
</div>
...
<div class="center">
<img class="depiction center-depiction" />
<div class="label">Center label</div>
</div>
</div>
I've applied a transform to .around element to move in a circle around the .center element.
I cannot manage to do two thing :
When i hover over an image the image and its label should go above everything (i put a z-index: 10000 but that doesn't work
Make the .around image above the .around label. You can see by figure two that hover doesn't work on label div.
This is the css:
.container .circle {
position: absolute;
z-index: 2;
top: 50%;
left: 50%;
margin: calc(-100px / 2);
border-radius: 50%;
}
.center {
border-radius: 50%;
z-index: 1;
position: absolute;
}
.depiction {
border-radius: 50%;
cursor: pointer;
transition: 0.2s;
}
.around-depiction:hover {
transform: scale(4);
z-index: 1000000;
}
.center-depiction:hover {
transform: scale(2);
z-index: 1000000;
}
.label {
opacity: 0;
min-width: 200px;
z-index: -2;
background: white;
border-radius: 10px/20px;
padding: 5px;
border: 1px solid black;
}
.center:hover .label,
.around:hover .label {
opacity: 1;
z-index: 5;
}
.center .label:hover,
.around .label:hover {
opacity: 0;
}
Try adding the z-index with position: relative; on your image/label.
z-index doesn't work on the default, which is position: static;
https://coder-coder.com/z-index-isnt-working/

Slide Up Transition

I'm working on trying to get a div to slide up from the bottom. So far it works ok as I can get the div to show and hide when I need to by adding a class of open-drawer to the element that I'm trying to get to slide up. But I'm not sure how I can get it to animate and slide up from the bottom.
Not sure if I need to adjust something within the transition or what.
Here's what I got so far:
$(".drawer-link").click(function(e) {
var vdata = $(this).data("id");
$(".drawer[data-id=" + vdata + "]").addClass("open-drawer");
e.preventDefault();
});
$(".close").on("click", function(e) {
$(".drawer").removeClass("open-drawer");
e.preventDefault();
});
body {
padding: 20px;
}
.drawer {
position: fixed;
height: 100%;
width: 100%;
left: 0;
background: #0c1f3f;
padding-top: 90px;
overflow-y: scroll;
transition: top 0.5s ease;
color: white;
opacity: 0;
}
.wrapper {
width: 100%;
max-width: 1140px;
margin: 0 auto;
}
.open-drawer {
top: 150px;
opacity: 1;
}
.close {
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<a class="drawer-link" href="#" data-id="drawer-01">Link To Show Drawer</a>
</div>
<div class="drawer" data-id="drawer-01">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<a class="close" href="#">Close The Drawer</a>
</div>
</div>
Link to demo (CodePen): https://codepen.io/ultraloveninja/pen/qzVQLp
Three examples: jQuery, pure JS, and pure HTML+CSS
Toggle animate panel using jQuery and .toggleClass()
Use transform: translateY at 100% and on click the class .is-open will animate to 0.
No need for extra special classes, use what you already have, a data-*
attribute: data-drawer="#drawer-01" (notice the ID # selector!)
Also, make sure to use id="drawer-01" as the drawer selector.
Use jQuery's .toggleClass()
Animating transform is always a better idea than animating non-accelerable properties like top, bottom etc etc
$("[data-drawer]").on('click', function(e) {
e.preventDefault();
$($(this).data("drawer")).toggleClass("is-open");
});
.drawer {
position: fixed;
height: 100%;
width: 100%;
left: 0;
top: 0;
background: #0c1f3f;
overflow-y: scroll;
color: white;
/* Initial transforms */
opacity: 0;
transform: translateY(100%);
transition: 0.5s ease;
}
.drawer.is-open {
opacity: 1;
transform: translateY(0);
}
<div>
Link To Show Drawer
</div>
<div class="drawer" id="drawer-01">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<a data-drawer="#drawer-01" href="#!">Close The Drawer</a>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Toggle animate panel in pure JavaScript and .classList.toggle()
If you don't want to use jQuery only because of such a simple task, here's in vanilla JavaScript:
const toggleDrawer = (evt) => {
evt.preventDefault();
document.querySelector(evt.target.getAttribute('data-drawer')).classList.toggle('is-open');
}
document.querySelectorAll('[data-drawer]').forEach(btn => btn.addEventListener('click', toggleDrawer));
.drawer {
position: fixed;
height: 100%;
width: 100%;
left: 0;
top: 0;
background: #0c1f3f;
overflow-y: scroll;
color: white;
/* Initial transforms */
opacity: 0;
transform: translateY(100%);
transition: 0.5s ease;
}
.drawer.is-open {
opacity: 1;
transform: translateY(0);
}
Link To Show Drawer
<div class="drawer" id="drawer-01">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<a data-drawer="#drawer-01" href="#!">Close The Drawer</a>
</div>
</div>
Toggle animate panel in pure HTML + CSS and a hidden checkbox
Need support for no-JS environment? Here you go
.drawer-button {color: blue; cursor: pointer;}
.drawer {
position: fixed;
height: 100%;
width: 100%;
left: 0;
top: 0;
background: #0c1f3f;
overflow-y: scroll;
color: white;
/* Initial transforms */
opacity: 0;
transform: translateY(100%);
transition: 0.5s ease;
}
.drawer-toggler:checked+.drawer {
opacity: 1;
transform: translateY(0);
}
<label class="drawer-button" for="drawer-01">SHOW DRAWER</label>
<div>Other HTML here...</div>
<input id="drawer-01" class="drawer-toggler" type="checkbox" hidden>
<div class="drawer">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<label class="drawer-button" for="drawer-01">CLOSE DRAWER</label>
</div>
</div>
If you're able to give the .drawer a fixed height, then you can change the bottom property to initially be negative that amount.
Be sure to also add the opacity to the transition, otherwise it will instantly hide instead of fading out gently.
$(".drawer-link").click(function(e) {
var vdata = $(this).data("id");
$(".drawer[data-id=" + vdata + "]").addClass("open-drawer");
e.preventDefault();
});
$(".close").on("click", function(e) {
$(".drawer").toggleClass("open-drawer");
e.preventDefault();
});
body {
padding: 20px;
}
.drawer {
position: fixed;
height: 150px;
bottom: -150px;
width: 100%;
left: 0;
background: #0c1f3f;
padding-top: 90px;
overflow-y: scroll;
transition: bottom 0.5s ease, opacity 0.5s ease;
color: white;
opacity: 0;
}
.wrapper {
width: 100%;
max-width: 1140px;
margin: 0 auto;
}
.open-drawer {
bottom: 0px;
opacity: 1;
}
.close {
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<a class="drawer-link" href="#" data-id="drawer-01">Link To Show Drawer</a>
</div>
<div class="drawer" data-id="drawer-01">
<div class="wrapper">
<h3>Test</h3>
<p>This is the drawer</p>
<a class="close" href="#">Close The Drawer</a>
</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>

Reveal a div with dynamic height underneath another div inside a container?

So, I have a box of content that has a title and a description, which are positioned at the bottom of the div. Initially, the description is hidden. What I'm trying to do is when you hover over the div, the title should move up and reveal the description, which has a dynamic height.
Here's what I have now: https://codepen.io/tayanderson/pen/qJrmXE
The problem is that it wouldn't display correctly if the description was 1 line or 3 lines. The title div should move up depending on the size of the description div.
Here's an example of what I'm trying to do
HTML
<div class="grid-item" style="background-image: url(https://source.unsplash.com/WLUHO9A_xik/1600x900);">
<div class="title">Title</div>
<div class="desc">Lorem ipsum dolor sit amet, consectetur</div>
</div>
CSS
.grid-item {
height:300px;
background-size: cover;
width:300px;
position: relative;
overflow: hidden;
color: #fff;
.title {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
padding: 0 20px;
}
.desc {
position: absolute;
bottom: 0;
transform: translateY(100%);
padding: 5px 20px;
}
&:hover .title {
bottom: 30%;
}
&:hover .desc {
transform: translateY(0%);
}
}
It this what you meant?
.inner, .inner:hover .grid-item.inner {
-webkit-transition:all linear 0.2s;
transition:all linear 0.2s;
}
.inner {
background: #afa;
width: 300px;
overflow: hidden;
position: absolute;
}
.grid-item:hover .inner{
margin-top: -100px;
}
<a class="grid-item" href="{{ .Permalink }}" style="background-image: url(images/recipes/{{.Params.image}})">
<div class="inner"><h3 class="title is-3">{{.Title}}</h3></div>
<div class="content"><p class="grid-item-blurb">{{.Description}}</p></div>
</a>
Note that I reversed the order of the inner elements.
.body {
background: #aaf;
height: 100px;
width: 300px;
overflow: hidden;
}
.inner, .content {
transition: all linear 0.2s;
}
.content {
height: 100%;
}
.inner {
background: #afa;
transform: translateY(100%);
top: 100%;
}
.body:hover .inner,
.body:hover .content {
transform: translateY(-100%);
}
<div class="body">
<div class="content">
Blue is a viewport (<body>, visible part of a page), which content should be compressed upon green slide-in
</div>
<div class="inner">Green is variable-height text which slides in on viewport hover</div>
</div>

Show div on hover on same position

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

Categories