昨日書いたリキッドカラムデザインの実験は、リンク先のテキストを解釈しきれていなかったのもあるけれど、実装をどうするかばかりを考えてしまった結果、ちょっと変な実装結果になっていたと思う。
つまり、昨日の実験では幅をおよそ半分以下に設定したときに段組になるように設定したけども、それだと高解像度環境では一行の長さ(=最大文字数)が長くなってしまって、読みづらくなってしまうケースが生じる。そうではなくて、一行の長さを固定的に1 決めた上で、ユーザーのブラウザが、それを超える幅を持つ場合に段組をするようにするのが適切なやり方なんじゃないかと。一言で言うと幅に応じた動的な段組ですね、昨日の記事ではリキッドカラムデザイン(レイアウト)と言っていたことですが。図にするとこんなのです。
jintrick氏の補足では、Mozilla Firefox 1.5以上で実装されているCSS3 段組モジュールの先行実装プロパティを利用して、そうした動的な段組を実現しています(このプロパティについては中身まできっちり調べていなかったので勉強になりました)
CSS 3のマルチカラムレイアウト – Go my wayという記事でもこのプロパティを用いた簡単なサンプルが紹介されています。
で、これを利用して実践に移そうということで、このサイトに適用しています。
Firefox系はこの先行実装を用います。つまり、-moz-column-width
にスライダで設定された値を設定することで、スライダを移動して、好きな段組レイアウトで本文を読むことができます。前のスクリプトのようにスムーズに最大文字数が増減するわけではなく、1カラム→2カラム→‥がガタンガタンと段階的に切り替わるような動きですが、そこまでゲンミツさを求めている人はいないと思うのでよしとしておきましょうか。
それ以外のブラウザ(IE6除く)では、昨日のように本文をdiv要素で真っ二つにして、両方の要素にfloat: left
をかけます。Firefoxのように幅に応じて組段数を柔軟に変更することはできないですし、1カラムか2カラムかを幅に応じて切り替えるのみですが、妥協策としてはまぁそんなに悪かないかなと。
このサイトでは現在、XHTMLコードが妥当でなくなる可能性があるため、Firefox以外のブラウザにこの手法が用いていません。原因は他のブロック要素が始まったときに、divタグを閉じてしまうからです。PHPのDOM関数を使えば安全にできるかもしれませんが、いったん様子見と言うことで。
で、あと残った問題はどう縦スクロールを減らすかですね。読みやすくなっても、上下に行ったり来たりでは面倒くさいですからね。
その他の反応
- 縦スクロールせずに読めるようにならないと、不便。
- カラムの高さをウィンドウサイズ内に制限。
- オーバーフローしたら、新カラムへ。
- 下の段の(或いは新しい)カラムへの移動は、ページをめくるような感じでないと。
これは素敵ですね。イメージにしてみるとこんな感じかな。
コレの良いところは、情報量がどれだけあっても(そこそこ十分な幅と高さがあれば)縦スクロールが一切不要にできることだと思います。コメント云々は下からポップアップ(jigelog)させればいいでしょうし。
技術的には、どうするんだろう‥。1ページ毎の表示(jintrick氏の言うスライドショーのような方法
)ならば、javascriptブラウザの高さを算出して、その高さに合わせた内容量を各々ID付きのdiv要素で括って、target疑似クラスで切り替えるとかでいけそうかな、でもちーともスマートではないですし。
そんなことするくらいなら、同じく内容量を算出してDOM Rangeで選択し、displayプロパティを切り替える方がまだマシかな。いずれにしても、まだ私の技術水準ではできなさそうな感じ。
コード
昨日のコードと多少違います。まずは記事呼出部分。
$content = apply_filters('the_content', get_the_content(__('(Read More)', 'sandbox')));
if (
ereg("gecko\/", $_SERVER['HTTP_USER_AGENT']) ||
ereg("MSIE 5.0", $_SERVER['HTTP_USER_AGENT']) ||
ereg("MSIE 6.0", $_SERVER['HTTP_USER_AGENT'])
){
echo $content;
} else{
$content = split("<p", $content);
$t = floor(count($content) / 2);
echo '<div id="former-part">'."\n";
for ($i=0; $i<count($content); $i++){
if (ereg("^<", $content[$i]) || (!$content[$i])){
echo $content[$i];
} else{
echo "<p".$content[$i];
}
if ($t == $i){
echo "</div>\n";
echo '<div id="latter-part">'."\n";
}
}
echo "</div>\n";
}
<br style="clear:both;" />
スライダー呼出部分。
<script type="text/javascript">
//
// max-width や font-size の単位
define("unit_width", "em");
define("unit_fontsize", "%");
// unit_xxx が "%"以外の場合は基準となる値を設定("%"なら無視)
//unit_width が "%" の場合は、最大値を常に100%として計算します
define("default_width", "50");
define("default_fontsize", "");
// max-width や font-size の振れ幅
// ex: [最小] 40% <== $range_fontsize(%) ==> 100% <== $range_fontsize(%) ==> 160% [最大]
// (この場合の range_width は 30, range_fontsize は 60)
define("range_width", "30");
define("range_fontsize", "60");
// 値を数式処理してセット [ value = $x_min + ( $x_default * $x_ratio ) ]
// max-width
if (unit_width == "%"){
$w_min = 100 - ( 2 * range_width );
} else{
$w_min = default_width - range_width;
}
$w_ratio = range_width / 50;
// font-size
if (unit_fontsize == "%"){
$f_min = 100 - range_fontsize;
$f_ratio = 1 + (( range_fontsize - $f_min ) / 100 );
} else{
$f_min = default_fontsize - range_fontsize;
$f_ratio = range_fontsize / 50 ;
}
if ("<? echo unit_width; ?>" == "%"){
$_COOKIE['userWidth'] = 100;
}
$w_default = ($_COOKIE['userWidth']) ? $_COOKIE['userWidth'] : 50;
$f_default = ($_COOKIE['userFont']) ? $_COOKIE['userFont'] : 50;
val_width = echo $w_min; + ( echo $w_default; * echo $w_ratio; );
val_fontsize = echo $f_min; + ( echo $f_default; * echo $f_ratio; );
setClass(val_width);
document.getElementById("content").style.fontSize = val_fontsize + " echo unit_fontsize; ";
// max-widthの設定
var userWidth = new Slider(document.getElementById("slider-1"), document.getElementById("slider-input-1"));
userWidth.setValue( echo $w_default; );
userWidth.onchange = function () {
val_width = echo $w_min; + (userWidth.getValue()* echo $w_ratio; );
setClass(val_width);
setCookie("userWidth", userWidth.getValue());
};
// font-sizeの設定
var userFont = new Slider(document.getElementById("slider-2"), document.getElementById("slider-input-2"));
userFont.setValue( echo $f_default; );
userFont.onchange = function () {
val_fontsize = echo $f_min; + (userFont.getValue()* echo $f_ratio; ) + " echo unit_fontsize; ";
document.getElementById("content").style.fontSize = val_fontsize;
setCookie("userFont", userFont.getValue());
};
function setClass(val_width){
if ($browser == firefox){
document.getElementById("content").childNodes[1].style.MozColumnWidth = val_width + " echo unit_width; ";
} else{
if (is_single()){
document.getElementById("former-part").style.maxWidth = val_width + " echo unit_width; ";
document.getElementById("latter-part").style.maxWidth = val_width + " echo unit_width; ";
} else{
document.getElementById("content").childNodes[1].style.maxWidth = val_width + " echo unit_width; ";
}
}
}
function setCookie(key, val) {
str = key + "=" + escape(val) + "; ";
str += "expires=Tue, 31-Dec-2010 23:59:59; ";
document.cookie = str;
}
window.onresize = function () {
userWidth.recalculate();
userFont.recalculate();
};
//
</script>
そして、最後にCSSをセット。
div#former-part,
div#latter-part{
float: left;
overflow: hidden;
}
div#former-part{
padding-right: 25px;
margin-right: 25px;
}
いいアイデアだと思うけど、このサイトが横スクロール必須のデザインなところが頭痛い。
Windows IE5, 6でスクロールバーが出るようになっていたのを修正しました。
- もちろん、実際には長さはユーザーが変更可能なのだが