JavaScriptでアニメーションするサイトを作るときに知っておきたいブラウザの仕組み

HTML5 Carnivalの参加レポートをたくさんの方に読んで頂けて嬉しいです!
(ただ惜しむらくはURLが「fukuok」になっちゃっててすごく気持ち悪い)

僕個人としては、特におおくぼさんのJavaScriptに関するお話しなんかは普段やってる仕事に直接役立つような内容ですごく勉強になったセッションでした。

特にブラウザの仕組みに関する部分は、パフォーマンスを考えるうえでとても重要な内容だなと、一度しっかり勉強してみたいなと思いました。

そんなことを考えていたらあるサイトを見つけまして、これは昨日のセッションを直感的に理解するうえでも役にたつだろうと思ったのでこのエントリーを書くことにしました。

見つけたサイトというのは下記のリンクで、WEBサイトがブラウザによってレンダリング表示される様子を動画で見れるサイトです。

CSS Reflow | Reflow Visualizations

このWEBサイトのトップページにある動画を貼り付けたので見てみてください。
これはブラウザがWEBページがどのようにレンダリングするかを可視化した動画です。

動画は大きく下記の2つのパートに分かれると思います。

1.まずは要素を配置する。(フロー)
2.配置された要素に対してCSSに基づいた装飾を加えていく。(ペイント)

このブラウザの動作をまず知ることがJavaScriptのパフォーマンスをあげるのに重要になってきます。ブラウザの仕組みについて詳しくは下記サイトによくまとめられているそうです。

ブラウザのしくみ: 最新ウェブブラウザの内部構造 – HTML5 Rocks

詳しくは下にリンクを貼ったUstreamとスライドを見たほうが早いと思いますが、要約をするとブラウザがWEBページを描画するときには

HTMLを解析 → レイアウト(フロー) → CSSの内容も含めた描画(ペイント)

というステップを踏みます。

フローの段階でブラウザは「レンダーツリー」と呼ばれる、「配置すべき要素のリスト」をチェックするのですが、さらに細かく見るとレンダーツリーは大きく3つのツリーに分かれます。

・DOMツリー ・・・普通の要素
・フロートツリー ・・・フロートしちゃってる要素
・絶対ツリー ・・・position:fixedやabsoluteされてる要素

要素をアニメーションさせると、要素を動かすたびにブラウザは何度もフローやペイントを繰り返します。(リフロー&リペイント)

で、JavaScriptっていうのはこの3つのツリーを別々に処理するんだそうです。
ということは、周りへの依存関係が少ない絶対ツリーの要素は、アニメーションさせてもさほど処理は重くならないので、動かす要素はposition:fixedやabsoluteして絶対ツリーに入れていこうよということなのです。

逆にDOMツリーの要素は親子関係などがある場合が多いので、1つ要素を動かすと他のレイアウト調整もしなければならず、リフロー&リペイントの負荷が大きくなるのです。

ただ、絶対配置が多くなるとレイアウトしずらくなるよねってお話しもされてました。
そこはうまくレイアウトもJavaScriptでやるか、パフォーマンスを犠牲にするかのトレードオフという感じもします。

さっきも言ったとおり、この内容はスライドとUstream見てもらえればそのまんま説明されているのですが、ただ単にこのWEBサイト見てもらうと、この説明が動画でより理解しやすくなるなーと思って紹介しようと思っただけなんです。はい。

CSS Reflow | Reflow Visualizations

こちらの動画&スライドを見ればばっちり理解できると思います!

画像がフェードイン、フェードアウトごとに配置を変えてローテーションするjQuery

画像イメージが大きさや配置を変えながらローテーションしていくjQueryのスクリプトを書いてみた。

説明がわかりづらいと思うのでデモサイトをご覧ください。

Image Rotation Demo

HTMLは下記のように。
わざわざ画像にfirst、second、thirdと順番にクラスをふってる。
小さく表示させる画像にはmini-photoのクラスが。

<!DOCTYPE HTML>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Image Rotation Demo</title>
	<link rel="stylesheet" href="style.css">
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
	<script type="text/javascript" src="script.js"></script>
</head>
<body>
	<div id="container">
		<div class="rotation">
			<img src="images/rotation1.gif" alt="" class="third"/>
			<img src="images/rotation2.gif" alt="" class="mini-photo first" />
			<img src="images/rotation3.gif" alt="" class="mini-photo second" />
		</div>
	</div>
</body>
</html>

CSSは下記のように。
first、second、thirdそれぞれにabsoluteで配置を決めている。
うーん、めんどくさい。

.rotation{
	width:500px;
	height: 180px;
	position: relative;
}
.mini-photo {
	width: 165px;
	height: 90px;
}
.first {
	position: absolute;
	top:0px;
	left: 330px;
}
.second {
	position: absolute;
	top: 90px;
	left:330px;
}
.third {
	position: absolute;
	top: 0px;
	left:0px;
}

で、javascriptファイルだけど、とりあえずひとつひとつの動作を追ってそのまま書いてる感じ。

$(function(){
	var interval = 4000;
	var delaySpeed = 500;
	$('.rotation').each(function(){
		var container = $(this);
		function switchImg(){
			var imgs = container.find('img');
			var first = imgs.eq(0);
			var second = imgs.eq(1);
			var third = imgs.eq(2);
			second.fadeOut(delaySpeed,function(){
				third.fadeOut(delaySpeed,function(){
					first.fadeOut(delaySpeed,function(){
						first.addClass('first mini-photo').removeClass('third');;
						second.addClass('second').removeClass('first');
						third.prependTo(container).addClass('third').removeClass('second mini-photo');
						imgs.each(function(i){
							$(this).delay(i*(delaySpeed)).fadeIn();
						});
					});
				});
			});
		}
		setInterval(switchImg, interval);
	});
});

全体的なローテーションの間隔はintervalで指定。各画像のフェードイン、フェードアウトのずれはdelaySpeedで指定している。

でも画像に変更があったときなんかは全てのファイルを修正しなきゃだからメンテナンスもめんどくさいし、これどう考えても冗長だよなー。。。

もっとスマートなやり方ができる人がいたら教えてほしいです。。。

ボタンを押すと特定のクラスを持った要素だけ選んでソートしてくれるjQuery

備忘録的にメモ。

商品を並べたときにボタンひとつで特定のジャンルだけ選んで表示したり、お手軽にソートできないかなと思うときがある。今回はそんなときのためのシンプルなjQueryを書いた。

コンテンツ一覧から特定のカテゴリだけ選ぶ、なんてときにも役に立つかも。

今回は、idがKeyYellowのボタンをクリックしたら、yellowというclassが振ってある要素だけが表示されるというものにした。

デモサイトも作ったので参考にしてください。

Class Sorting Demo

htmlは下記の通り。

<!DOCTYPE HTML>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>Class Sorting Demo</title>
	<link rel="stylesheet" href="style.css">
	<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
	<script type="text/javascript" src="script.js"></script>
</head>
<body>
<div id="wrapper">
	<ul id="sort">
		<li id="KeyYellow">Yellow</li>
		<li id="KeyRed">Red</li>
		<li id="KeyBlue">Blue</li>
		<li id="KeyAll">All</li>
	</ul>
	<div id="container">
		<div class="yellow all">sample</div>
		<div class="blue all">sample</div>
		<div class="red all">sample</div>
	</div>
</div>

script.jsはこんな感じで書いた。

$(function(){
	$('#sort li').each(function(){
		$(this).click(function(){
			var idname = $(this).attr("id").substring(3).toLowerCase();
			var classname = '.';
			classname += idname;
			$('#container div:not(classname)').css('display','none');
			$(classname).fadeIn(200);
		});
	});
});

6行目で押したボタンについてるidを取得して加工をしてclass名を作る。
7行目のdiv:not(classname)のところで選択するclass以外の要素は非表示にしてる。
あとは選択されたclassの要素だけフェードインさせて出来上がり。

全部選択するときにallというクラスを全部ふらなきゃいけないとか、もっとスマートな書き方があると思うけどとりあえずこんな感じで作りました。

2013年のWebデザイントレンド

WDLに2013年のWebデザイントレンドをまとめた記事が上がっていたので紹介します。

Web Design Trends in 2013

もう1ヶ月過ぎたけど今年のWebデザイントレンド、おさえとこう、よしそうしよう。

——————————————以下意訳——————————————

この数年間はWebサイトを開発する手法がすごく変化してきた。
より多くのユーザーたちがHTML5とCSS3をサポートしているブラウザを載せたモバイルプラットフォームに切り替えた。

デザインのコミュニティからは次々とユニークな手法がうみだされるから、そのトレンドは毎週変化するように感じる。この記事では僕らが見てきた進化のなかで、最も新しいトレンドをざっとご紹介したい。

これらのデザインアイデアの多くは長い間使われてきたけど、2013年にはこれらのアイデアはもっと主流になってくると思う。

ネット上には無料で提供されているオープンソースプロジェクトやユーザーインターフェースがたくさんあって、これらはデザイナーたちがトレンドを取り入れるのにとっても便利だ。

モバイルファーストデザイン

レスポンシブデザインはなにもフルサイズのWebサイトが縮小レイアウトを実現することだけに限った意味じゃない。考え方としてモバイル端末のデザインから構築に取り掛かるということだ。

このアイデアを語るうえで非常に素晴らしい記事がDesignShackにあがっている。

インターフェースの最も重要なエレメントを最初に用意して、モバイルレイアウトに凝縮することは多くの仕事をやりやすくすると思う。

全てがフィットしない場合はエレメントをいくつか削ろう。
同時に、ウィンドウサイズが大きくなったときにレイアウトがどう変化するかを検討しよう。
他にも多くのページエレメントを検討する余地がある。

mobile-first-book-web-development

A List ApartによるMobile Firstという本があり、モバイルファーストに関するアイデアがたくさん書かれている。

ユーザーが望むモバイルインターフェースを作ることが最優先だと考えるのが最近のトレンドだ。

ほとんどのデスクトップブラウザは多様なレイアウトやインタラクションを実現できる。
だけどそれらのレイアウトをモバイルブラウザ用に縮小することは難しいから、モバイル向けのデザインから始まって、より大きな画面でのレイアウトを考えるほうがいいと思う。

無限スクロールデザイン

多くのソーシャルメディアWebサイトは、フィードやタイムラインを表示するダッシュボード画面に無限スクロールを使っている。

このインターフェースはTwitterやTumblrで人気を博し、Pinterestも自身のホームページで無限スクロールを取り入れている。

pinterest-infinite-scroll-layout

しかしこのインターフェースを利用するまえに「本当に必要なのか?」ということは確認しておいたほうがいいだろう。

確かにリロードの必要ないシームレスなインターフェースが作れる。
しかし、ユーザーが異なるページのパーマリンクを作ろうとすることは難しくなる。
全てのWebサイトが無限スクロールを取り入れる必要はないはずだ。

このインターフェースはページ区切りが必要な情報を読み込むときには効果を発揮する。

しかし例えばブログのアーカイブページに適用するのはあまりいい選択とは言えないと思う。
読者はいつまでも下にスクロールするより、直接15ページ、25ページと移りたがるかもしれないから。

TumblrやPinterestにおいてはいいアイデアだろう。
なぜならこれらのサイトでは情報が絶えずダイナミックに変化しているから。

Twitterフィードの1ページ目や2ページ目は何回もアップデートされるので比較的Ajaxのスピードが重要になってくる。だれも次のツイートセットをみるために「次のページ」というリンクなどクリックしたくはないよね。

ホワイトスペース&ミニマリズム

ホワイトスペースとミニマリズムは長い間Webデザインのトレンドとなっているが、その時々の時代に合わせて進化してきた。

メインコンテンツにユーザーの注意をひきつけるツールとして、ホワイトスペースを使っているWebサイトはたくさんある。

しかし密度の高いWebサイトでも、狭いエリアの密集度を下げるためにホワイトスペースを活用できるはず。

leaftlet-iphone-app-mobile-website

大きく誤解されているのはホワイトスペースデザインでは白が使われるべきという点だろう。

ダークなデザインでも当然ホワイトスペースは使う。
言葉の問題だけど、”空きスペース(empty space)”と呼んだほうがわかりやすいんじゃないか。

これは要素が散らかったなかで一息つく余地をつくっておくということだ。
多くの場合、そうした息継ぎとしてのホワイトスペースはボタンやアイコン、画像として代替される。

デザインポートフォリオにはでっかいタイポグラフィーが見出しと段落の間のホワイトスペースを埋めているものがある。

これはコンテンツを見やすくし、アイキャッチでユーザーがすぐに離脱することを防いでいる。

blip-me-iphone-app-website-layout

ナチュラルなデザインインターフェース

CSS3の仕様は多くの変化をもたらした。

@font-faceを通してタイポグラフィをインポートし、キーフレームでアニメーションをさせることは今時なデモンストレーションのほんの1例だ。
しかしベーシックなCSS3プロパティは自然なレイアウトデザインに影響を与え続けてきた。

その中には角丸やボックスシャドウ、背景グラデーションなどが含まれている。
5~10年前なら、これらのスタイルには画像が必要だった。
現在ではこれらのエフェクトを生成するのに、インブラウザでCSS3を書くだけでモックアップを作れたりする。

今年はますます画像がCSSに置き換わるようになると思う。

dabblet-css-html-gist-website-css3

僕はいつも背景グラデーションを作るのにDabbletを愛用している。

このWebアプリはGithubやGistフレームワークに紐付けされていて、HTMLとCSSプロパティを書けばリアルタイムで表示確認ができる。
すべてのインターフェースはCSS3プロパティが元になっており、見ればこの何年かの進化したトレンドを感じることができるだろう。

大きな写真を使用したデザイン

大きな写真背景を使ったデザインの勢いは衰えない。

実際にこの手のデザインはよく見るし僕自身も同じスタイルでいくつかWebサイトをリリースした。

大きな写真を背景に使うと、ある特定の状況や感情に同調させる効果があると思う。

全てのケースには薦めないが、十分なスペースがある時に適切に使えば、大きな背景画像は心地よいオシャレな印象ををユーザーに与えるだろう。

一番の悩みどころはコンテンツの視認性をいかにあげるかだ。

the-great-discontent-website-background

ランディングページやデザインファームのWebサイトには効果的だと思う。
ポートフォリオサイトや個人的なサイトにもよく利用されるスタイルだ。

より綺麗なソースコードを。

CSSフレームワークの登場はWebサイト制作者のコーディング時間を劇的に改善した。

適切なツールを使えば、2カラム、3カラムのWebサイトレイアウトをものの数分で作ることも可能になってきている。
今までと同じものを作るにしても、より少ないHTMLマークアップで済むようになってきた。

Webサイトを綺麗なソースコードで作ることは、よりサイトが合理化しミニマムになることを意味する。サイズファイルが小さければロード時間も短くすむのでいいことだ。

またレイアウト修正をするときにもソースコードが綺麗ならばスムーズにいく。

僕はオンラインで整ったHTML/CSSを読んだり、才能ある制作者の記事を読んで多くのことを学んできた。

html5-github-open-source-projects

GithubStack Overflowは重要な学習リソースだ。
Githubにはたくさんのフリーソースコードがあり、ダウンロードしたり活用できる。
Stack Overflowはとても実用的な開発者のQ&Aコミュニティだ。
この2つのWebサイトにはお手本となるようなソースコードや情報が豊富にある。

結びとして

Webデザイナーのコミュニティはいまやグローバルになり、私たちはお互いの情報やスキルをシェアできるようになった。間違いなくWebデザインという分野にとってこれほど良い時代はないだろう。

Webデザインの分野で生き残るためのベストな道は、そのトレンドに積極的に身をおいてみることだ。ブログを読み、チュートリアルを実践し、最新のWeb制作に常に触れていよう。

jQuery MasonryをWordPressで使ったときのメモ

要素を隙間なく埋める、いわゆるPinterest風のレイアウトを作ることができるjQueryプラグインMasonryを使ってWordPressでサイトを作ったので手順などをメモして置きます。

jQueryファイルのダウンロード

設置自体は難しくなく下記のサイトからjquery.masonry.min.jsをダウンロードしてサイトフォルダに置きます。

jQuery Masonry

まずはデモを見やすくするためにWordPressではなくて普通のサイトで使う方法を説明します。

サンプルコード

HTMLは例として下記のようなものを用意します。

<div id="container">
	<div class="post">コンテンツ</div>
	<div class="post">コンテンツ</div>
	<div class="post">コンテンツ</div>
	<div class="post">コンテンツ</div>
	<div class="post">コンテンツ</div>
</div>

次にMasonryを動かすために下記のようなsample.jsを書きます。

$(function(){
	$('#container').masonry({
		itemSelector: '.post',
		columnWidth: 270,
		isAnimated:true,
	});
});

ここではMasonryを適用させるアイテムとして.postを指定し、それを包括する親要素として#containerを指定しています。

HTMLファイルにjsファイルを読み込む記述をしましょう。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script><script type="text/javascript" src="jquery.masonry.min.js"></script>
<script type="text/javascript" src="sample.js"></script>

CSSはサンプルで下記のようなものにしました。

body {
	background: #CCC;
}
#container {
	width:80%;
	margin:0 auto;
}
.post {
	background: #FFF;
	width:230px;
	padding:10px;
	margin:10px;
}

.postについて、marginとpaddingとwidthをあわせた幅は先ほどのsample.jsで指定したcolumnWidthの値に収まるようにしましょう。

#containerのwidthは%指定することでリキッドレイアウトになり、ブラウザの幅にあわせてカラム数が変化してくれます。

あと、sample.jsでisAnimatedを有効にしておくことでカラム数が変わるときにアニメーションをさせることができます。デモサイトを作ったので参考にしてみてください。

デモサイト

WordPressへの実装

さて、このMasonryをWordPressで使えるようにします。
といっても難しいことはなく、テーマフォルダにjsファイルを置いて、下記のコードを<head></head>内に書けばいいだけです。

<?php wp_enqueue_script('masonry', '/wp-content/themes/テーマ名/js/jquery.masonry.min.js',array(jquery)); ?>
<?php wp_enqueue_script('sample', '/wp-content/themes/テーマ名/js/sample.js',array(jquery)); ?>
<?php wp_head(); ?>

あとは自分で作ったHTMLやデザインにあわせて前述したsample.jsやCSSを書き換えしてみてください。