Movable Type で作る可変な固定レイアウト

2月17日にロクナナワークショップで開催される「実験!Movable Typeラボラトリー」に参加するので、今日は Movable Type テンプレートのアイデア的ネタを記事にしてみます。

昨年のDevConのライトニングトークでチラッとしゃべったネタの中で、「変数を利用して、3カラムレイアウトの幅を自動で変えるテンプレート」みたいなことを話しました。それがこの「可変な固定レイアウト」です。

[ 980px, Wide-Thin-Thin ]

layout_980wtt.png

[ 100%, Thin-Wide-Thin ]

layout_100twt.png

変数の値と変えれば、自動的に幅を計算し、上の画像のようにレイアウトを変えてくれます。

サンプルのHTMLのテンプレート

まず、今回のサンプルのHTMLは以下の通りです。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja" dir="ltr">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <meta http-equiv="content-style-type" content="text/css" />
 <title>Movable Type で作る可変な固定レイアウト・サンプル - かたつむりくんのWWW</title>
 <link rel="stylesheet" href="variable_fixed.css" type="text/css" media="screen,tv" />
</head>
<body id="home" class="main_index layout-wtt">
 <div id="page">
 <div id="header">
 <h1 id="siteName"><a href="/blog/">Movable Type で作る可変な固定レイアウト・サンプル</a></h1>
 </div>
 <div id="wrapper">
 <div id="primary">
 <p>ここが primary コンテンツです。</p>
 </div>
 <div id="secondary">
 <p>ここが secondary コンテンツです。</p>
 </div>
 <div id="extra">
 <p>ここが extra コンテンツです。</p>
 </div>
 </div>
 <div id="footer">
 <p>ここが footer コンテンツです。</p>
 </div>
 </div>
</body>
</html>

サンプルのCSSのテンプレート

そして、上記HTMLに適用する可変な固定レイアウトのCSSは以下の通りです。

@charset "<mt:PublishCharset />";
<mt:Ignore>
********** レイアウト: カラムタイプ **********

 Wide-Thin-Thin : wtt (default)
 Thin-Wide-Thin : twt </mt:Ignore>

<mt:SetVar name="column_type" value="wtt">

<mt:Ignore>
********** レイアウト: コンテンツ全体の幅 **********

 コンテンツ全体の幅 (default : 980)</mt:Ignore>

<mt:SetVar name="page_width_value" value="980">

<mt:Ignore>
********** レイアウト: コンテンツ全体の幅 **********

 コンテンツ全体の幅の単位 (default : px)</mt:Ignore>

<mt:SetVar name="page_width_unit" value="px">

<mt:Ignore>
********** 自動計算(変更不要) **********</mt:Ignore>

<mt:GetVar name="page_width_value" cat="$page_width_unit" setvar="page_width" />

<mt:GetVar name="page_width_value" value="24" op="/" regex_replace="/\.[0-9]*/","" setvar="primary_width_value" />
<mt:SetVar name="primary_width_value" value="14" op="*" />
<mt:GetVar name="primary_width_value" cat="$page_width_unit" setvar="primary_width" />

<mt:GetVar name="page_width_value" value="24" op="/" regex_replace="/\.[0-9]*/","" setvar="secondary_width_value" />
<mt:SetVar name="secondary_width_value" value="5" op="*" />
<mt:GetVar name="secondary_width_value" cat="$page_width_unit" setvar="secondary_width" />

<mt:GetVar name="secondary_width_value" cat="$page_width_unit" setvar="extra_width" />

<mt:SetVarBlock name="layout_info">/* 各カラムの幅 = primaryWidth:<mt:GetVar name="primary_width" />, secondaryWidth:<mt:GetVar name="secondary_width" />, extraWidth:<mt:GetVar name="extra_width" /> */</mt:SetVarBlock>

/* ----------------------------------------
 __layout
---------------------------------------- */
<mt:GetVar name="layout_info" />

* {
 margin: 0;
 padding: 0;
}
body {
 text-align: center;
}
#page {
 position: relative;
 margin: 0 auto;
 width: <mt:GetVar name="page_width" />;
 text-align: left;
 overflow: hidden;
 background-color: #cccccc;
}
* html #page {
 height: 1%; 
}
#header {
 background-color: #0000FF;
}
#primary {
 background-color: #FF8000;
}
#secondary {
 background-color: #00FF00;
}
#extra {
 background-color: #800080;
}
#footer {
 clear: both;
 background-color: #0C2847;
}

<mt:If name="column_type" eq="wtt">
/* ===== Wide-Thin-Thin ===== */

#primary, #secondary {
 display: inline;
 float: left;
}
#extra {
 display: inline;
 float: right;
}
#primary {
 width: <mt:GetVar name="primary_width" />;
}
#secondary {
 width: <mt:GetVar name="secondary_width" />;
}
#extra {
 width: <mt:GetVar name="extra_width" />;
}

<mt:ElseIf name="column_type" eq="twt">
/* ===== Thin-Wide-Thin ===== */

#primary, #secondary {
 position: relative;
 float: left;
}
#extra {
 position: relative;
 float: right;
}
#primary {
 left: <mt:GetVar name="secondary_Width" />;
 width: <mt:GetVar name="primary_Width" />;
}
#secondary {
 left: -<mt:GetVar name="primary_Width" />;
 width: <mt:GetVar name="secondary_Width" />;
}
#extra {
 width: <mt:GetVar name="extra_Width" />;
}
</mt:If>

解説

レイアウトのタイプを指定する

<mt:Ignore>
********** レイアウト: カラムタイプ **********

 Wide-Thin-Thin : wtt (default)
 Thin-Wide-Thin : twt </mt:Ignore>

<mt:SetVar name="column_type" value="wtt">

現在は、3カラムレイアウトの2パターンのみに対応しています。

この部分で、変数 column_type の値を「wtt」「twt」に設定することで、カラムの並び順を指定します。

コンテンツ全体の幅を指定する

<mt:Ignore>
********** レイアウト: コンテンツ全体の幅 **********

 コンテンツ全体の幅 (default : 980)</mt:Ignore>

<mt:SetVar name="page_width_value" value="980">

この部分で、変数 page_width_value の値を設定することで、コンテンツ全体の幅を指定します。サンプルのHTMLでいえば、div#page の幅になります。

この部分のポイントは「数値のみ」で「単位不要」です。

コンテンツ全体の幅の単位を指定する

<mt:Ignore>
********** レイアウト: コンテンツ全体の幅 **********

 コンテンツ全体の幅の単位 (default : px)</mt:Ignore>

<mt:SetVar name="page_width_unit" value="px">

この部分で、変数 page_width_unit の値に「px」や「%」を設定することで、先ほどのコンテンツ全体の幅の指定と合わせて div#page の幅が決まります。幅の値を単位を分けたことで、より多くのレイアウトに対応できます。

自動に白銀比で計算する

<mt:Ignore>
********** 自動計算(変更不要) **********</mt:Ignore>

<mt:GetVar name="page_width_value" cat="$page_width_unit" setvar="page_width" />

<mt:GetVar name="page_width_value" value="24" op="/" regex_replace="/\.[0-9]*/","" setvar="primary_width_value" />
<mt:SetVar name="primary_width_value" value="14" op="*" />
<mt:GetVar name="primary_width_value" cat="$page_width_unit" setvar="primary_width" />

<mt:GetVar name="page_width_value" value="24" op="/" regex_replace="/\.[0-9]*/","" setvar="secondary_width_value" />
<mt:SetVar name="secondary_width_value" value="5" op="*" />
<mt:GetVar name="secondary_width_value" cat="$page_width_unit" setvar="secondary_width" />

<mt:GetVar name="secondary_width_value" cat="$page_width_unit" setvar="extra_width" />

<mt:SetVarBlock name="layout_info">/* 各カラムの幅 = primaryWidth:<mt:GetVar name="primary_width" />, secondaryWidth:<mt:GetVar name="secondary_width" />, extraWidth:<mt:GetVar name="extra_width" /> */</mt:SetVarBlock>

あとは自動で3つのカラムの幅を算出します。このとき、「Wide」カラムと「Thin+Thin」カラムの比率がだいたい白銀比になるように算出してくれます。なので、レイアウトが出来上がった時点でそこそこいい感じになります。

The blog of H.Fujimotoさんが公開している変数の機能を拡張するプラグインを使えばもっとシンプルになるはずですが、ここではあえて使っていません。

算出された値は、指定した単位を付けて次のように変数に格納されますので、あとはそれをCSSのテンプレートに埋め込んでいけばOKです。

  • primary_width : 「Wide」カラムの幅
  • secondary_width : 「Thin」カラムの幅
  • extra_width : 「Thin」カラムの幅

ちなみに、layout_info という変数で、3つのカラムの幅が確認できるようになっています。

完成イメージ

数パターンの完成イメージの画像は次の通りです。

【wtt : 800px】

wtt_800px.png

【wtt : 980px】

wtt_980px.png

【wtt : 99%】

wtt_99perc.png

【twt : 750px】

twt_750px.png

【twt : 980px】

twt_980px.png

【twt : 100%】

twt_100perc.png

以上です。細かい調整をCSSで行う必要があるかもしれませんが、僕的には便利なアイデアだと思っています。

今後は、もっと対応するレイアウトパターンを増やしたり、計算の完成度を上げていきたいと思っています。そのうち、テンプレートを公開するのが目標です。