28 votes

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

tl;dr? Obtenez le mécanisme démontré dans le lien ci-dessous pour se comporter avec l'accélération GPU sur Android, de Chrome et le navigateur par défaut.

Mise à JOUR 2 (2014-01-13 13:25:30Z): Selon le bref.ils'commentaire ci-dessous, le comportement est fixé comme de Android 4.4 KitKat - mais le correctif que j'ai décrit ci-dessous maintenant, il tombe! Gazon de la loi.

Mise à JOUR 1 (2012-11-01 17:54:09Z): Le buggy comportement est inferrable à partir de la matrice de transformation tel que rapporté par le calcul de style de la transformation de l'élément, qui retourne une valeur de pixel. Je vais essayer d'écrire un Modernizr tester cette option pour ouvrir la voie à d'éventuelles solutions.

J'ai développé un mécanisme pour glisser un conteneur pour révéler toute la largeur, disposés horizontalement sous-sections. Coulissante onglets, dans le fond. Car il y a beaucoup de rendement intensif de trucs et d'élaborer Javascript passe, je veux garder JS au minimum et en faire autant de l'aspect purement stylistique dans le CSS. Je pense que j'ai fait assez bien, compte tenu de - JS juste la modification d'un attribut sur l'emballage:

(w/ gauche)

http://jsfiddle.net/barney/VPJuq/ (les appareils mobiles peuvent ajouter /afficher/ de ces tripoter Url pour voir les résultats par eux-mêmes)

Un mot sur la façon dont cela fonctionne: traiter les onglets inline-blocks me permet de spécifier white-space: nowrap (le reste du code dans les deux dernières règles sont essentiellement réduit l'espace entre les onglets) et de leur permettre d'empiler horizontalement sans effacer / retour, le tout dans le maintien de la totalité de la largeur de son parent. À partir de là, la fixation d'un négatif à gauche décalage à l'emballage fait la magie. Cool, hein?

Maintenant, un peu de contexte: l'interface, je suis en développement à exécuter dans des applications mobiles natives - l'application de base de fonctionnalité s'appuie sur la pointe mobile-technologie spécifique (ne me demandez pas - NDA) - via une UIWebView, et la seule plate-forme qui prend actuellement en charge la technologie en question est Android.

Voici mon problème est double: transform: translate fonctionne un /beaucoup/ plus lisse (translate3d même plus) que left ou margin-left transitions, à un point qui est vraiment souhaitable, à la limite un élément crucial, en particulier sur Android, en le voyant comme non-traduits, les transitions sont toujours stutteringly glaciaire sur les derniers téléphones avec le dernier système d'exploitation. Avec cela à l'esprit, le cœur du problème, c'est que Android semble déduire le modèle de boîte différemment lorsque relatives à l' translate. Pour le démontrer, voici un transform-version de la même chose, qui fait la même chose que la précédente violon, et fonctionne sur tous les navigateurs qui prennent en charge translate3d...

(w/ translate)

http://jsfiddle.net/barney/EJ7ve

Si vous examinez ce sur iPhone (encore une fois, en ajoutant /show), vous remarquerez une amélioration de la cadence sur les iPhones. Il en va de même pour Firefox fonctionnant sur Android, et sans doute sur le Chrome et le navigateur par défaut sur Android aussi, sauf qu'ici, l' translateX décalage de -100% en quelque sorte se réfère à l'espace occupé par chacun des trois onglets, de sorte que le wrapper de diapositives juste assez pour qu'aucun des onglets sont visibles. C'est étrange, depuis transformer les pourcentages sont spécifiés comme concernant le plein de modèle de boîte de l'élément en cours de transformation et calculée style sans ambiguïté décrit le wrapper width comme étant la même que celle de son parent (non pas, comme le résultat implique, tendu 3 fois pour accueillir les onglets).

Pouvons-nous décrire cela comme un bug?

Aussi loin que je peux dire, il n'y a pas de pure CSS (je ne suis pas opposé à la requête de support de la fonctionnalité de détection, CSS fournisseur de bifurquer ou bien le piratage) méthode d'inférer et de la résolution de ce problème. En fait, la seule façon de faire ce même CSS mécanicien de travail que je peux penser maintenant est reniflant la chaîne de l'agent utilisateur pour Android et l'application de règles différentes de façon conditionnelle. Beurk! Si je suis à faire un Android-WebKit-seule solution, et de briser la fonctionnalité partout ailleurs, je peux le prendre, de facto, le comportement en compte et de faire les pourcentages se réfèrent à des fractions:

(w/ translate pour Android mise à jour: inutile et casse sur Android 4.4 KitKat)

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

Pas l'idéal, car cela rend l'INTERFACE utilisateur du navigateur et nécessite que nous savons jusqu'devant le nombre d'onglets dans un groupe avant d'écrire le code CSS. Mais ce n'est pas à même de résoudre complètement le problème, là, que, sur le changement d'orientation (et c'est vraiment bizarre), le décalage des commutateurs à la spécification correcte du comportement affiché par les autres navigateurs!

J'ai aussi essayé l'application de la traduction dans le réel onglets, ce qui fonctionne partout ailleurs, mais malgré correctement la cueillette et de l'application des règles, Android du navigateur n'est pas le rendu de l'effet. Étranger et strangerer:

(w/ traduire, de travail sur Android théorie, ne fonctionne pas sur Android en tout)

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

Des idées ou des idées pour un cross-browser solution beaucoup apprécié.

3voto

Ryan Wheale Points 4685

Je suis en utilisant Android 2.3 et ne peut pas produire exactement le problème que vous décrivez (en ce qui concerne votre commentaire "-100% en quelque sorte se réfère à l'espace occupé par chacun des trois onglets"). Cependant, j'ai été confrontés à d'autres problèmes résultant d'intermittent/jumpy transitions et quelques autres bizarreries je n'ai pas vraiment étudier.

Pour l'intérêt de la conversation, permet de supposer que le "wrapper" est 500px de large.

À l'aide de votre inline-block/nowrap technique (qui est un très sous-estimé technique de disposition de YUI), votre 3 panneaux à onglets prennent 1500px de l'espace horizontal. D'après ce que vous décrivez, vous avez besoin d'usurper le navigateur en pensant à tous de panneaux à onglets sont, ensemble, prise de 500px de l'espace horizontal. La caisse de mon violon, qui utilise essentiellement quelques des marges négatives et se traduit par astuce le navigateur de façon à ce que je pense devrait fonctionner, mais je ne peux pas le tester. De toute façon, mon exemple fixe l'étrangeté, j'ai fait l'expérience sur mon Android 2.3 - de sorte que vous pouvez l'utiliser de toute façon.

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

(et le 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: j'ai essayé d'utiliser le positionnement relatif au lieu de les transformations ci-dessus, et j'ai été toujours obtenir le même sentiment bizarre que je l'ai décrit ci-dessus.

2voto

Ian Jamieson Points 1078

Je rencontrais un problème similaire.

Pour moi, le problème était:

 * {
    box-sizing: border-box;
}
 

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

0voto

Ivan Seidel Points 615

Si CSS ne fonctionne pas (et devrait fonctionner), vous avez besoin d'une solution de contournement. Veuillez vérifier 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));
});
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X