在Android上强制正确的CSS3转换百分比解释

tl;博士 ? 获取以下链接中演示的机制,以在Android Chrome和默认浏览器上使用GPU加速。

更新2 (2014-01-13 13:25:30Z):根据bref.it下面的评论,截至Android 4.4 KitKat报告的行为是固定的 – 但我下面描述的修复现在打破了它! 索德定律。

更新1 (2012-11-01 17:54:09Z):从转换元素的计算样式报告的变换矩阵可以推断出有缺陷的行为,它返回一个像素值。 我将尝试为此编写一个Modernizr测试,以便为任何可能的解决方案铺平道路。

我开发了一种滑动容器的机制,以显示全宽,水平排列的子部分。 滑动标签,基本上。 因为有很多性能密集的东西和精心设计的Javascript,我希望将JS保持在最低限度,并尽可能多地使用CSS中的纯粹风格。 我认为我做得很好,考虑到 – JS只是改变了包装器的一个属性:

(左)

http://jsfiddle.net/barney/VPJuq/ (移动设备可以附加/显示/显示这些小提琴url以自行查看结果)

关于这是如何工作的一句话:将标签视为inline-block s允许我指定white-space: nowrap (最后几条规则中的其余代码基本上折叠了标签之间的空白)并允许它们水平堆叠没有清除/返回,一直保持其父级的全宽。 从那里开始,为包装器设置负的左偏移就可以了。 很酷,对吧?

现在,一点上下文:我正在开发的接口是在本机移动应用程序中运行 – 应用程序的核心function依赖于尖端的移动专用技术(不要问 – NDA) – 通过UIWebView,而且是唯一的目前支持该技术的平台是Android。

在这里,我的问题是双重的: transform: translate工作a / lot / smoother( translate3d甚至更多)比leftmargin-left过渡,到一个非常可取的点,边缘线至关重要 – 特别是在Android上,看作非翻译在拥有最新操作系统的最新手机上,过渡仍然令人窒息。 考虑到这一点,问题的关键在于Android在与translate相关时似乎推断出盒子模型的不同。 为了演示,这里是基于transform的同一件事的版本,它与前一个小提琴做同样的事情,适用于支持translate3d的所有浏览器……

(带翻译)

http://jsfiddle.net/barney/EJ7ve

如果你在iPhone上检查这个(再次,通过追加/show ),你会注意到iPhone上的帧率有所提高。 对于在Android上运行的Firefox也是如此,可以说在Chrome和Android上的默认浏览器上也是如此,除了在这里,-100%的translateX偏移以某种方式指的是所有三个选项卡占用的空间,因此包装器滑动就足够了没有任何标签可见。 这很奇怪,因为变换百分比被指定为与正在变换的元素的完整框模型相关 – 并且计算出的样式明确地将包装宽度描述为与其父元素相同(不是,结果意味着,拉伸3倍到容纳标签)。

我们可以将其描述为一个错误吗?

据我所知,没有纯CSS(我不反对媒体查询function检测,CSS供应商分叉或财产黑客)推断和解决这个问题的方法。 事实上,我现在能够想到的唯一一种制作相同的CSS机制工作的方法是嗅探Android的UA字符串并有条件地应用不同的规则。 育! 如果我要制作一个Android-WebKit专用解决方案,并在其他地方打破function,我可以将事实上的行为考虑在内,并使百分比引用分数:

(带翻译 – 适用于Android 更新:Android 4.4 KitKat上的不必要和中断

http://jsfiddle.net/barney/nFt5t/

不理想,因为这会使UI浏览器特定,并且要求我们在编写CSS之前预先知道组中的选项卡数量。 但这甚至没有完全解决那里的问题,因为在方向改变时(这真的很奇怪),偏移切换到其他浏览器显示的规范正确行为!

我也尝试将翻译应用到实际的标签中,这些标签在其他任何地方都可以使用,但是尽管正确选择和应用规则,Android的浏览器也不会产生效果。 陌生人和陌生人:

(翻译,研究Android的理论,根本不在Android上工作)

http://jsfiddle.net/barney/EJ7ve/9

深入了解跨浏览器解决方案的任何见解或想法。

Solutions Collecting From Web of "在Android上强制正确的CSS3转换百分比解释"

我正在使用Android 2.3并且无法产生您描述的确切问题(关于您的评论“-100%以某种方式指的是所有三个选项卡占用的空间” )。 但是,我遇到了导致间歇性/跳跃性过渡的其他问题以及其他一些我没有真正研究的奇怪之处。

为了对话,我们假设“包装器”宽度为500px。

通过使用你的inline-block / nowrap技术(这是YUI非常不受欢迎的布局技术),你的3个选项卡面板占用了1500px的水平空间。 根据您的描述,您需要欺骗浏览器,使所有选项卡面板占据500px的水平空间。 检查我的小提琴,它基本上使用一些负边距并转换为以我认为应该工作的方式欺骗​​浏览器,但我无法测试它。 无论哪种方式,我的例子修复了我在Android 2.3上遇到的怪异 – 所以你可能想要以任何一种方式使用它。

http://jsfiddle.net/ryanwheale/EJ7ve/29/

(和相关的CSS)

 .tabs > * { width: 100%; margin-left: -100%; } .tabs > *:first-child { -webkit-transform: translate3d(0%, 0, 0); -moz-transform: translate3d(0%, 0, 0); -ms-transform: translate3d(0%, 0, 0); -o-transform: translate3d(0%, 0, 0); transform: translate3d(0%, 0, 0); } .tabs > *:first-child + * { -webkit-transform: translate3d(100%, 0, 0); -moz-transform: translate3d(100%, 0, 0); -ms-transform: translate3d(100%, 0, 0); -o-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); } .tabs > *:first-child + * + * { -webkit-transform: translate3d(200%, 0, 0); -moz-transform: translate3d(200%, 0, 0); -ms-transform: translate3d(200%, 0, 0); -o-transform: translate3d(200%, 0, 0); transform: translate3d(200%, 0, 0); } .tabs > *:first-child + * + * + * { -webkit-transform: translate3d(300%, 0, 0); -moz-transform: translate3d(300%, 0, 0); -ms-transform: translate3d(300%, 0, 0); -o-transform: translate3d(300%, 0, 0); transform: translate3d(300%, 0, 0); } 

注意:我尝试使用相对定位而不是上面的变换,我仍然得到了上面描述的相同的怪异。

我遇到了类似的问题。

对我来说问题是:

 * { box-sizing: border-box; } 

我将边框应用于所有元素。 删除后,翻译了百分比translate3d。

如果CSS不起作用(并且应该正常工作),则需要一种解决方法。 请检查我的修改版本:

http://jsfiddle.net/EG9v8/1/

 function makeCss(index){ // Calculate the offset, given the tabs size var size = -$('.tabs').width() * index; // Create style for the given offset. var css = '-webkit-transform: translate3d('+size+'px, 0, 0);'; css += '-moz-transform: translate3d('+size+'px, 0, 0);'; css += '-ms-transform: translate3d('+size+'px, 0, 0);'; css += '-o-transform: translate3d('+size+'px, 0, 0);'; css += 'transform: translate3d('+size+'px, 0, 0);'; return css; } $('.tabLinks a').on('click', function(e){ e.preventDefault(); var index = $(this).index(); // Set the current style $('.tabs').attr('style', makeCss(index)); });