スマートフォン対応でよく使うhtml、css、javascriptのまとめ

スマートフォン(ios、android)向けのウェブサイト・ウェブアプリを作る際に個人的によく使うhtml、css、javascriptの備忘録。

html関連


headタグ内での設定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- //デバイスサイズにあわせて表示領域を変更する -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<!-- //電話番号のリンクを無効化 -->
<meta name="format-detection" content="telephone=no">

<!-- //ホーム画面用アイコン -->
<link rel="apple-touch-icon" href="icon.png">

<!-- //ホーム画面用アイコンの光沢を無効化する -->
<link rel="apple-touch-icon-precomposed" href="icon.png">

<!-- //iPadホーム画面用アイコン -->
<link rel="apple-touch-icon" sizes="72x72" href="touch-icon-ipad.png">

<!-- //iPhone4ホーム画面用アイコン -->
<link rel="apple-touch-icon" sizes="114x114" href="touch-icon-iphone4.png">

<!-- //splash画像の設定 -->
<link rel="apple-touch-startup-image" href="startup.png">

<!-- //homeボタンから起動時にfull screen modeで起動 -->
<meta name="apple-mobile-web-app-capable" content="yes">

<!-- //full screen mode起動時のステータスバーの色の変更 -->
<meta name="apple-mobile-web-app-status-bar-style" content="black">

viewportについて

  • width:ビューポート(可視領域)の幅(初期値980px)
  • initial-scale:倍率の初期値、minimum-scale:倍率の最小値、maximum-scale:倍率の最大値
  • user-scalable:拡大縮小の可否
  • コンテンツより小さいviewport widthやheightを設定しても設定値は適用されない
    例えば、device-width=320pxでinitial-scale=0.5の場合は、表示領域 320px/0.5px = 640pxで算出、
    device-width=320px、width=400px、コンテンツ450pxであれば、initial-scale = 320/450で横幅450pxのドキュメントを描写される。

Tel URI、Sms URIの設定

1
2
3
4
5
6
7
8
9
10
11
<!-- //リンクをクリックで電話をかける -->
<a href="tel:00000000000">00000000000</a>

<!-- //リンククリックでsms -->
<a href="sms:00000000000">sms</a>

<!-- //smsの送信先複数 -->
<a href="sms:00000000000,1111111111">sms複数</a>

<!-- //smsの本文追加 -->
<a href="sms:00000000000,1111111111?body=%83e%83X%83g%83%81%83b%83Z%81%5b%83W">smsメッセージ</a>

inputタグ関連

1
<input autocorrect="off" autocomplete="off" autocapitalize="off">
  • autocorrect:スペルチェック機能
  • autocomplete:自動補完
  • autocapitalize:先頭文字を大文字にする
1
<input type="number" value="001">
  • iOS5以上の場合、inputのnumber属性値の場合、「001」は「1」の数値形式に変換される。
  • 同様に「1000」は「1,000」の数値形式に変換される
  • ソフトウェアキーボードを数値入力形式で表示させたいならばtel属性値を付与するかJavaScriptで回避
    pattern属性を使って正規表現で回避するのがいいのではないかと思ってる。
1
2
<input type="text" pattern="[0-9]*"/>
<input type="text" pattern="\d*"/>

css関連


position:fixed関連

position:fixed はiOS5、Android2.2以降が対応。
ただし

  • Androidではviewportにuser-scalable=noの指定がないとposition:fixedが動かない
  • iOS5ではURLに#がついた状態だと挙動が不安定
  • iOS5で他ページに遷移した後に、戻るボタンでページにもどると表示位置がずれる
  • Androidではuser-scalable=noとposition: fixedを使用すると、-webkit-transformが動かなくなる

ちなみに、iOSがposition:fixをサポートしているかの判定は、Modernizr position fixed checkのコードから

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var isSupported;

if ( typeof document.body.scrollIntoViewIfNeeded === 'function') {

(function () {
var container = document.body,
elem = document.createElement('div'),
orgHeight = container.style.height,
orgScrollTop = window.pageYOffset,
testScrollTop = 20;

elem.style.cssText = 'position:fixed;top:0px;height:10px;';

container.appendChild(elem);
container.style.height = '2048px';

window.setTimeout(function() {
elem.scrollIntoViewIfNeeded();
isSupported = !(window.pageYOffset === testScrollTop) || !(window.pageYOffset === testScrollTop+1);
alert(isSupported);
container.removeChild(elem);
container.style.height = orgHeight;

window.scrollTo(0, orgScrollTop);
}, 1000);

window.scrollTo(0, testScrollTop);
}());

}

return isSupported;

という感じで判定できそうです。


overflow:scroll関連

overflow:scrollはiOSは2本指スクロール(わかりにくい)、Androidはoverflow:hiddenとして扱われます。iOS5の場合は、

1
-webkit-overflow-scrolling: touch;

で1本指スクロールが可能です。Androidの場合は現状、JavaScriptなどで回避するか別のアプローチが必要の様子。
overflow-scrollingは将来的にAndroidでもサポートされるかもしれないので、個人的には、

1
2
3
4
5
6
7
if("overflowScrolling" in document.body.style || "webkitOverflowScrolling" in document.body.style || "MozOverflowScrolling" in document.body.style) {
//対応しているときの処理
}
else {
//対応してないときの処理
}
;

という感じで分岐したりしてます。


Media Queries

デバイスの向きによって、スタイルを変更する場合、インラインなら

1
2
3
4
5
6
7
8
9
10
11
12
13
/*縦向き*/
@media all and (orientation: portrait) {
body {
/* your styles */
}
}

/*横向き*/
@media all and (orientation: landscape) {
body {
/* your setting here */
}
}

読込むcssファイルを変更する場合は

1
2
3
4
5
/*縦向き*/
<link rel="stylesheet" media="all and (orientation: portrait)" href="portrait.css">

/*横向き*/
<link rel="stylesheet" media="all and (orientation: landscape)" href="landscape.css">

デバイスの画面サイズや解像度によってもスタイルを変更できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/* 画面サイズ〜480pxの端末のときに */ 
@media only screen and (max-width: 481px) {
/* CSS goes here */
}

/* 画面サイズ481px〜1024pxの端末が縦(portrait)のときに */
@media only screen and (max-width: 480px) and (max-device-width: 1024px) and (orientation:portrait) {
/* CSS goes here */
}

/* 画面サイズ481px〜1024pxの端末が横(landscape)のときに */
@media only screen and (max-width: 480px) and (max-device-width: 1024px) and (orientation:landscape) {
/* CSS goes here */
}

/* 画面サイズ1025〜の端末が横(landscape)のときに */
@media only screen and (max-width: 480px) and (max-device-width: 1024px) and (orientation:landscape) {
/* CSS goes here */
}

width: 1025px〜の端末のときに */
@media only screen and (max-width: 1025px) {
/* CSS goes here */
}

/* iphone4 iphone4s */
@media (-webkit-min-device-pixel-ratio: 2),
(min--moz-device-pixel-ratio: 2),
(min-resolution: 300dpi) {
body{ your styles here }
}

/* andoroid */
@media (-webkit-max-device-pixel-ratio: 1.5),
(max--moz-device-pixel-ratio: 1.5),
(max-resolution: 299dpi) {
body{ your styles here }
}

そのほかの設定

そのほか、細かい設定などなど。

1
2
3
4
5
6
7
8
/* タップ時のハイライトカラー*/
-webkit-tap-highlight-color:#f00;

/*テキストの選択をキャンセルする場合*/
-webkit-user-select:none;

/*リンクの長時間タップでリンク内容をポップアップで表示させない場合*/
-webkit-touch-callout: none;

などが主なものになります。

JavaScript関連


URLバーを隠す

ウェブページを表示した際にURLバーを隠すことができます。(厳密には1pxだけwindowをスクロールさせる)

1
2
3
4
5
6
7
//1000ミリ秒の遅延を設定しているのはページの読込が完了するまでの十分な時間として設定してます。
setTimeout(function(){ window.scrollTo(0,1);},1000);

//jQueryなどだとページ読込み完了時に呼んでやるのもありです。
$(function(){
window.scrollTo(0,1);
});

メディアクエリ・解像度関連

cssのメディアクエリのjavascript版のような感じで、window.matchMediaを使うとデバイス画面サイズごとに処理を分岐できます。

1
2
3
4
5
6
7
if ( window.matchMedia("only screen and (max-width: 480px")).matches ) {
// For Mobile
} else if (window.matchMedia("only screen and (min-width: 481px) and (max-width: 1024px)").matches ) {
// For Tablet
} else {
// For PC
}

同じように、デバイスの解像度も取得できます。

1
2
3
4
5
6
7
8
9
10
11
12
if( window.devicePixelRatio == 2 )
{
//iphone4,iphone4s
}
else if( window.devicePixelRatio == 1.5 )
{
//Android
}
else
{
//others
}

また、フルスクリーンモードで起動しているかも検出できます。

1
2
3
4
if(!window.navigator.standalone)
{
//your method
}

通信状態の取得

Android2.2以降からは接続状態も検出できます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
Browser Object Model

navigator = {
connection: {
"type": "4",
"UNKNOWN": "0",
"ETHERNET": "1",
"WIFI": "2",
"CELL_2G": "3",
"CELL_3G": "4"
}
};
*/

switch (navigator.connection.type ) {
case 0:
//unknown
case 1:
//ETHERNET
break;

case 2:
//WIFI
break;

case 3:
//CELL_2G
break;

case 4:
//CELL_3G
break;
}

オンラインかどうかの検出もできて、以下のようになります。

1
2
3
4
5
6
7
8
if (window.navigator.onLine) 
{
//online
}
else
{
//offline
}

touchイベント関連

touch、gestureイベントは次のようになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//スクリーンにタッチ
document.addEventListener("touchstart", touchHandler, false);

//タッチ後、指を動かす
document.addEventListener("touchmove", touchHandler, false);

//タッチ後、指を離す
document.addEventListener("touchend", touchHandler, false);

//タッチ後、指をスライドさせた(タッチをキャンセルした)
document.addEventListener("touchcancel", touchHandler, false);

//2本以上の指を使ってスクリーンにタッチ
document.addEventListener("gesturestart", gestureHandler, false);

//指が動く
document.addEventListener("gesturechange", gestureHandler, false);

//どちらかの指がスクリーンから離れる
//ちなみにこの後、残りの指を離すとtouchendが発生
document.addEventListener("gestureend", gestureHandler, false);

デバイスの向き関連

デバイスの向きも検出できます。

1
2
3
4
5
6
7
8
9
10
11
12
//90度ごとに向きが変更された場合に発生
window.addEventListener("orientationchange ", orientationEvent, true);

//細かい回転量の取得
//返される値は
//alpha:0~360(degrees)
//beta:-180~180(degrees)
//gamma:-90~90(degrees)
window.addEventListener("deviceorientation", orientationEvent, true);

//デバイスの加速度と回転データを取得
window.addEventListener('devicemotion', deviceMotionHandler, false);

このあたりはhtml5rocksが詳しくです。


Media capture API

Andoroidはhtmlからユーザーがアップロードできるコンテンツを細かく制御できます。

1
2
3
4
5
6
7
8
9
10
11
<!-- regular file upload (Android 2.2+) -->
<input type="file"></input>

<!-- opens directly to the camera (Android 3.0+) -->
<input type="file" accept="image/*;capture=camera"></input>

<!-- opens directly to the camera in video mode (Android 3.0+) -->
<input type="file" accept="video/*;capture=camcorder"></input>

<!-- opens directly to the audio recorder (Android 3.0+) -->
<input type="file" accept="audio/*;capture=microphone"></input>
Comments