Forcer l'interprétation correcte du pourcentage de transformation CSS3 sur Android

Td dr Obtenez le mécanisme démontré dans le lien ci-dessous pour vous entraîner avec l'accélération du GPU sur Android Chrome et le navigateur par défaut.

MISE À JOUR 2 (2014-01-13 13: 25: 30Z): Selon le commentaire de bref.it ci-dessous, le comportement rapporté est corrigé à partir de l'Android 4.4 KitKat – mais la correction que j'ai décrite ci-dessous le casse maintenant! La loi de Sod.

MISE À JOUR 1 (2012-11-01 17: 54: 09Z): Le comportement de buggy est inferrable de la matrice de transformation comme indiqué par le style calculé de l'élément transformé, qui renvoie une valeur de pixel. Je vais essayer d'écrire un test Modernizr pour que cela ouvre la voie à toutes les solutions possibles.

J'ai développé un mécanisme pour glisser un conteneur pour révéler des sous-sections à largeur et horizontalement. Pattes coulissantes, fondamentalement. Parce qu'il y a beaucoup de choses intensives en matière de performance et de Javascript élaboré, je veux garder JS au minimum et faire autant de purement stylistique dans CSS. Je pense que j'ai fait très bien en considérant – JS modifie simplement un attribut sur l'emballage:

(W / left)

Http://jsfiddle.net/barney/VPJuq/ (les périphériques mobiles peuvent ajouter / afficher / à ces URL de violon pour voir les résultats par eux-mêmes)

Un mot sur la façon dont cela fonctionne: le traitement des onglets en tant que inline-block en inline-block s me permet de spécifier l' white-space: nowrap (le reste du code dans les deux dernières règles white-space: nowrap essentiellement les espaces entre les onglets) et leur permet de s'empiler horizontalement Sans compensation / retour, tout en conservant la largeur totale de leur parent. De là, le réglage d'un décalage gauche négatif sur l'enveloppe fait la magie. Cool hein?

Maintenant, un peu de contexte: l'interface que je développe doit être exécutée dans des applications mobiles natives: la fonctionnalité de base de l'application repose sur une technologie de pointe (ne demande pas – NDA) – via UIWebView et le seul La plate-forme qui prend actuellement en charge la technologie en question est Android.

Ici, mon problème est double: transform: translate works a / lot / smoother ( translate3d encore plus) que les transitions left ou margin-left , à un point vraiment souhaitable, borderline crucial – surtout sur Android, vu que non traduit Les transitions sont toujours glutins sur les derniers téléphones avec le dernier système d'exploitation. Dans cet esprit, l'essentiel du problème est que l'Android semble inférer le modèle de boîte différemment lorsqu'il s'agit de translate . Pour démontrer, voici une version basée sur la transform de la même chose, qui fait la même chose que le violon précédent, et fonctionne sur tous les navigateurs qui supportent translate3d …

(W / translate)

Http://jsfiddle.net/barney/EJ7ve

Si vous examinez cela sur iPhone (encore une fois, en ajoutant /show ), vous remarquerez une meilleure fréquence d'images sur les iPhones. Il en va de même pour Firefox s'exécuter sur Android, et sans doute sur Chrome et le navigateur par défaut sur Android aussi, sauf que ici, le décalage translateX de -100% se réfère en quelque sorte à l'espace occupé par les trois onglets, de sorte que l'emballage glisse juste assez Qu'aucun des onglets n'est visible. Ceci est étrange, puisque les pourcentages de transformation sont spécifiés en relation avec le modèle de l'ensemble de l'élément en cours de transformation, et le style calculé décrit sans ambiguïté la largeur de l'enveloppe comme étant la même que celle de son parent (non pas, comme le résultat l'indique, étiré 3 fois jusqu'à Accueille les onglets).

Peut-on décrire cela comme un bogue?

Pour autant que je puisse le dire, il n'y a pas de CSS pur (je ne préjuge pas de la détection des fonctionnalités de la requête médiatique, du fourrage du fournisseur CSS ou du piratage de propriété) pour déduire et résoudre ce problème. En fait, la seule façon de faire fonctionner ce même travail mécanique CSS que je peux penser maintenant est de renifler la chaîne UA pour Android et d'appliquer des règles différentes conditionnellement. Yuk! Si je dois faire une solution Android-WebKit-only, et briser la fonctionnalité partout ailleurs, je peux prendre en compte le comportement de facto et faire en sorte que les pourcentages se réfèrent aux fractions:

(W / translate – pour la mise à jour d' Android : inutile et casse sur Android 4.4 KitKat )

Http://jsfiddle.net/barney/nFt5t/

Pas idéal, car cela rend l'UI spécifique au navigateur et exige que nous connaissions le nombre d'onglets dans un groupe avant d'écrire notre CSS. Mais cela ne résout pas complètement le problème là-bas, car, lors du changement d'orientation (et c'est vraiment étrange), le décalage change en fonction du comportement de la spécification-correctif affiché par d'autres navigateurs!

J'ai également essayé d'appliquer la traduction aux onglets actuels, qui fonctionnent à nouveau partout ailleurs, mais malgré la reprise et l'application des règles, le navigateur Android ne rend pas l'effet. Plus étrange et plus étrange:

(W / traduire, travailler sur la théorie d'Android, ne fonctionne pas sur Android)

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

Des idées ou des idées pour une solution cross-browser ont été très appréciées.

J'utilise Android 2.3 et je ne peux pas produire le problème exact que vous décrivez (en ce qui concerne votre commentaire "-100% signifie en quelque sorte l'espace occupé par les trois onglets" ). Cependant, j'éprouvais d'autres problèmes, ce qui a entraîné des transitions intermittentes / nerveuses et une autre étrange chose que je n'ai pas vraiment enquêté.

Pour des raisons de conversation, supposons que le "wrapper" a une largeur de 500px.

En utilisant votre technique inline-block / nowrap (qui est une technique de mise en page très peu appréciée de YUI), vos 3 panneaux de tabulation prennent 1500px d'espace horizontal. Sur la base de ce que vous décrivez, vous devez falsifier le navigateur afin de penser que tous les panneaux d'onglets contiennent 500px d'espace horizontal. Checkout my fiddle, qui utilise essentiellement des marges négatives et traduit pour tromper le navigateur d'une manière que je pense devrait fonctionner, mais je ne peux pas le tester. Quoi qu'il en soit, mon exemple a résolu l'étrange émotion que j'avais sur mon Android 2.3, alors vous voudrez peut-être l'utiliser de toute façon.

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

(Et le CSS pertinent)

 .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); } 

Remarque: J'ai essayé d'utiliser un positionnement relatif au lieu des transformées ci-dessus, et j'avais toujours la même étrange chose que j'ai décrite ci-dessus.

J'avais un problème similaire.

Pour moi, le problème était:

 * { box-sizing: border-box; } 

J'avais une bordure appliquée à tous les éléments. Une fois que j'ai supprimé ceci, le pourcentage translate3d a été correctement appliqué.

Si CSS ne fonctionne pas (et devrait fonctionner), vous avez besoin d'une solution de contournement. Vérifiez ma version modifiée:

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)); });