z-index, stacking context の説明

重なり順をコントロールするためには z-index を使えばいい。上にしたい要素ほど高い z-index の値を与えればいい。と思っていたら全然重なり順が思った通りにならない!!といった経験は CSS を書き始めたばかりの人間が必ず経験する出来事だと思う。

私わかったはず!

See the Pen vxwyze by nakanishi (@nakanishi) on CodePen.

まずこの記事を読んでほしいんですが、経験の浅いウェブディベロッパーが z-index で混乱するのは、次の原則を知らないからだと。「z-index は要素の position が absolute, fixed, ralative に指定されていないと機能しない。」作業で疲れてくるとこういうところを見逃しがちです。

その上で MDN のこの記事を読みます。Stacking Context に関する話です。

スタッキングコンテクストを正確に把握するのは難しいのですが、以下の部分が重要です。

It is important to note that DIV #4, DIV #5 and DIV #6 are children of DIV #3, so stacking of those elements is completely resolved within DIV#3. Once stacking and rendering within DIV #3 is completed, the whole DIV #3 element is passed for stacking in the root element with respect to its sibling’s DIV.

#4, #5, #6 の DIV は #3 の子要素なので、#4, #5, #6 の重なり順は DIV#3 の中だけで解決されます。DIV#3 のなかで重なり順が処理された後は、DIV#3 は一つ上の階層、つまりここでは Root エレメントの階層の中での重なり順の処理に移行します。ここではルート階層内の親要素とかなり順を考慮することになります。

つまり

  1. まずは重なり順に関係してくる要素には必ず position: relative, absolute, fixed のどれかを付ける。(他にも flex とか opacity:0 以外でもなるようだけれども、重なり順のコントロールのためには普通は使わない)
  2. 重なり順が z-index でコントロールできるのは「兄弟要素」の間だけ。
  3. 子要素は絶対に親要素の下には配置できない。
  4. 2,3 が起きるのは スタッキング・コンテクストという考え方が必要になる。
  5. スタッキング・コンテクストのダイジェスト:ある要素の中に potision: static 以外の position を持つ子要素がある場合、まずはその子要素の中だけで z-index の順番に重なり合う。この重なりが決まった時点で、それらの子要素は、親要素の上に乗っかって、それら全体で一枚の紙のような扱いになる。一枚の紙のようになった要素は、さらに親要素があって、兄弟要素があれば、兄弟要素の中でまたこのスタッキングコンテクストの処理をする。→以降無限にこの処理

ということで DOM ツリーの中で、同じ親要素を持つ要素同士 = 兄弟要素内でしか z-index の並び順は効かない。ってことですね。 わかればなんということはない!!

 

window.Main = Main;

<script src="./js/velocity.min.js"></script> いつものやつ
<script src="./js/velocity.ui.min.js"></script> UIアニメーション
<script src="./js/ScrollMagic.min.js"></script> 位置情報からトリガーするライブラリ
<script src="./js/animation.velocity.min.js"></script> ScrollMagic のプラグインで velocity との連携を行う
<script src="./js/app.js"></script> メインスクリプト

 

仮Assemble(≒Handlebars)

ほとんどHTMLと同じhandlebars記法でかかれた.hbsファイルをHTMLに変換する。

例えば{{変数名}}で囲まれた変数名を、jsonファイルから参照して、埋め込むことができる。

また{{#if}} {{/#if}}で囲まれた範囲の記述の有無を条件式で指定できる機能もある。

現在主に関わっているプロジェクトでは正確にはassembleを使用しており、その記法にHandlebars記法を使用している。

{{#is}}はその機能。

詳しくは次の記事

https://app.codegrid.net/series/assemble

読み込むJsonファイルは以下のファイルで指定している。(その中ではさらにconfig.jsonから値を取得している)

gulp/tasks/assemble.js

 

仮OGPの設定

LIG社さんの記事を参考にしました

 

{
	"title": "title",
	"meta": {
		"description": "title site"
	},
	"ogp": {
		"enabled": true,
		"siteName": "サイトの名前",
		"type": "website、blog、article等を入れる",
		"url": "http://www.example.com/そのアイテムのページURL",
		"imageUrl": "http://www.example.com/images/ogp.jpg",
		"title": "ページのタイトル",
		"description": "My ogp description"
	},_
	"facebook": {
		"admins": "個人アカウントと結びつけるためのもの。通常の企業サイトでは使わない",
		"appId": "インサイト機能等を使うための企業用のID"
	},
	"twitter": {
		"enabled": true,
		"imageUrl": "http://www.example.com/images/twitter.jpg",
		"title": "My twitter card title",
		"description": "My twitter card description"
	},
	"mixi": {
		"content-rating": false
	},
	"link": {
		"appleTouchIcon": false
	}
}

画像についての注意

画像パス、またURLパスは絶対ですること(仕様)

twitter

1MB以下。

facebook

1200 x 630pxが推奨。縦横比1.91:1の比率。

 

自分が主に参加するプロジェクトでは、テンプレートが使用されており、website.jsonファイルの変数を参照している。{{#is 値 true~}}{{/is~}}で条件式が定義されており、jsonファイル側で値がtrueになっている場合のみ記述される。

{{#is website.ogp.enabled true~}}
<meta property="fb:admins" content="{{website.facebook.admins}}">
<meta property="fb:app_id" content="{{website.facebook.appId}}">
<meta property="og:site_name" content="{{website.ogp.siteName}}">
<meta property="og:type" content="{{website.ogp.type}}">
<meta property="og:url" content="{{website.ogp.url}}">
<meta property="og:image" content="{{website.ogp.imageUrl}}">
<meta property="og:title" content="{{website.ogp.title}}">
<meta property="og:description" content="{{website.ogp.description}}">
{{/is~}}
{{#is website.twitter.enabled true~}}
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{website.twitter.title}}">
<meta name="twitter:description" content="{{website.twitter.description}}">
<meta name="twitter:image:src" content="{{website.twitter.imageUrl}}">
{{/is~}}