UI 設計におけるスマートフォン対応のまとめ

【KLab× ミクシィ・リクルートメント】 ∼ HTML5 によるソーシャルゲームの新世界@福岡∼
スマートフォンにおけるバグおよび問題まとめ


・共通                 ・Android                   ・iOS
 - イベントバブリング対応      - CSS アニメーションが遅い           - position:fixed のバグ
 - 端末画面サイズへの対応      - text-shadow バグ
 - Flash の問題        - CSS3 アニメーション+box-shadow 問題
 - jQuery アニメーション   - scroll ができない
  のメモリリーク           - z-index が効かなくなる
                    - 下層レイヤーが反応する
                    - フォントが無い
                    - font-weight:bold が使えない
                    - フォーカスがずれる件
                    - translate3d によるバグ
                    - touchend イベントが発生しない
                    - select や input[type=text] フォーカス時の挙動
                    - mask-image+アニメーション問題
                    - ...
                    - 端末依存のバグ
スマートフォンにおけるバグおよび問題まとめ




      ソースコードを一元管理するには
    Android の設計を先に考える必要がある
対応方法を簡単に共有

・position:fixed への対応
  現象

 スクロールするとついてくる。

                        対策

                      スクロールしない様に、
                      コンテンツの高さを 100% に抑える様に
                      CSS でチューニング。
                      もしくは、JS でスクロールをハンドリング。


                        環境

                      iOS5 以下 , Android2.2 以下
対応方法を簡単に共有

・z-index が効かなくなる。
   現象

 position:absolute の要素が
 z-index を無視して上にくる。
                            対策

                          オーバーレイ表示している HTML 要素に対して、
                          -webkit-transform:translate3d(0,0,0)
                          を指定する。



                            環境

                          Android 4.*
対応方法を簡単に共有

・端末画面サイズへの対応
  現象

 画面サイズが機種ごとに違う

                         対策

                 zoom プロパティで画面サイズ / 基本サイズで拡大。
                 更に高さを適応する。
                 var ratio = jQuery(window).width()/640;
                 jQuery( html ).css({
                       zoom : ratio,
                       height :window.innerHeight+ px
                 });


                         環境

                 Android, iPhone5
対応方法を簡単に共有

・下層レイヤーが反応する
  現象                          対策

 オーバーレイ表示等、上に要素を重ねると    オーバーレイした際に下層レイヤーの
 下にクリッカブルな要素があると反応する。   クリッカブル要素に visiblity:hidden に設定。
                        $('a,select,input').filter(function(i){
                          // 指定した親要素内は除外
                          if($(this).parents(ParrentNodeDom).length!=0) return false;
                          return true;
                        }).css({
                          'display': none ,
                          'visibility': hidden ,
                          '-webkit-tap-highlight-color': rgba(0,0,0,0) ,
                          '-webkit-touch-callout': none
                        }).bind('touchstart.Canceler',function(e){
                          e.preventDefault();
                        });

                              環境

                        Android 2.3
対応方法を簡単に共有

・スクロールができない
   現象                      対策

 overflow:auto が効かないので、   flickable や flicksimple などを使い
 スクロールができません。            フリック要素を形成する必要がある。
                         中にイメージがある場合には、
                         イメージをプリロードしてから実装する必要がある。
                         オーバーレイの中では、非表示だと高さがとれないので、
                         表示されてから再設定する。


                           環境

                         Android2.3
対応方法を簡単に共有

・イベント感染問題
  現象                             対策

 オーバーレイ表示時等にタップイベントが   オーバレイ非表示時にはオーバーレイのリンク要素に
 上層レイヤーにまで渡ってしまう。      e.preventDefault(); e.stopPropagation();
                       を設定。表示する関数のコールバックで解除する。

                       if(arguments[0]){
                           $('*',arguments[1]).bind('click.pre',function(e){
                             event.stopPropagation();
                             event.preventDefault();
                             if(window.event) window.event.cancelBubble = true;
                           }).bind('touchend.pre',function(e){
                             event.stopPropagation();
                             event.preventDefault();
                             if(window.event) window.event.cancelBubble = true;
                           });
                       }else{
                           $('*',arguments[1]).unbind('click.pre').unbind('touchend.pre');
                       }
感想



・Android への対応がかなり工数を取られる


・スマートフォン対応は Android から対応策を検討すべき

UI設計におけるスマートフォン対応のまとめ

  • 1.
  • 2.
    スマートフォンにおけるバグおよび問題まとめ ・共通 ・Android ・iOS - イベントバブリング対応 - CSS アニメーションが遅い - position:fixed のバグ - 端末画面サイズへの対応 - text-shadow バグ - Flash の問題 - CSS3 アニメーション+box-shadow 問題 - jQuery アニメーション - scroll ができない のメモリリーク - z-index が効かなくなる - 下層レイヤーが反応する - フォントが無い - font-weight:bold が使えない - フォーカスがずれる件 - translate3d によるバグ - touchend イベントが発生しない - select や input[type=text] フォーカス時の挙動 - mask-image+アニメーション問題 - ... - 端末依存のバグ
  • 3.
    スマートフォンにおけるバグおよび問題まとめ ソースコードを一元管理するには Android の設計を先に考える必要がある
  • 4.
    対応方法を簡単に共有 ・position:fixed への対応 現象 スクロールするとついてくる。 対策 スクロールしない様に、 コンテンツの高さを 100% に抑える様に CSS でチューニング。 もしくは、JS でスクロールをハンドリング。 環境 iOS5 以下 , Android2.2 以下
  • 5.
    対応方法を簡単に共有 ・z-index が効かなくなる。 現象 position:absolute の要素が z-index を無視して上にくる。 対策 オーバーレイ表示している HTML 要素に対して、 -webkit-transform:translate3d(0,0,0) を指定する。 環境 Android 4.*
  • 6.
    対応方法を簡単に共有 ・端末画面サイズへの対応 現象 画面サイズが機種ごとに違う 対策 zoom プロパティで画面サイズ / 基本サイズで拡大。 更に高さを適応する。 var ratio = jQuery(window).width()/640; jQuery( html ).css({ zoom : ratio, height :window.innerHeight+ px }); 環境 Android, iPhone5
  • 7.
    対応方法を簡単に共有 ・下層レイヤーが反応する 現象 対策 オーバーレイ表示等、上に要素を重ねると オーバーレイした際に下層レイヤーの 下にクリッカブルな要素があると反応する。 クリッカブル要素に visiblity:hidden に設定。 $('a,select,input').filter(function(i){ // 指定した親要素内は除外 if($(this).parents(ParrentNodeDom).length!=0) return false; return true; }).css({ 'display': none , 'visibility': hidden , '-webkit-tap-highlight-color': rgba(0,0,0,0) , '-webkit-touch-callout': none }).bind('touchstart.Canceler',function(e){ e.preventDefault(); }); 環境 Android 2.3
  • 8.
    対応方法を簡単に共有 ・スクロールができない 現象 対策 overflow:auto が効かないので、 flickable や flicksimple などを使い スクロールができません。 フリック要素を形成する必要がある。 中にイメージがある場合には、 イメージをプリロードしてから実装する必要がある。 オーバーレイの中では、非表示だと高さがとれないので、 表示されてから再設定する。 環境 Android2.3
  • 9.
    対応方法を簡単に共有 ・イベント感染問題 現象 対策 オーバーレイ表示時等にタップイベントが オーバレイ非表示時にはオーバーレイのリンク要素に 上層レイヤーにまで渡ってしまう。 e.preventDefault(); e.stopPropagation(); を設定。表示する関数のコールバックで解除する。 if(arguments[0]){ $('*',arguments[1]).bind('click.pre',function(e){ event.stopPropagation(); event.preventDefault(); if(window.event) window.event.cancelBubble = true; }).bind('touchend.pre',function(e){ event.stopPropagation(); event.preventDefault(); if(window.event) window.event.cancelBubble = true; }); }else{ $('*',arguments[1]).unbind('click.pre').unbind('touchend.pre'); }
  • 10.