2

This works perfectly in Chrome and smoothly changes the icons, but in iOS Safari (and possibly desktop Safari), it does them in order, waiting till the other is done before doing the next:

Safari Transition:

  1. Does the rotation until complete
  2. Does the translate (x,y)

This makes for a very poor animation. In Chrome it's all done at the same time.

Is there a way to force that in Safari?

https://jsfiddle.net/6nju07s8/

HTML:

<div class="error" id="outer">
<div class="line left">
</div>
<div class="line right">

</div>

</div>

CSS:

#outer,body,html
{
  width: 100%;
  height: 100%
}
.line {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 2.5rem;
    height: .375rem;
    background-color: red;
    -webkit-transform: translate(-50%,-50%) rotate(45deg);
    -ms-transform: translate(-50%,-50%) rotate(45deg);
    transform: translate(-50%,-50%) rotate(45deg);
    -webkit-transition: transform 250ms;
    transition: transform 250ms;
    -webkit-transition-timing-function: ease-in-out;
    transition-timing-function: ease-in-out;
}

.line.right {
    -webkit-transform: translate(-50%,-50%) rotate(-45deg);
    -ms-transform: translate(-50%,-50%) rotate(-45deg);
    transform: translate(-50%,-50%) rotate(-45deg);
}

.info .line {
    width: .375rem;
    height: .375rem;
    -webkit-transform: translate(-50%,-50%) translateY(-1.0625rem);
    -ms-transform: translate(-50%,-50%) translateY(-1.0625rem);
    transform: translate(-50%,-50%) translateY(-1.0625rem);
    background-color: blue;
}

.info .line.right {
    width: 1.75rem;
    height: .375rem;
    -webkit-transform: translate(-50%,-50%) translateY(.4375rem) rotate(90deg);
    -ms-transform: translate(-50%,-50%) translateY(.4375rem) rotate(90deg);
    transform: translate(-50%,-50%) translateY(.4375rem) rotate(90deg);
    background-color: blue;
}

JS (optional):

var outer = document.querySelector( "#outer" );

outer.onclick = function()
{
  if ( outer.className === "info" ) { outer.className = "error"; }
  else outer.className = "info";
}
Don Rhummy
  • 24,730
  • 42
  • 175
  • 330
  • I can't test on safari, but maybe you 'll be more lucky if you convert your transform translate, rotate,etc... to matrix. You can find good tools online for that. [here is a cool one](http://ds-overdesign.com/transform/matrix3d.html) – scraaappy Mar 04 '17 at 23:55

1 Answers1

2

I see an issue with Safari Desktop. I am not sure if it is the same issue you are speaking of, but when having a transition on transform and width issues arise.

I think the issue has to do with Safari re-positioning the element after the width change. In other browser it seems to happen fluidly, in Safari it is "jerky."

You can see a simplified example of that behaviour here. Unfortunately I don't know exactly why that is occurring, but we can accomplish the same effect by adjusting our approach. That is what I would suggest.


Rather than changing the width value(to avoid the issue in Safari), I used the scaleX(X) property. This will given you a very similar visual affect (adjusting the "height" of the line) and should not introduce the problems. You will have to also edit your top values to re-position the elements after scaling them (or adjust the translate(-50%,Y) value; I prefer using top).

Here's a demo. I also made some QoL markup changes, you will need to prefix everything if you want to use it in production.

$('.box').click(function(){
 $(this).toggleClass('info');
});
.parent {
    width: 100%;
    height: 100vh;
}

.box {
    width: 50px;
    height: 50px;
    background: lightblue;
}

.va {
    position: relative;
    top: 50%;
    -webkit-transform: translateY(-50%);
    transform: translateY(-50%);
    margin: 0 auto;
}

.line {
    display: inline-block;
    background: white;
    width: 2.5rem;
    height: .375rem;
    position: absolute;
    top: 50%;
    left: 50%;
    transition: all 250ms;
    transform: translate(-50%,-50%) rotate(45deg);
}

.line.right {
    background: red;
    transform: translate(-50%,-50%) rotate(-45deg);
}

.info .line.left {
    top: 20%;
    transform: translate(-50%,-50%) rotate(90deg) scaleX(.15);
}

.info .line.right {
    top: 60%;
    transform: translate(-50%,-50%) rotate(90deg) scaleX(.65);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent error">
    <div class="box va">
        <div class="line left"></div>
        <div class="line right"></div>
    </div>
</div>
justinw
  • 3,856
  • 5
  • 26
  • 41
  • You're right! It appears to be the change in width asking with transform, not the multiple transforms. and your solution works well on safari. – Don Rhummy Mar 05 '17 at 04:00