简体   繁体   English

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

[英]Force correct CSS3 transform percentage interpretation on Android

tl;dr ? tl;博士 Get the mechanism demonstrated in the link below to behave with GPU acceleration on Android Chrome & default browser. 获取以下链接中演示的机制,以在Android Chrome和默认浏览器上使用GPU加速。

UPDATE 2 (2014-01-13 13:25:30Z): According to bref.it 's comment below, the reported behaviour is fixed as of Android 4.4 KitKat — but the fix I described below now breaks it! 更新2 (2014-01-13 13:25:30Z):根据bref.it下面的评论,截至Android 4.4 KitKat报告的行为是固定的 - 但我下面描述的修复现在打破了它! Sod's law. 索德定律。

UPDATE 1 (2012-11-01 17:54:09Z): The buggy behaviour is inferrable from the transformation matrix as reported by the computed style of the transformed element, which returns a pixel value. 更新1 (2012-11-01 17:54:09Z):从转换元素的计算样式报告的变换矩阵可以推断出有缺陷的行为,它返回一个像素值。 I'll try to write a Modernizr test for this to pave the way for any possible solutions. 我将尝试为此编写一个Modernizr测试,为任何可能的解决方案铺平道路。

I've developed a mechanism for sliding a container to reveal full-width, horizontally arranged sub-sections. 我开发了一种滑动容器的机制,以显示全宽,水平排列的子部分。 Sliding tabs, basically. 滑动标签,基本上。 Because there's a lot of performance intensive stuff and elaborate Javascript going on, I want to keep JS to the minimum and do as much of the purely stylistic in CSS. 因为有很多性能密集的东西和精心设计的Javascript,我希望将JS保持在最低限度,并尽可能多地使用CSS中的纯粹风格。 I think I've done pretty well, considering — JS just changes an attribute on the wrapper: 我认为我做得很好,考虑到 - JS只是改变了包装器的一个属性:

(w/ left) (左)

http://jsfiddle.net/barney/VPJuq/ (mobile devices can append /show/ to these fiddle URLs to see the results by themselves) http://jsfiddle.net/barney/VPJuq/ (移动设备可以附加/显示/显示这些小提琴网址以自行查看结果)

A word on how this works: treating the tabs as inline-block s allows me to specify white-space: nowrap (the rest of the code in the last couple of rules essentially collapses the whitespace between the tabs) and allow them to stack horizontally without clearing / returning, all the while each maintaining the full width of their parent. 关于这是如何工作的一句话:将标签视为inline-block s允许我指定white-space: nowrap (最后几条规则中的其余代码基本上折叠标签之间的空白)并允许它们水平堆叠没有清除/返回,一直保持其父的全宽。 From there, setting a negative left offset to the wrapper does the magic. 从那里开始,为包装器设置负的左偏移就可以了。 Cool, huh? 很酷,对吧?

Now, a bit of context: the interface I'm developing is to be run in native mobile applications — the application's core functionality relies on cutting edge mobile-specific technology (don't ask — NDA) — via a UIWebView, and the only platform that currently supports the technology in question is Android. 现在,有点上下文:我正在开发的接口是在本机移动应用程序中运行 - 应用程序的核心功能依赖于尖端的移动专用技术(不要问 - NDA) - 通过UIWebView,而且是唯一的目前支持该技术的平台是Android。

Here my problem is twofold: transform: translate works a /lot/ smoother ( translate3d even more so) than left or margin-left transitions, to a point that is really really desirable, borderline crucial — especially on Android, seeing as non-translated transitions are still stutteringly glacial on the latest phones with the latest OS. 在这里,我的问题是双重的: transform: translate工作a / lot / smoother( translate3d甚至更多)比leftmargin-left过渡,到一个非常可取的点,边缘线至关重要 - 特别是在Android上,看作非翻译在拥有最新操作系统的最新手机上,过渡仍然令人窒息。 With that in mind, the crux of the issue is that Android seems to infer the box model differently when relating to translate . 考虑到这一点,问题的关键在于Android在与translate相关时似乎推断出盒子模型的不同。 To demonstrate, here's a transform -based version of the same thing, which does the same thing as the previous fiddle, and works on all browsers that support translate3d… 为了演示,这里是一个基于transform的同一个版本,与前一个小提琴做同样的事情,适用于支持translate3d的所有浏览器......

(w/ translate) (带翻译)

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

If you examine this on iPhone (again, by appending /show ), you'll notice improved frame rate on iPhones. 如果你在iPhone上检查这个(再次,通过追加/show ),你会注意到iPhone上的帧速率提高了。 The same goes for Firefox running on Android, and arguably on Chrome and the default browser on Android too, except that here, the translateX offset of -100% somehow refers to the space occupied by all three tabs, so the wrapper slides just enough such that none of the tabs are visible. 对于在Android上运行的Firefox也是如此,可以说在Chrome和Android上的默认浏览器上也是如此,除了这里,-100%的translateX偏移量以某种方式指向所有三个选项卡占用的空间,因此包装器滑动就足够了没有任何标签可见。 This is odd, since transform percentages are specified as relating to the full box model of the element being transformed — and computed style unambiguously describes the wrapper width as being the same as its parent (not, as the result implies, stretched 3-fold to accomodate the tabs). 这很奇怪,因为变换百分比被指定为与正在变换的元素的完整框模型有关 - 并且计算出的样式明确地将包装宽度描述为与其父元素相同(不是,结果意味着,拉伸3倍到容纳标签)。

Can we describe this as a bug? 我们可以将其描述为一个错误吗?

As far as I can tell, there's no pure-CSS (I'm not averse to media query feature detection, CSS vendor forking or property hacking) method of infering and resolving this problem. 据我所知,没有纯CSS(我不反对媒体查询功能检测,CSS供应商分叉或财产黑客)推断和解决这个问题的方法。 In fact the only way of making this same CSS mechanic work that I can think of now is sniffing the UA string for Android and applying different rules conditionally. 事实上,我现在能够想到的唯一一种制作相同的CSS机制工作的方法是嗅探Android的UA字符串并有条件地应用不同的规则。 Yuk! 育! If I'm to make an Android-WebKit-only solution, and break functionality everywhere else, I can take the de facto behaviour in to account and make the percentages refer to fractions: 如果我要制作一个Android-WebKit专用解决方案,并在其他地方打破功能,我可以将事实上的行为记入帐户并使百分比引用分数:

(w/ translate — for Android update: unnecessary and breaks on Android 4.4 KitKat ) (带翻译 - 适用于Android 更新:Android 4.4 KitKat上的不必要和中断

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

Not ideal, as this makes the UI browser-specific and requires that we know up front the number of tabs in a group before writing our CSS. 不理想,因为这会使UI浏览器特定,并且要求我们在编写CSS之前预先知道组中的选项卡数量。 But this doesn't even completely solve the problem there, as, on orientation change (and this is really weird), the offset switches to the specification-correct behaviour displayed by other browsers! 但这甚至没有完全解决那里的问题,因为在方向改变时(这真的很奇怪),偏移切换到其他浏览器显示的规范正确行为!

I've also tried applying the translation to the actual tabs, which again works everywhere else, but despite correctly picking up and applying the rules, Android's browser won't render the effect. 我也尝试将翻译应用到实际的标签中,这些标签在其他任何地方都可以使用,但是尽管正确选择并应用规则,Android的浏览器也不会产生效果。 Stranger and strangerer: 陌生人和陌生人:

(w/ translate, working on Android's theory, not working on Android at all) (翻译,使用Android的理论,根本不在Android上工作)

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

Any insights or ideas for a cross-browser solution much appreciated. 深入了解跨浏览器解决方案的任何见解或想法。

I am using Android 2.3 and can't produce the exact problem you describe (with regards to your comment "-100% somehow refers to the space occupied by all three tabs" ). 我使用Android 2.3并且无法产生您描述的确切问题(关于您的评论“-100%以某种方式指的是所有三个标签占用的空间” )。 However, I was experiencing other issues resulting in intermittent/jumpy transitions and some other weirdness I didn't really investigate. 但是,我遇到了导致间歇性/跳跃性过渡的其他问题以及其他一些我没有真正研究的奇怪之处。

For the sake of conversation, lets assume that the "wrapper" is 500px wide. 为了对话,我们假设“包装器”宽度为500px。

By using your inline-block/nowrap technique (which is a very under-appreciated layout technique from YUI), your 3 tab panels are taking up 1500px of horizontal space. 通过使用你的内联块/ nowrap技术(这是YUI非常不受欢迎的布局技术),你的3个选项卡面板占用了1500px的水平空间。 Based on what you describe, you need to spoof the browser into thinking all of tab panels together are taking up 500px of horizontal space. 根据您的描述,您需要欺骗浏览器,使所有选项卡面板占据500px的水平空间。 Checkout my fiddle, which essentially uses some negative margins and translates to trick the browser in a way I think should work, but I can't test it. 检查我的小提琴,它基本上使用一些负边距并转换为以我认为应该工作的方式欺骗​​浏览器,但我无法测试它。 Either way, my example fixed the weirdness I was experiencing on my Android 2.3 - so you may want to use it either way. 无论哪种方式,我的例子修复了我在Android 2.3上遇到的怪异 - 所以你可能想要以任何一种方式使用它。

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

(and the relevant CSS) (和相关的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);
}

Note: I tried using relative positioning instead of the transforms above, and I was still getting the same weirdness I described above. 注意:我尝试使用相对定位而不是上面的变换,我仍然得到了我上面描述的相同的怪异。

I was experiencing a similar issue. 我遇到了类似的问题。

For me the problem was: 对我来说问题是:

* {
    box-sizing: border-box;
}

I had border-box applied to all elements. 我将边框应用于所有元素。 Once I removed this, the percentage translate3d was applied correctly. 删除后,翻译了translate3d百分比。

If CSS is not working (and should be working), you need an workaround. 如果CSS不起作用(并且应该正常工作),则需要一种解决方法。 Please check my modified version: 请检查我的修改版本:

http://jsfiddle.net/EG9v8/1/ 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));
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM