iOS CSS opacity + visibility transition

2019-01-23 18:40发布

问题:

Take a look at the following test in a desktop browser (JSFiddle):

a {
  background: gray;
  display: block;
  margin: 100px;
  padding: 100px;
}
a span {
  opacity: 0;
  -webkit-transition: 0.5s;
  visibility: hidden;
}
a:hover span {
  opacity: 1;
  -webkit-transition: 0.5s;
  visibility: visible;
}
<a href="#">a <span>span</span></a>

You hover over the anchor element and the span element fades in like it should.

Now take a look via an iOS device. Result: it does nothing.

Facts:

  • If the transition property is absent, it works.
  • If either the opacity or visibility property is absent, it works.
  • There is no webkitTransitionEnd event being fired for the opacity or visibility property.

Is there any workaround?

回答1:

Only opacity on transition sucks.

Since that on iPhone you need to tap in order to focus an element this is how I've fixed my problem:

.mydiv {
        visibility:hidden;
        opacity: 0;
        transition: all 1s ease-out; 
        -webkit-transition: all 1s ease-out;
        -moz-transition: all 1s ease-out;
        -o-transition: all 1s ease-out;
}
.mydiv:hover {
            visibility:visible;
            opacity: 1;
}
.mydiv:active {
            -webkit-transition: opacity 1s ease-out;
}

I've added the opacity transition to :active.

This way it works with all transition animation (consider that you want to apply animation to height or something else) on Chrome, Firefox and iPhone (on tap).

Thanks to Grezzo and Michael Martin-Smucker for spotting out about the opacity transition.

(copy/paste of my response from CSS animation visibility: visible; works on Chrome and Safari, but not on iOS)



回答2:

With some minor modifications to the transition property, this can work on iOS. On :hover, limit the transition to only the opacity property, like so:

a:hover span {
    opacity:1;
    -webkit-transition: opacity 0.5s;
    transition: opacity 0.5s;
    visibility:visible;
}​

While visibility is an animatable property, there seems to be a bug in the iOS implementation. When you try to transition visibility, it seems like the entire transition doesn't happen. If you simply limit your transition to opacity, things work as expected.

To be clear: Leave the visibility property in your CSS, just don't try to transition it if you want things to work in Mobile Safari.

For reference, here's your updated fiddle, which I tested on an iPad:

a {
  background: gray;
  display: block;
  margin: 100px;
  padding: 100px;
}
a span {
  opacity: 0;
  -webkit-transition: 0.5s;
  visibility: hidden;
}
a:hover span {
  opacity: 1;
  -webkit-transition: opacity 0.5s;
  visibility: visible;
}
<a href="#">a <span>span</span></a>