はじめに
Google Apps ScriptでWebアプリを作ると、PCでは問題なく見えても、スマートフォンでは画面の左右に余白が出たり、iPhoneの回転後に文字サイズが変わったりすることがあります。
特にGASのWebアプリはiframe内で表示されるため、通常のHTMLページよりも余白の出方を意識しておく必要があります。
この記事では、GAS Webアプリの最初のHTMLとして使える、スマホ向けの余白リセット込みテンプレートを紹介します。
最重要:viewportはdoGetのaddMetaTagで設定する
先に結論を書きます。HTMLの<head>に<meta name="viewport">を書くだけでは、スマホの余白は消えません。
GAS Webアプリは「外側のラッパーページ」の中に、あなたのHTMLがサンドボックスiframeとして埋め込まれる二重構造になっています。HTMLの<head>に書いた<meta viewport>はiframeの内側に入るため、モバイル表示を制御する外側ページには届かず、効きません。
外側ページにviewportを効かせるには、サーバ側のdoGetでHtmlOutputに対して.addMetaTag('viewport', ...)を呼ぶ必要があります。これが無いと、CSSでhtml, body { margin: 0 }を完璧に書いても、スマホで左右に余白が出て画面幅にフィットしません。
function doGet() {
return HtmlService.createTemplateFromFile('Index')
.evaluate()
.setTitle('アプリ名')
// ★この1行が無いとスマホ余白は消えない
.addMetaTag('viewport', 'width=device-width, initial-scale=1, viewport-fit=cover');
}
createHtmlOutputFromFileを使う場合も、同じHtmlOutputに.addMetaTag(...)を呼びます。HTML側の<meta viewport>は害は無いので残しても構いませんが、実際に効いているのはaddMetaTagの方だと理解しておきましょう。
こんな場面で使えます
- GAS Webアプリをスマホで使いやすくしたい
- フォーム、一覧、カード型UIの土台を毎回作っている
- 画面左右の余白や横スクロールを減らしたい
- 外部フレームワークなしで軽い画面を作りたい
写真付き報告や入力フォームのようにスマートフォンで使う画面では、最初にこの土台を入れておくと後から調整しやすくなります。
実装コード
GASのHTMLファイルに、次の形で配置します。
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<!-- このmeta自体はiframe内なので決め手にはなりません。本命はdoGetのaddMetaTagです。 -->
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<style>
/* GAS iframe余白リセット */
html,
body {
margin: 0 !important;
padding: 0 !important;
width: 100% !important;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
-webkit-text-size-adjust: 100%;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Hiragino Sans', sans-serif;
background: #f0f2f5;
color: #333;
min-height: 100vh;
}
.container {
max-width: 640px;
margin: 0 auto;
padding: 10px;
}
@media (max-width: 480px) {
.container {
padding: 6px;
}
}
</style>
</head>
<body>
<div class="container">
<!-- ここにコンテンツ -->
</div>
<script>
// 親要素の余白除去(補助)。サイドバー表示など同一オリジン時に有効。
// 標準のWebアプリ直開き(/exec)は外側ページが別オリジンのため弾かれることが多く、
// 余白対策の本命はあくまで doGet の addMetaTag('viewport')。
(function() {
var css = 'html,body{margin:0!important;padding:0!important;width:100%!important;}'
+ 'body,div.script-application-sidebar{margin:0!important;padding:0!important;}'
+ 'iframe{border:0!important;}';
var w = window;
for (var i = 0; i < 5; i++) {
try {
var d = w.document;
if (d && d.head) {
var style = d.createElement('style');
style.textContent = css;
d.head.appendChild(style);
}
} catch (e) { break; } // クロスオリジンの階層に達したら終了
if (w === w.parent) break;
w = w.parent;
}
})();
</script>
</body>
</html>
そして、サーバ側のdoGetでaddMetaTag('viewport')を必ず呼びます(前述)。HTMLとサーバ側はセットで考えてください。
設計のポイント
最初のポイントは、htmlとbodyの余白を明示的に消すことです。GAS Webアプリでは、表示枠の外側と内側の余白が重なって見えることがあるため、土台側でリセットしておくと安定します。
2つ目は、すべての要素にbox-sizing: border-boxを指定することです。幅100%の要素にpaddingを足しても横にはみ出しにくくなり、スマホ画面での横スクロールを防ぎやすくなります。
3つ目は、.containerでPCとスマホの見え方を分けることです。PCではmax-width: 640pxで読みやすい幅にし、スマホでは画面幅を使いながら最小限のpaddingだけ残します。
注意点
- 余白が消えない時はまず
doGetのaddMetaTag('viewport')を疑う。CSSやHTMLの<meta viewport>をいくら直しても、ここが抜けているとスマホ余白は消えません(実際にこれが原因で数回デプロイし直しても直らなかった事例があります) - 親要素の余白除去スクリプトは補助であり、Webアプリ直開き(
/exec)ではクロスオリジン制約で効かないことが多いです !importantは土台の余白リセットに限定し、個別の部品では乱用しない方が保守しやすくなります- 大きな表をそのまま置くと、このテンプレートだけでは横スクロールを防げません
- 入力途中の保護が必要なフォームでは、
beforeunloadや下書き保存も検討します - DevToolsのスマホエミュレーションはGASの入れ子iframeを実機と同じには描画しないことがあるため、最終確認は実機の
/execで行うのが確実です
関連記事
- GAS Webアプリのスマホ対応フォント設定
- GASでカード型レスポンシブレイアウトを実装する方法
- GAS Webアプリの入力途中離脱を防ぐ方法
- GASのgoogle.script.runでエラーハンドリングを実装する方法
まとめ
GAS Webアプリをスマホで使う場合は、画面の中身を作る前に、余白、box-sizing、フォント、コンテナ幅を整えておくと後の調整が楽になります。
このテンプレートを土台にして、カード型レイアウト、入力フォーム、送信中スピナー、エラーハンドリングを追加していくと、スマートフォン向けの業務Webアプリを作りやすくなります。
