1

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>
hayley
  • 384
  • 5
  • 17

2 Answers2

1

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>
Kaiido
  • 123,334
  • 13
  • 219
  • 285
0

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

Shubham K.
  • 67
  • 1
  • 9
  • I'm just wondering why the first time wrapping, the transition effect will disappear. Do you know the reason? – hayley Jun 23 '20 at 01:46
  • Yes I know because .click(function(){ when you click more than one .wrap( is calling every click so on **first click**
    Somecontent
    **on second click**
    Somecontent
    and so on That's why your are going in nested wrapping
    – Shubham K. Jun 23 '20 at 12:27
  • I do know that the fact that I keep doing nested wrapping. Your JSFiddle result shows that after the first wrapping, every card flipping transition works fine. And my question is whether the .wrap() cause the first time card flipping transition failed or not and why? – hayley Jun 23 '20 at 14:31