この翻訳は不完全です。英語から この記事を翻訳 してください。
「Planning your App」の記事の中で、わたしたちは、あなたがアプリのコーディングを始める前に決める必要がある、企画性と機能性に分類される決定において、デスクトップとモバイルのデザインのためのいくつかのアイデアを含め、高いレベルの画面を提供します。この記事は、モバイルファーストのコンセプトに注目し、いくつかの関連するアイデアを提案します。標準的なレイアウト構成は、モバイル端末のためのものです。そして、デスクトップブラウザ用のレイアウトや機能は、その標準的なレイアウト構成の上に積み重ねられます。このガイドは、モバイルファーストの包括的な内容を含む、いくつかの有用な技術に注目します。
重要なものから順番に 標準としてのモバイル
わたしたちがデスクトップサイトを扱うことに慣れてしまっているように、モバイルでの体験を最初に考えることを、あなたは無意味に思うかもしれません。確かに、わたしたちは、よりシンプルで合理化された、または何であるモバイルの体験を切り捨てる前に、デスクトップ、モバイルなども包括した体験に関して、すべての機能の範囲について考える必要があります。これは本当らしく聞こえますが、わたしたちの経験では、モバイルファーストは、もっと基本的な標準のモバイル実装についてです。
企画の段階ではすべての体験を考慮します。適切な場合はいつも、追加情報を詰め込む前に、どのような機能が、モバイル、デスクトップその他の端末で実現可能か。それに前後して、どのように実装されるべきか。その後、実装段階において、レイアウトと機能を提示します。これは、モバイル(しばしば利用者が少なく、帯域幅や処理能力が小さいターゲット端末)が早ければ早いほど、気持ちの良い体験を与えることができ、本質的ではない情報から解放されることを意味します。例えば、
- もし、あなたが、異なったviewportサイズ用に、レイアウト情報とスタイルを分けて用意しているならば、デスクトップやワイドなスクリーンのスタイリングを優先するよりも、狭いスクリーンやモバイルのスタイリングを優先した方が効率が良いです。この方法では、モバイル端末は別ファイルやその他の情報を2回読み込む必要はありません。
- もしあなたが、機種判別機能や、viewportサイズに応じて条件付きでスクリプトを読み込む「matchMedia」機能、特定の機種をサポートするものなどを使っているなら、ほとんどすべてのブラウザが最初に必要とする基本的なものを読み込むべきです。それから、優先度の高いブラウザを順番に強化していきましょう。
全体からスタートして必要ないものまでカバーするより、最少限から始めて、必要に応じて作り上げていくことが、常に大事です!
モバイルの制約
モバイルは他のデバイスと比較して、一般的にメモリが少なく、処理速度も遅く、帯域幅も狭いことは、すでに言及しました。(スマートTVも同じく一般的にかなり低い性能であることを覚えておきましょう。)モバイルはまた、狭いviewportしか提供されていません。したがって、コンテンツはそれぞれの画面用に分けた方が良いでしょう。また、インターフェースを簡略化し、コンテンツを出来る限りそれぞれの画面用に制作し、影やアニメーションやグラデーションのようなビジュアル効果を含まない方が良いでしょう。アプリケーションをモバイルで動かした時に、遅いパフォーマンスを体験したなら、少なくともそれらはオプションとして考えるべきです。
物理的な操作方法
モバイル端末において、物理的な操作方法は、もう一つの大きな制約です。モバイル端末からフォームに入力しようとしたことがある人なら誰でも、または数回でも複雑なサイトで迷ったことがある人なら誰でも、このことにはよくご存じでしょう。これが、モバイルにあらゆることを簡潔にするべき理由なのです。可能であれば、それぞれの項目を1ビューに保ち、ユーザーが入力するだろうと予測される文字の量を減らしましょう。入力する文字の量が減ったら、モバイルのユーザーはもちろん、デスクトップのユーザーも喜ぶでしょう!
使用コンテキスト
全ての最上位には、モバイル端末が使われる状況や、モバイルでユーザが最も実行したがるタスクの種類を考慮しないといけません。いくつかの場所で読むフレーズは"一つの目、一つの親指"で、これはユーザの注意をどれほど持っているかに触れています。もちろんユーザはやろうとしている事に集中していますが、明るくない社内にいたり、TVのスポーツが流れているうるさいバーにいたりしがちです!
これらを考慮して、コンテンツ・機能性がシンプルであるか、なるべく読みやすく気を散らすものがないのか、再度確認する必要があります。
モバイルナビゲーション
When developing mobile app layouts, you often run into problems with navigation menus. The concept is the same regardless of the target device — you want to provide a mechanism for users to search for things and get to different views/pages of the application — but because mobile screens are so much smaller, a reasonable desktop navigation can spoil the experience by filling up most of the initial view of the app, covering up the content.
There are a number of ways to solve the problem of navigation getting in the way on mobile, a few of which i'll discuss here. The main objective is to put the content first, and to hide away the navigation until the user really needs it.
First of all, you can consider a different navigation mechanism on mobile. So if you were planning to have a vertical navigation menu on desktop, you might replace this on mobile with a select menu containing the options, or even a single button that when pressed brings the navgation options up in an overlay.
Second, a popular option is to put the navigation menu down at the bottom of the page rather than up at the top as the expectation would commonly be. This puts the content first at the top of the page, and means that when the user has reached the end of a page, they have a sign post giving them an idea of where to go next.
Third, combining the two is also a good option — why not have a single button at the top of the page, which links to an anchor on the nav menu at bottom of the page? You could then also provide a link to get back up to the top of the article.
条件付きリソースローディング
実際にレスポンシブ/アダプティブなデザインを実装するには、条件付きリソースローディングにある程度の協力をえる必要があるでしょうし、それによって異なる端末に最適化されたエクスペリエンスが、たくさんの不要なリソース読み込みの重荷を背負うことなしに、得られるでしょう。詳細は下記を見てください。
簡単な例
To demonstrate the concepts I wanted to cover in this article, I created a very simple app containing a nav menu, heading and single column of text. You can see my mobile first example running live, or grab the code to play with it on Github. To make my simple example I created a sample app structure from a Mozilla Mortar template. I installed the Volo automation tool by running the following on the command line
sudo npm install -g volo
(You'll also need to get Node.js too, if you don't already have it)
I then created my sample project using
volo create myapp mozilla/mortar-app-stub
This creates a sample project inside a directory called myapp. The app's code files are inside the www folder. Volo has a number of useful commands available (find out more on Volo's homepage), of which we will just use a couple:
volo server
: starts a local web server at localhost:8080 and runs your app through it: great for easy testing.volo build
: builds a minified code version of your app, ready for production deployment, in a www-built folder.volo build base=www-built
: runs the built version through the server instead of the development version.
ビルトイン機能の Mortar テンプレート
Mortar templates contain a number of built in features: Read アプリのテンプレートを使用する for more details. In this sample app I have used a couple of the built-in features to:
- Include an install button that works for Firefox OS, Firefox Aurora, Chrome and iOS app installs (as explained on the Install github page). To make the install button work, all you have to do is put a
<button>
on the page with an ID ofinstall-btn
. Magic! - Selectively include JavaScript libraries according to media query and feature tests (require.js is built in, which is helpful and very easy to use.)
HTML 構造
For this example app, the HTML structure is going to be very simple: I am just including a heading, navigation menu and filler text to highlight the fact that articles can get very long on narrow screen devices. Our HTML looks like this:
<article> <nav> <ul> <li><a href="#">Home</a></li> <li><a href="#">Articles</a></li> <li><a href="#">Videos</a></li> <li><a href="#">Work</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul> </nav> <header> <a id="top" href="#bottom">Jump to menu</a> <h1>My article</h1> </header> <div class="main"> <p>Lorem ipsum … </p> <a id="bottom" href="#top">Back to top</a> </div> </article> <button id="install-btn">Install</button>
デフォルトのモバイルCSS
For the CSS, I first added some styles into our app.css stylesheet to provide a reasonable narrow screen layout. There is very little going on here, and anyone with a basic understanding of CSS should be able to understand most of it by just looking at the source code in app.css. Particular bits of interest to point out are as follows.
article { display: table; } nav { display: table-caption; caption-side: bottom; }
This is a rather nice hacky bit of CSS you can use to make the navigation menu display at the bottom, even thought it is at the top in the source order. And it works in IE8+. display: table
makes the <article>
and its children display in a table layout, without abusing table markup. display: table-caption
makes the <nav>
element think it's the caption of the table, and caption-side: bottom
makes it jump down to the bottom of the table.
One word of warning about this technique though - positioning doesn't work as expected on elements with display: table
set on them. I have included two links in my markup:
<a id="top" href="#bottom">Jump to menu</a> … <a id="bottom" href="#top">Back to top</a>
The first one is to jump down from the top of the article to the navigation menu, and the second one is to jump back up to the top of the article again. I had to make sure both of these were NOT direct children of the <article>
, otherwise the following would not work:
#bottom, #top { font-size: 0.8em; position:absolute; right: 1em; text-decoration: none; } #top { color: white; top: 0.5em; } #bottom { bottom: 0.5em; }
I also set their parents to be positioned relatively, so they would become the positioning contexts of the absolutely positioned elements (you don't want them to be positioned relative to the <body>
element.)
モバイルファーストなレイアウトを追加する
The above layout is fine for narrower layouts, but it doesn't work very well when you get wider than about 480px. To create something more suitable for desktop, I put in the following media queries:
@media (min-width: 480px) { #bottom, #top { display: none; } article, nav { display: block; } nav ul { text-align: center; } nav li { display: inline; } nav li a { border-right: 1px solid #AD66D5; border-bottom: none; display: inline-block; padding: 0 5px; font-size: 1.6em; } nav li:last-child a { border-right: none; } } @media (min-width: 600px) { html { background: #eee; height: 100%; } body { width: 600px; height: inherit; margin: 0 auto; background: url(../img/firefox-os.png) bottom left no-repeat, linear-gradient(to bottom, #fff, #eee); } .main > p { background: rgba(255,255,255,0.3); } nav li a { padding: 0 10px; font-size: 2em; } }
The first one cancels out the CSS display: table
behaviour, hides the links to jump to and from the navigation, as they are not needed anymore in the wider layout, and changes the vertical menu to a horizontal menu that makes better use of the horizontal space available.
The second one sets the width of the content at 600px and centers it in the space available, then adds in a gradient and a nice background image for the wider layout. This is a key point - the background image is 126KB, and not ideal for narrow layouts. Having it included inside the "600 pixel or wider" media query means that narrow screen devices won't read that media query, so they will not waste their time and bandwidth downloading that image.
Note: Firefox's Responsive Design View is a great way to get a quick idea of how your media queries are behaving themselves. Try it out with Tools > Web Developer > Responsive Design View.
機能の検出
Feature detection involves doing tests (usually in JavaScript) to determine whether a browser supports a certain feature, and then serving CSS or JavaScript to suit that situation. This can be very useful for mobile first, as you may well want to hide bits of code from the "mobile version" and only include them for the "desktop version", or vice versa.
You can write you own feature detects (Mark Pilgrim's All-In-One Almost-Alphabetical Guide to Detecting Everything is a good start), but really it is much better to use a dedicated existing solution, such as Modernizr. Modernizr is a good choice as it not only includes a feature detect for just about everything (CSS, HTML5, some other bits besides), it is also fairly reliable, and you can create your own custom version with only the feature detects you need in it, using the Modernizr Download Builder. The full uncompressed Modernizr library is 42KB, but the version we are using in this demo is only 8KB.
I put Modernizr inside my js/lib
directory, then included it by putting the following construct inside my HTML file:
<script type="text/javascript" src="js/lib/modernizr.js"></script>
With Modernizr in place, we cna now use the following JS block to test whether media queries are supported, and if not, to load in respond.js, Scott Jehl's matchMedia
and media query polyfill.
if(!Modernizr.mq('only all')) { require('respond'); }
EDITORIAL NOTE: This currently doesn't work, and I'm not sure why. Ongoing work required.
matchMedia
is also very useful in many other ways. Imagine you wanted to include some kind of WebGL chart in the desktop version of the site requiring a WebGL library like Three, but didn't want it included in the mobile version? You could create a block to only load the library in the case of narrow screen devices:
if(window.matchMedia("(min-width: 481px)").matches) { require('three'); }
We can therefore save the bandwidth for browsers that don't need it.
Modernizr CSS と JS
Back to Modernizr! The reason why it is so useful is that it provides a mechanism to selectively serve both CSS and JavaScript. Modernizr stores the results of all its feature tests as classes on the HTML element. For example, the Modernizr in our example app is testing for multiple background image and rgba support. When they are not supported, the <html>
tag looks like this:
<html class=" js no-rgba no-multiplebgs">
When these are present, we can serve alternative styling rules to provide sensible fallbacks using descendant selectors — see the following in my code.
.no-multiplebgs body { background: white; } .no-rgba .main > p { background: white; }
This is not hugely pretty, but it does make the main content area more readable on browsers that don't support either or both of these features.
Modernizr also puts its feature detect results in a JavaScript Modenizr
object too, so that you can run JavaScript code selectively depending on feature support. For example you could do this:
if(Modernizr.rgba) { // run code that depends on RGBA colours being supported. }