Click on the image in snippet (expand full page) to run transform and look more closely at bottom right corner when animated card goes behind, you will see it overlaps slightly when it shouldn't. I happens when I apply z-index on each box div in CSS. If I remove z-index, there is no flash, but I need z-indexes on my box divs. Otherwise I cant have stack behave in such when I shuffle them (unless I change DOM order which I don't want). I have tried with some backface-visibility in CSS but with no luck. How could I get rid of such flash?
$('body').on('click', function() {
var box = $('#a2')
box.one("transitionend", function() {
box.css("zIndex", -1).one("transitionend", function() {
}).removeClass('t').addClass('t2')
}).addClass('t')
})
.box {
position: absolute;
width: 250px;
padding: 10px;
background: #fff;
box-shadow: 1px 1px 5px #484848;
left: 0;
top: 0;
height: 370px;
box-sizing: content-box;
transition-duration: 0.5s;
transition-timing-function: ease;
backface-visibility: hidden;
}
.box img {
display: block;
position: relative;
backface-visibility: hidden;
user-select: none;
}
#a1 {
z-index: 0;
transform: rotate(-4.5884deg);
}
#a2 {
z-index: 1;
transform: rotate(7deg);
}
.t {
transform: translateX(370px) rotate(23deg) !important;
}
.t2 {
transform: translateX(0) rotate(-7deg) !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="box" id="a1">
<img src="http://interactivepixel.net/tst/01.jpg" alt="" />
</div>
<div class="box" id="a2">
<img src="http://interactivepixel.net/tst/02.jpg" alt="" />
</div>
Happens in all browsers from what I can see.
The fix is actually simple - just add transition-property: transform because that is what you want to transform (transition-property: all is the default and z-index is also transitioned).
See demo below:
$('body').on('click', function() {
var box = $('#a2')
box.one("transitionend", function() {
box.css("zIndex", -1).removeClass('t').addClass('t2')
}).addClass('t')
});
.box {
position: absolute;
width: 250px;
padding: 10px;
background: #fff;
box-shadow: 1px 1px 5px #484848;
left: 0;
top: 0;
height: 370px;
box-sizing: content-box;
transition-duration: 0.5s;
transition-timing-function: ease;
backface-visibility: hidden;
transition-property: transform; /* added */
}
.box img {
display: block;
position: relative;
backface-visibility: hidden;
user-select: none;
}
#a1 {
z-index: 0;
transform: rotate(-4.5884deg);
}
#a2 {
z-index: 1;
transform: rotate(7deg);
}
.t {
transform: translateX(370px) rotate(23deg) !important;
}
.t2 {
transform: translateX(0) rotate(-7deg) !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="box" id="a1">
<img src="http://interactivepixel.net/tst/01.jpg" alt="" />
</div>
<div class="box" id="a2">
<img src="http://interactivepixel.net/tst/02.jpg" alt="" />
</div>
Why the flicker?
Note that z-index is an integer and it doesn't make much sense to transition it - the animation type is integer according to MDN:
When animated, values of the data type are interpolated
using discrete, whole steps. The calculation is done as if they were
real, floating-point numbers; the discrete value is obtained using the
floor function. The speed of the interpolation is determined by the
timing function associated with the animation.
See a sample of how you can animate z-index:
div {
position: absolute;
border: 1px solid;
}
.container div {
width: 100px;
height: 100px;
}
.container .box {
background-color: cadetblue;
z-index: 1;
animation: stack 5s infinite linear;
}
.box + div {
top: 10px;
left: 10px;
z-index: 1;
background-color: lightblue;
}
.box + div + div {
top: 20px;
left: 20px;
z-index: 2;
background-color: aliceblue;
}
#keyframes stack {
50% {
z-index: 3;
}
}
<div class="container">
<div class="box"></div>
<div></div>
<div></div>
</div>
This is why you have the flicker in your animation.
I think it is merely an order problem.
Just place the .css (" zIndex ", -1) next to the .addClass ('t'):
this way flash doesn't happen since z-index is applyed before the backward translation
$('body').on('click', function() {
var box = $('#a2')
box.one("transitionend", function() {
box.removeClass('t').addClass('t2')
}).css("zIndex", -1).addClass('t')
})
I just update your code with jQuery update. Actually i just move your box.css("zIndex", -1).addClass('t'); script in setTimeout method. Try this I hove it'll resolve your issue. Thanks
$('body').on('click', function() {
var box = $('#a2')
box.one("transitionend", function() {
box.one("transitionend").addClass('t2');
})
setTimeout(function(){
box.css("zIndex", -1).addClass('t');
})
})
.box {
position: absolute;
width: 250px;
padding: 10px;
background: #fff;
box-shadow: 1px 1px 5px #484848;
left: 0;
top: 0;
height: 370px;
box-sizing: content-box;
transition-duration: 0.5s;
transition-timing-function: ease;
backface-visibility: hidden;
}
.box img {
display: block;
position: relative;
backface-visibility: hidden;
user-select: none;
}
#a1 {
z-index: 0;
transform: rotate(-4.5884deg);
}
#a2 {
z-index: 1;
transform: rotate(7deg);
}
.t {
transform: translateX(370px) rotate(23deg) !important;
}
.t2 {
transform: translateX(0) rotate(-7deg) !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="box" id="a1">
<img src="http://interactivepixel.net/tst/01.jpg" alt="" />
</div>
<div class="box" id="a2">
<img src="http://interactivepixel.net/tst/02.jpg" alt="" />
</div>
I tried increasing the z-index of the succeeding image and it works.
$('body').on('click', function() {
var box = $('#a2')
var i=0;
box.one("transitionend", function() {
// increase the z-index
$("#a1").css("zIndex", 99);
box.css("zIndex", -1).one("transitionend", function() {
}).removeClass('t').addClass('t2')
}).addClass('t')
})
.box {
position: absolute;
width: 250px;
padding: 10px;
background: #fff;
box-shadow: 1px 1px 5px #484848;
left: 0;
top: 0;
height: 370px;
box-sizing: content-box;
transition-duration: 0.5s;
transition-timing-function: ease;
backface-visibility: hidden;
}
.box img {
display: block;
position: relative;
backface-visibility: hidden;
user-select: none;
}
#a1 {
z-index: 0;
transform: rotate(-4.5884deg);
}
#a2 {
z-index: 1;
transform: rotate(7deg);
}
.t {
transform: translateX(370px) rotate(23deg) !important;
}
.t2 {
transform: translateX(0) rotate(-7deg) !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="box" id="a1">
<img src="http://interactivepixel.net/tst/01.jpg" alt="" />
</div>
<div class="box" id="a2">
<img src="http://interactivepixel.net/tst/02.jpg" alt="" />
</div>
Related
Here is a codepen: https://codepen.io/jon424/pen/XWzGNLe
In this example, if you select the toggle button, the image will be covered by another div. The white square will gradually cover the image from the top of the image to the bottom.
I simply want to reverse this effect. I want the white square to cover the image, moving from the bottom of the image to the top.
I’ve tried using a negative value for max-height in the .covered class, but that wasn’t working. Any idea on how I can go about doing this?
document.querySelector('.child2').classList.add('covered');
document.querySelector('button').addEventListener('click', () => {
document.querySelector('.child2').classList.toggle('covered');
});
.parent {
position: relative;
width: 300px;
height: 300px;
margin: 10px;
overflow: hidden;
}
.child1 {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.child2 {
z-index: 1;
background: #ffffff;
transition: max-height 1s ease-in-out;
max-height:100%;
}
.covered {
max-height: 0px;
}
<button>Toggle</button>
<div class="parent">
<img class="child1" src="https://picsum.photos/200/300">
<div class="child1 child2"></div>
</div>
Very simple: change the top: 0; attribute in .child1 to bottom: 0;
Here is another way to do it you can manipulate the top of the child2:
document.querySelector('button').addEventListener('click', () => { document.querySelector('.child2').classList.toggle('covered');});
.parent {
position: relative;
width: 300px;
height: 300px;
margin: 10px;
overflow: hidden;
}
.child1 {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.child2 {
position: absolute;
top: 100%;
z-index: 1;
background: #ffffff;
transition: top 1s ease-in-out;
max-height: 100%;
}
.covered {
top: 0px;
}
<button>Toggle</button>
<div class="parent">
<img class="child1" src="https://picsum.photos/200/300">
<div class="child1 child2"></div>
</div>
By adding those lines on .child2 I am getting I think what you want:
bottom:0;
top:unset;
Here is the full working example:
document.querySelector(".child2").classList.add("covered");
document.querySelector("button").addEventListener("click", () => {
document.querySelector(".child2").classList.toggle("covered");
});
.parent {
position: relative;
width: 300px;
height: 300px;
margin: 10px;
overflow: hidden;
}
.child1 {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.child2 {
z-index: 1;
background: #ffffff;
transition: max-height 1s ease-in-out;
max-height: 100%;
bottom:0;
top:unset;
}
.covered {
max-height: 0px;
}
<button>Toggle</button>
<div class="parent">
<img class="child1" src="https://picsum.photos/200/300">
<div class="child1 child2"></div>
</div>
Not sure but are you looking for this type of effect, I know CSS solution if this help you.
.parent {
position: relative;
}
.parent::before {
content: "";
position: absolute;
height: 0;
width: 100%;
background-color: white;
bottom: 100%;
left: 0;
transition: all 0.9s ease-in-out;
}
.parent:hover::before {
height: 100%;
bottom: 0;
-webkit-transition: height 0.9s ease;
transition: height 0.9s ease;
}
<div class="parent">
<img class="child1" src="https://picsum.photos/200/300">
</div>
</div>
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/
I want to make tarot games. When the user click the card, the size of the card scales and the position of the card moves to the center of the screen. So I want to add a parent div on .flipping-card element after click event by calling jQuery wrap() function. Here's my js code:
Before I add this line: $(this).wrap("<div class='h-modal-bg'></div>");
The tarot cards flip transition effect works perfectly. But after adding that line, the transition effect just disappeared. Can somebody tell me what's wrong with this code? Thank you! (When you run my code on snippets, it's better to resize the screen size to the mobile
$(function() {
$('.h-flipping-card').click(function(){
$(this).toggleClass('card-flipped');
$(this).closest('.card-frame').wrap("<div class='h-modal-bg h-modal-bg-show'></div>");
});
});
*, *:before, *::after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.h-flipping-card {
position: relative;
width: 96%;
height: 0;
padding-bottom: 144%;
display: block;
margin: 0 auto;
perspective: 1000px;
}
.h-flipping-card-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.8s;
}
.h-flipping-card-front, .h-flipping-card-back {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 18px;
box-shadow: 2px 1px 15px #8A8A8A;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.h-flipping-card-front {
transform: rotateY(180deg);
}
.h-flipping-card-back {
background-color: brown;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.h-flipping-card-front[data-tarot-opt='demo1'] {
background-color: orange;
background-size: 130% auto;
background-repeat: no-repeat;
background-position: center;
}
.h-flipping-card.card-flipped .h-flipping-card-content {
transform: rotateY(180deg);
}
.h-modal-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(33, 33, 33, 0.48);
z-index: 10000;
visibility: hidden;
display: flex;
flex-direction: column;
justify-content: center;
opacity: 0;
-webkit-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.h-modal-bg-show {
visibility: visible;
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="card-frame" style="max-width: 320px; width: 50%; display: inline-block;">
<div class="h-flipping-card">
<div class="h-flipping-card-content">
<div class="h-flipping-card-back"></div>
<div class="h-flipping-card-front" data-tarot-opt="demo1"></div>
</div>
</div>
</div>
</div>
This is because when you call $.wrap(), your original element is removed from the DOM, and then appended again.
Doing so, its computed style gets set directly to the one set by the class .card-flipped, and there is nothing to transition anymore, since for the CSS engine it's already in this flipped state.
You can see this related Q/A which explains a very similar situation.
The solution is thus to first wrap your element, then force a reflow so the CSS engine knows what's the current computed style of your element, and finally change its class, so the transition happens.
$(function() {
$('.h-flipping-card').click(function(){
// first DOM manip
$(this).closest('.card-frame').wrap("<div class='h-modal-bg h-modal-bg-show'></div>");
document.body.offsetWidth; // force recalc
$(this).toggleClass('card-flipped'); // now ask for transition
});
});
$(function() {
$('.h-flipping-card').click(function(){
$(this).closest('.card-frame').wrap("<div class='h-modal-bg h-modal-bg-show'></div>");
document.body.offsetWidth;
$(this).toggleClass('card-flipped');
});
});
*, *:before, *::after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.h-flipping-card {
position: relative;
width: 96%;
height: 0;
padding-bottom: 144%;
display: block;
margin: 0 auto;
perspective: 1000px;
}
.h-flipping-card-content {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
transition: transform 0.8s;
}
.h-flipping-card-front, .h-flipping-card-back {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 18px;
box-shadow: 2px 1px 15px #8A8A8A;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.h-flipping-card-front {
transform: rotateY(180deg);
}
.h-flipping-card-back {
background-color: brown;
background-size: cover;
background-repeat: no-repeat;
background-position: center;
}
.h-flipping-card-front[data-tarot-opt='demo1'] {
background-color: orange;
background-size: 130% auto;
background-repeat: no-repeat;
background-position: center;
}
.h-flipping-card.card-flipped .h-flipping-card-content {
transform: rotateY(180deg);
}
.h-modal-bg {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(33, 33, 33, 0.48);
z-index: 10000;
visibility: hidden;
display: flex;
flex-direction: column;
justify-content: center;
opacity: 0;
-webkit-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
}
.h-modal-bg-show {
visibility: visible;
opacity: 1;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class="card-frame" style="max-width: 320px; width: 50%; display: inline-block;">
<div class="h-flipping-card">
<div class="h-flipping-card-content">
<div class="h-flipping-card-back"></div>
<div class="h-flipping-card-front" data-tarot-opt="demo1"></div>
</div>
</div>
</div>
</div>
I think the issue is when your click event trigger every time your wrap function is calling and so .card-frame is wrapping inside already wrapped div.
So I think you just want to wrap only once on first click. So I tried something one click function check this
$(function() {
$('.h-flipping-card').click(function(){
$(this).toggleClass('card-flipped');
});
$('.h-flipping-card').one("click", function(){
$(this).closest('.card-frame').wrap("<div class='h-modal-bg h-modal-bg-show'></div>");
});
});
Here is my JSFiddle Link
I'm trying to change the color every image on click but they are not properly selectable because of overlying each other with positioning and z-index...
code is working as you can check by clicking on top right corner it change color...tried different methods of CSS, not JavaScript... newbie in JavaScript.
body,div,p,h1,h2,h3,h4,h5,h6,span {
margin: 0;
}
div.nav {
height: 100px;
width: 100%;
padding: 20px 0;
background-color: #615d5d;
text-align: center;
}
.screens_wrap {
display: inline-block;
margin: 0 auto;
height: 100%;
position: relative;
}
.screen_inner {
position: relative;
height: 100%;
margin: 0 auto;
width: 150px;
}
.screen {
position: absolute;
width:100px;
height: 58px;
border: 3px solid #aeaeae;
}
/* transparent style -------------------------------------------------------------------*/
.nav .screen.screen1 {
bottom: 0;
left: 0;
z-index: 3;
background-color: #00ad63;
}
.nav a .screen.screen2 {
bottom: 15px;
left: 15px;
z-index: 2;
background-color: transparent;
}
.nav a .screen.screen2:hover{
background-color: #4f025a;
}
.nav .screen.screen3 {
bottom: 30px;
left: 30px;
z-index: 1;
background-color: transparent;
}
.nav .screen.screen3:hover{
background-color: #ffec36;
}
.nav .screen2:hover, .screen3:hover {
-webkit-animation-name: hover;
-webkit-animation-duration: 1s;
animation-name: hover;
animation-duration: 4s;
-webkit-animation-fill-mode: forwards;
opacity: 1;
width: 100px;
}
.nav.nav6 {
height: 200px;
}
.screen_inner a.screenanchors:first-child img {
position: absolute;
left: 0;
top: 0;
z-index: 1;
}
.screen_inner a.screenanchors:nth-child(2) img{
position: absolute;
left: 20px;
top: 20px;
z-index: 2;
}
.screen_inner a.screenanchors:nth-child(3) img{
position: absolute;
left: 40px;
top: 40px;
z-index: 3;
}
.screenanchors img {
overflow: hidden;
}
#keyframes spinning {
from {
transform: translateZ(-5em) rotateY(0deg);
}
to {
transform: translateZ(-5em) rotateY(180deg);
}
}
#keyframes skewing {
from {
transform: translateZ(-5em) skew(-3deg, -25deg);
}
to {
transform: translateZ(-5em) skew(-3deg, 0deg);
width: 100%;
height: 100px;
z-index: 9999999;
bottom: 0;
}
}
/* Standard syntax */
#keyframes hover {
0% {
margin-bottom:+10px;
bottom: unset;
}
100% {
margin-bottom:+10px;
bottom: unset;
}
}
<div class="nav nav6" style="margin-top: 25px;">
<div class="screens_wrap">
<div class="screen_inner">
<img id="imgName" src="https://imageshack.com/i/plylrZh4p" onclick="changeSrc()" width="100px">
<img id="imgName1" src="https://imageshack.com/i/pljaZE0Gp" onclick="changeSrc1()" width="100px">
<img id="imgName2" src="https://imageshack.com/i/plm9slyTp" onclick="changeSrc2()" width="100px">
</div>
</div>
</div>
<script>
function changeSrc(){
document.getElementById("imgName").src="https://imageshack.com/i/plm9slyTp";
document.getElementById("imgName1").src="https://imageshack.com/i/plylrZh4p";
document.getElementById("imgName2").src="https://imageshack.com/i/pljaZE0Gp";
}
function changeSrc1(){
document.getElementById("imgName").src="https://imageshack.com/i/pljaZE0Gp";
document.getElementById("imgName1").src="https://imageshack.com/i/plm9slyTp";
document.getElementById("imgName2").src="https://imageshack.com/i/plylrZh4p";
}
function changeSrc2(){
document.getElementById("imgName").src="https://imageshack.com/i/plylrZh4p";
document.getElementById("imgName1").src="https://imageshack.com/i/pljaZE0Gp";
document.getElementById("imgName2").src="https://imageshack.com/i/plm9slyTp";
}
</script>
it should work by clicking every where on single image, no overlay effecting clickable space...
Just to Help out others, I fixed the issue using area mapping...
I am just playing around trying to get a simple 3 slide slider working but run into some issues with the javascript. All i want to happen is on click of the slider colour i would like the current slider to slide out and the selected one to slide in. I am trying to do it by adding an active class to the slider number that I have clicked to show. I just cant quite work out where I have gone wrong. I don't want to use jQuery as I am trying to learn vanilla javascript.
Thanks as always
window.onload = onPageLoad();
function onPageLoad() {
document.querySelector('.red').classList.add('active');
};
document.querySelector('.box').addEventListener('click', function() {
document.querySelector('.red').classList.toggle('active');
document.querySelector('.green').classList.toggle('active');
document.querySelector('.yellow').classList.toggle('active');
});
* {
padding: 0;
margin: 0;
}
.main__wrapper {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
.red,
.green,
.yellow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
transform: translateX(-100%);
transition: transform 1.2s;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.yellow {
background-color: yellow;
}
.active {
transform: translateX(0) !important;
transition: transform 1s !important;
}
.slide__select {
position: absolute;
bottom: 0;
right: 0;
width: 60%;
height: 20%;
z-index: 10;
display: flex;
}
.box {
position: relative;
flex: 1 0 0;
color: $color-white;
display: flex;
align-items: center;
cursor: pointer;
background-color: #A68D71;
}
.box span {
display: block;
position: relative;
z-index: 11;
}
.box::after {
content: "";
position: absolute;
top: 0;
left: 0;
background-color: yellow;
width: 100%;
height: 0;
transition: height .3s;
}
.box:hover::after {
height: 100%;
transition: height .3s;
}
<div class="main__wrapper">
<section class="red">
</section>
<section class="green">
</section>
<section class="yellow">
</section>
<div class="slide__select">
<div class="box">
<span>red</span>
</div>
<div class="box">
<span>green</span>
</div>
<div class="box">
<span>yellow</span>
</div>
</div>
</div>
You're only adding an event listener to the first box and you're toggling every box's active class in order, and the last one is yellow, so you result with a yellow background.
querySelector returns the first DOM element it finds, which is the red box.
For the functionality that you want, you have to add event listeners to each box (querySelectorAll)
window.onload = onPageLoad();
function onPageLoad() {
document.querySelector('.red').classList.add('active');
};
document.querySelector('.redbox').addEventListener('click', function() {
document.querySelector('.red').classList.add('active');
document.querySelector('.green').classList.remove('active');
document.querySelector('.yellow').classList.remove('active');
});
document.querySelector('.greenbox').addEventListener('click', function() {
document.querySelector('.red').classList.remove('active');
document.querySelector('.green').classList.add('active');
document.querySelector('.yellow').classList.remove('active');
});
document.querySelector('.yellowbox').addEventListener('click', function() {
document.querySelector('.red').classList.remove('active');
document.querySelector('.green').classList.remove('active');
document.querySelector('.yellow').classList.add('active');
});
* {
padding: 0;
margin: 0;
}
.main__wrapper {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
.red,
.green,
.yellow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
transform: translateX(-100%);
transition: transform 1.2s;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.yellow {
background-color: yellow;
}
.active {
transform: translateX(0) !important;
transition: transform 1s !important;
}
.slide__select {
position: absolute;
bottom: 0;
right: 0;
width: 60%;
height: 20%;
z-index: 10;
display: flex;
}
.box {
position: relative;
flex: 1 0 0;
color: $color-white;
display: flex;
align-items: center;
cursor: pointer;
background-color: #A68D71;
}
.box span {
display: block;
position: relative;
z-index: 11;
}
.box::after {
content: "";
position: absolute;
top: 0;
left: 0;
background-color: yellow;
width: 100%;
height: 0;
transition: height .3s;
}
.box:hover::after {
height: 100%;
transition: height .3s;
}
<div class="main__wrapper">
<section class="red">
</section>
<section class="green">
</section>
<section class="yellow">
</section>
<div class="slide__select">
<div class="redbox box">
<span>red</span>
</div>
<div class="greenbox box">
<span>green</span>
</div>
<div class="yellowbox box">
<span>yellow</span>
</div>
</div>
</div>
Here is a primitive example solution. It's overly verbose but shows you what is needed. This can be condensed.
To get an idea of how it can be condensed, all three listeners CAN be condensed into a single listener how you had it, listen just to the .box selector. But if you do that, you need a way to identify which box was clicked. This can be done via a data attribute or by looking at the html text. A data attribute would be my preferred method, as it separates the content from the logic a bit, but either would work.
Another less verbose solution:
window.onload = onPageLoad();
function onPageLoad() {
document.querySelector('.red').classList.add('active');
};
var boxes = document.querySelectorAll('.box');
for (var i = 0; i < boxes.length; i++) {
boxes[i].addEventListener('click', toggleSections);
}
var colors = ['red', 'green', 'yellow'];
function toggleSections(ev) {
var color = ev.currentTarget.innerText;
for (var c = 0; c < colors.length; c++) {
var colorElem = document.querySelector('.' + colors[c]);
if (colors[c] != color) {
colorElem.classList.remove('active');
} else {
colorElem.classList.add('active');
}
}
}
* {
padding: 0;
margin: 0;
}
.main__wrapper {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
.red,
.green,
.yellow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
transform: translateX(-100%);
transition: transform 1.2s;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.yellow {
background-color: yellow;
}
.active {
transform: translateX(0) !important;
transition: transform 1s !important;
}
.slide__select {
position: absolute;
bottom: 0;
right: 0;
width: 60%;
height: 20%;
z-index: 10;
display: flex;
}
.box {
position: relative;
flex: 1 0 0;
color: $color-white;
display: flex;
align-items: center;
cursor: pointer;
background-color: #A68D71;
}
.box span {
display: block;
position: relative;
z-index: 11;
}
.box::after {
content: "";
position: absolute;
top: 0;
left: 0;
background-color: yellow;
width: 100%;
height: 0;
transition: height .3s;
}
.box:hover::after {
height: 100%;
transition: height .3s;
}
<div class="main__wrapper">
<section class="red">
</section>
<section class="green">
</section>
<section class="yellow">
</section>
<div class="slide__select">
<div class="box">
<span>red</span>
</div>
<div class="box">
<span>green</span>
</div>
<div class="box">
<span>yellow</span>
</div>
</div>
</div>
To achieve expected result, use below option
Use one section to avoid looping of section elements
Use querySelectorAll or elementsByClassName instead of querySelector to fetch all elements in array
Use forEach to loop through all elements of class- box and add addEventListener and run another loop with forEach for span elements
Use classList to add or remove
window.onload = onPageLoad();
function onPageLoad() {
document.querySelector('.red').classList.add('active');
};
// use querySelectorAll to get all elements of class-box and forEach to loop through
document.querySelectorAll('.box').forEach(function(ele){
//Add clici event through addEventListener
ele.addEventListener('click', function() {
// use another querySelectorAll to get all elements of tag span and forEach to loop through
document.querySelectorAll('span').forEach(function(e){
e.classList.remove('active');
//use querySelector for section element and empty classList to remove active and red/green/yellow class names
document.querySelector('section').className ='';
});
//toggle active class for clicked element
ele.children[0].classList.toggle("active");
//add active class for section
document.querySelector('section').classList.add('active');
//add class red/yellow/green using span innerHTML
document.querySelector('section').classList.add(ele.children[0].innerHTML);
});
});
* {
padding: 0;
margin: 0;
}
.main__wrapper {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
.red,
.green,
.yellow {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
transform: translateX(-100%);
transition: transform 1.2s;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.yellow {
background-color: yellow;
}
.active {
transform: translateX(0) !important;
transition: transform 1s !important;
}
.slide__select {
position: absolute;
bottom: 0;
right: 0;
width: 60%;
height: 20%;
z-index: 10;
display: flex;
}
.box {
position: relative;
flex: 1 0 0;
color: $color-white;
display: flex;
align-items: center;
cursor: pointer;
background-color: #A68D71;
}
.box span {
display: block;
position: relative;
z-index: 11;
}
.box::after {
content: "";
position: absolute;
top: 0;
left: 0;
background-color: yellow;
width: 100%;
height: 0;
transition: height .3s;
}
.box:hover::after {
height: 100%;
transition: height .3s;
}
<div class="main__wrapper">
<section class="red">
</section>
<div class="slide__select">
<div class="box">
<span>red</span>
</div>
<div class="box">
<span>green</span>
</div>
<div class="box">
<span>yellow</span>
</div>
</div>
</div>
code sample - https://codepen.io/nagasai/pen/vRoPwp