Liner Note

情報(ユーザー中心デザイン・ユーザビリティ)と技術(ウェブプログラミング・ウェブサービス)についてのメモ書き

この記事は実験記事で、失敗作です。続編をお読みいただくことを推奨します。

上述するとおり、実際導入してみて失敗したのでこのサイトには導入していないのですが、コードと実装について一応書いておきます。きっかけは、前回と同じサイトの以下のテキスト。

閲覧者のウィンドウ幅が充分広くなると、当然左右、あるいは左右どちらかにスペースができる。そのスペースがある一定以上の幅になったとき、そのスペースに、それまで本文の下部にあった(あるいは異なるURIをもつ外部にあった)補足情報などがサイドバーとして登場する。つまり、ウィンドウをたくさん並べて並行閲覧していても、あるいは低解像度のモニタで閲覧しても、本文がキチンと表示されて利用しやすいリソースとなり、一方、高解像度のモニタでウィンドウを大きくしてみる閲覧者には、その投資に見合ったそれ相応の利益がある。

Hatena::agenda – 本物のリキッドレイアウト

スライダーで動的に1行の文字数と文字サイズを変更・保存するスクリプトでは、内容幅を狭くしたときに、右部分に空きができるのが「もったいないなぁ」とは思っていて、それがこのスクリプトの不満でした。

今回はjintrick氏の提案に着想を得て、その不満を解決できる様な改良を施してみることにした。まずあらかじめ本文を2等分し、本文幅が半分以下に設定された場合、後半のテキストを前半のテキストの右側に回り込ませることにしました(これをリキッドカラムと呼ぶことにしました、本文を6分割すれば6/3/2カラムに柔軟に切り替えることもできるでしょう)

と、言葉で言っても伝わりにくいので、できたものをば。

ビフォー(幅を狭める前)

リキッドカラム(ビフォー)

アフター(幅を半分以下に設定)

リキッドカラム(アフター1)

前半の下段には、後半上部に飛ぶリンクも用意しています

リキッドカラム(アフター2)

実装について

で、これで作ってみて、Firefox ではうまく動作するんですが、Operaでは上手いこと動作しませんでした。あとSafariの動作もちょっと怪しい‥。

これ以上、動作確認できるブラウザを減らしたくないので、今回は導入見送りすることにしました。とりあえず、以下にコードを示しておきますので、利用したい人などは自由に使ってください。

動作としては PHP(サーバサイド)で、本文中の p 要素の数を数えて、本文最初から p 要素が全体の半分の位置に来たところまでを前半の div 要素で、全体の半分の位置から最後までを 後半の div 要素で囲います。この辺はDOM Rangeで本文要素を書き換えてもいいかもしれませんが、スライダー側の処理とタイミングうまくいかないのが原因なのか、上手く動かなかったためサーバーサイドで処理してます。

一方 javascript(クライアントサイド)では、本文要素の幅を監視して、47%以下の場合は回り込みとクラス名の変更、それより大きい場合はその解除を行っています。

なお、記事単体ページとそれ以外のページを分けて処理しているため、WordPressに依存したコードになっているところがあります。

「本物のリキッドレイアウト」について

今まで「どの解像度環境を最低基準にしてデザインを進めるか」ばかりが注目されてきて、「高解像度環境」ではそれに見合ったメリットが得られないどころか、逆に見づらくなるデザインも散見されてきたと思います。

いわば下を見てばかりで、上を見ずに「リキッドデザインはどの解像度環境でも云々」とか言ってきたようなものですから、そうした中で注目すべき提案だと思います。

私もサイドバーいらない論では、1カラム・2カラム..nカラムをユーザーが選べるように(CSS切り替えとかでありがちですが)なるのが理想的な答えだと思いますと言ったこともあり、同じような感想は持っています。

link要素のrel属性・rev属性で示されるナビゲーションなどは、有効に使うUAも少なく、半ばストリクタのおもちゃ的存在な感がありましたが、そうした使い方はなかなか実践的で有効な使い手だと思います(このサイトでは、必要な情報は下部に表示しているので、わざわざ表示しませんけど)

コード

記事単体を呼び出しているところに、本文要素数の計算と要素の追加をしています。一般的には、<?php the_content; ?>を以下のようなコードに書き換えてください。

PHPソースコード (single.php)
<?
$content = apply_filters('the_content', get_the_content(__('(Read More)', 'sandbox')));
$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 '<p id="move-next" class="hidden"><a href="#latter-part">次の段へ移動</a></p>'."\n";
        echo "</div>\n";
        echo '<div id="latter-part">'."\n";
    }
    echo "</div>\n";
}
?>

スライダーを呼び出しているところもいじります。

PHPソースコード (make_slider.js.php)
<script type="text/javascript">
// 
<?
// max-width や font-size の単位
define("unit_width", "%");
define("unit_fontsize", "%");
// unit_xxx が "%"以外の場合は基準となる値を設定("%"なら無視)
//unit_width が "%" の場合は、最大値を常に100%として計算します
define("default_width", "55");
define("default_fontsize", "");
// max-width や font-size の振れ幅
// ex: [最小] 40% <== $range_fontsize(%) ==> 100% <== $range_fontsize(%) ==> 160% [最大]
// (この場合の range_width は 30, range_fontsize は 60)
define("range_width", "40");
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 (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").style.maxWidth = val_width + "<? echo unit_width; ?>";
<? } if (is_single()){ ?>
    if ("<? echo unit_width; ?>" == "%"){
        if (val_width <= 47){
            document.getElementById("former-part").className = "active-part";
            document.getElementById("latter-part").className = "active-part";
            document.getElementById("move-next").className = "button";
        } else{
            document.getElementById("former-part").className = "non-active-part";
            document.getElementById("latter-part").className = "non-active-part";
            document.getElementById("move-next").className = "hidden";
        }
    }
<? } ?>
}
 
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をセット。

CSSソースコード (テーマのCSS)
div#former-part.active-part{
    padding-right:        25px;
    margin-right:        25px;
    border-right:        1px solid #ccc;
}
 
div.active-part{
    float:                left;
    overflow:            hidden;
}
 
/* 後続の要素をclear */
dl.show_uri{
    clear:                both;
}
キーワード:

この記事はシリーズものの一篇です。ブログのIA研究シリーズのそのほかの記事もよろしければご覧ください
RSS このシリーズ記事のフィード

似たもの記事

読者の皆さんの反応サイト内コメントの更新情報(RSSフィード)

読者のコメント

1

ブックマークコメント

0

他サイトの関連記事

1

読者のコメント

  1. お名前

    未熟者

    投稿日時
    2008年12月19日
    13時ごろ
    Comment No
    #1

    リキッドカラムについて勉強中にたどり着きました。
    サーバサイドも利用するんですね。

はてなブックマークでつけられたコメント

この記事はまだブックマークされていません

他サイトの関連記事

  1. ウェブサイト

    agenda

    投稿日時
    2007年11月23日
    15時ごろ
    Comment No
    #1

    本物のリキッドレイアウト – 補足…

    本物のリキッドレイアウト (agenda)の続き。 リキッドなマルチカラムの実例……


トラックバックとは
この記事に言及したサイトをこちらに掲載する仕組みをトラックバックと言います。ここでは、このサイトに頂いたトラックバックを一覧表示しています。
トラックバックしてくださる方へ
この記事への言及がない記事など、トラックバック受信方針に沿っていないものは、読者にお見せしても仕方ないこともあり削除させていただいることをご了承ください。
トラックバックを受け取るためのURI