CSS3 Transitioning Transforms in Mobile WebKit
I have a transition transform on an element in CSS3, but whenever I run the animation, it seems that one of the elements involved in the animation is always hidden for the duration of the animation.
Here is the CSS, HTML and JavaScript code:
CSS
div.toggle {
font-family: Arial, Helvetica, sans-serif;
width: 92px;
overflow: hidden;
cursor: default;
border-radius: 3px;
border: 1px solid #919191;
float: right;
position: relative;
height: 26px
}
div.toggle div.control-cont {
display: -webkit-box;
position: absolute;
-webkit-transition:all 0.2s ease-in-out;
width: 155px;
}
div.toggle span {
display: inline-block;
float: left;
text-transform: uppercase;
position: relative;
float: left;
}
div.toggle span.on {
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(41,90,178,1)), color-stop(50%,rgba(64,133,236,1)), color-stop(51%,rgba(77,143,239,1)), color-stop(100%,rgba(118,173,252,1)));
background: -webkit-linear-gradient(top, rgba(41,90,178,1) 0%,rgba(64,133,236,1) 50%,rgba(77,143,239,1) 51%,rgba(118,173,252,1) 100%);
font-weight: bold;
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
font-size: 16px;
width: 57px;
text-align: center;
padding-top: 4px;
}
div.toggle.important span.on {
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(210,102,8,1)), color-stop(2%,rgba(234,115,10,1)), color-stop(4%,rgba(248,123,12,1)), color-stop(50%,rgba(255,140,14,1)), color-stop(51%,rgba(255,153,33,1)), color-stop(100%,rgba(254,188,86,1)));
background: -webkit-linear-gradient(top, rgba(210,102,8,1) 0%,rgba(234,115,10,1) 2%,rgba(248,123,12,1) 4%,rgba(255,140,14,1) 50%,rgba(255,153,33,1) 51%,rgba(254,188,86,1) 100%);
}
div.toggle span.handle {
border-radius: 3px;
height: 26px;
border-left: 1px solid #9f9f9f;
border-right: 1px solid #9f9f9f;
width: 39px;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(239,239,239,1)), color-stop(3%,rgba(206,206,206,1)), color-stop(100%,rgba(251,251,251,1)));
background: -webkit-linear-gradient(top, rgba(239,239,239,1) 0%,rgba(206,206,206,1) 3%,rgba(251,251,251,1) 100%);
z-index: 10;
left: -5px
}
div.toggle span.off {
font-size: 16px;
font-weight: bold;
color: #7e7e7e;
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(181,181,181,1)), color-stop(2%,rgba(207,207,207,1)), color-stop(4%,rgba(223,223,223,1)), color-stop(6%,rgba(231,231,231,1)), color-stop(50%,rgba(239,239,239,1)), color-stop(51%,rgba(249,249,249,1)), color-stop(100%,rgba(254,254,254,1)), color-stop(100%,rgba(251,251,251,1)));
background: -webkit-linear-gradient(top, rgba(181,181,181,1) 0%,rgba(207,207,207,1) 2%,rgba(223,223,223,1) 4%,rgba(231,231,231,1) 6%,rgba(239,239,239,1) 50%,rgba(249,249,249,1) 51%,rgba(254,254,254,开发者_如何学JAVA1) 100%,rgba(251,251,251,1) 100%);
left: -10px;
text-align: center;
padding-top: 4px;
width: 57px;
}
div.toggle input {
display: none;
}
JavaScript:
(function($) {
$.fn.toggle = function()
{
this.each(function() {
var toggle_class = ($(this).attr('checked')) ? 'checked' : '';
var important_class = ($(this).hasClass('important')) ? 'important' : '';
var this_transformed = false;
var this_toggle = $('<div class="toggle">\
<div class="control-cont">\
<span class="on">on</span>\
<span class="handle"></span>\
<span class="off">off</span>\
</div>\
</div>');
this_toggle.addClass(toggle_class);
this_toggle.addClass(important_class);
var thecheckbox = this;
$(this).replaceWith(this_toggle);
this_toggle.append(thecheckbox);
if(toggle_class != 'checked')
{
this_toggle.find('.control-cont').css({ left: '-53px' });
}
this_toggle.click(toggle_switch);
$(thecheckbox).change(toggle_switch);
function toggle_switch() {
var self = $(this);
var this_off = $(this).find('.off');
var this_on = $(this).find('.on');
var this_container = $(this).find('.control-cont');
var the_checkbox = $(this).find('input[type="checkbox"]');
if($(this).hasClass('checked'))
{
if(!this_transformed)
{
this_container.css("-webkit-transform", "translate(-53px, 0px)");
this_transformed = true;
}
else
{
this_container.css("-webkit-transform", "translate(53px, 0px)");
}
self.removeClass('checked');
the_checkbox.attr('checked', false);
}
else
{
if(!this_transformed)
{
this_container.css("-webkit-transform", "translate(53px, 0px)");
this_transformed = true;
}
else
{
this_container.css("-webkit-transform", "translate(0px, 0px)");
}
self.addClass('checked');
the_checkbox.attr('checked', true);
}
};
});
};
}) ( jQuery );
Essentially, the animation moves the entire div.control-con
along or backwards, depending on the checkbox's status. Everything works fine in Chrome and Safari, but when running in Mobile Safari, for some reason the span.off
and span.on
elements are not displayed when the animation is run.
Which span element is hidden depends on the direction of the animation. Here's a screenshot of the problem, you'll notice that the span.off
isn't displayed until the animation is complete:
I've also put this into a jsFiddle for reference: http://jsfiddle.net/kShEQ/
Mobile Safari is not an exact clone of normal safari and the webkit engine. It's a myth that there's a single webkit engine haha. Mobile Safari renders transitions differently. From what I've seen, the syntax in which you enter the transition values differs slightly. Check out this semi-similar stackoverflow question:
Scaling problem with -webkit-transform with mobile safari on iPad
精彩评论