最近書かれた記事5件分を表示します。
更新状況をRSS 1.0形式でご覧になれます。
Operaが開発10周年を迎え、Opera 10-year online anniversary party - My Opera Communityでは1日限定(30日16時から31日16時までらしい)でregistration codeが無料配布されている。
Operaは元々無料で使用できるブラウザであり、registration codeを購入することで広告を取り外して表示領域を広げられる。今回配布されているregistration codeは、その広告を取り外すためのものだ。
私はおよそ2年前にOperaを「購入」して以来、ずっと使い続けている。完璧なブラウザではないが、マウスジェスチャーやFastForwardといった便利な機能がたくさんあり、使うほどに手放せなくなる。これらの機能はGoogle検索において最も効果を発揮し、検索効率はMSIEやFirefoxの比ではない。
だが、ブラウザというもの、どれが一番であるかといった議論は無意味である。これは海外の話であるが、この類の議論とも形容できぬ言い合いは見ていて滑稽にさえ思えた。いくつかの選択肢があるなら、それぞれを自分で試してみたらよい。自分にとっての一番は決められるだろうが、万人にとっての一番など存在しない。
CSSのcontentプロパティで生成する文字列には改行(\A; br要素と等価)を含められるが、Gecko(Firefoxなど)では改行(br要素)を行わずに改行コード(CRやLF)を返す。だが、これはバグなどではなく仕様であった。
生成文字列を改行するには、バックスラッシュでエスケープしたAを入れてやればよい。
blockquote:after {
content: "引用元: " attr(title) "\A URI: " attr(cite);
}
これだけで改行が行われそうなものだが(Operaは改行を行う)、CSS 2.1 Specification(W3C)では次のように説明されている。
Authors may include newlines in the generated content by writing the "\A" escape sequence in one of the strings after the 'content' property. This inserted line break is still subject to the 'white-space' property.
CSS 2.1 Specification: 12 Generated content, automatic numbering, and lists - W3Cより引用
改行を行うにはwhite-spaceプロパティを併用する必要があるそうだ。引用文の直下に示されている例では、white-space: pre;として生成文字列に含まれる空白類文字をそのまま扱うようにしている(pre要素と同じ扱い)。pre要素に含まれる改行コードは改行としてレンダリングされるため、Geckoにおいても改行が行われる。
つまり、先程のコードは次のようにしなければならない。
blockquote:after {
content: "引用元: " attr(title) "\A URI: " attr(cite);
white-space: pre;
}
なお、MSIE6は疑似要素(:afterなど)を認識しないため、これらの指定は一切無効となる。
MSIE6はDOCTYPE宣言の有無によって挙動を変えるといわれているが、詳しくは知らなかった。別件でXML宣言を外した(DOCTYPE宣言が先頭に来た)際に綺麗にレンダリングされたため、不思議に思って調べたところ、XHTML文書における落とし穴の存在を知ることになる。
!DOCTYPEスイッチについてはIE6研究会が詳しい。DOCTYPE宣言があれば標準準拠モード(仕様に従った)、なければ後方互換モードという挙動をするそうだ。後方互換モードは次のように解説されている。
後方互換モードとは、IE 3 / 4 / 5 / 5.5 でなされていた IE の独自(あるいは、誤った)解釈によるスタイル解釈のことです。これは大雑把に言うと「DOCTYPE 宣言を付けてない人は HTML の文法なんか知らない。だから、スタイルも IE 依存になっていることも多く、仕様に厳格な挙動をすると今まで見えていたサイトが見えなくなってしまう。そこで、そうした文書における挙動は今までの IE と同じにしておこう」という考えに基づいています。
標準準拠モード(!DOCTYPE スイッチ) - IE6研究会より引用
確かにその通りだ。だが、この後方互換モードがあるために、MSIEでしかまともに表示できない「ホームページ」を制作する連中(随分減ったように思うのは、それらの世界から乖離しているせいか)が後を絶たないのも事実ではないか。あるいはWebページ制作の難易度を下げるのに一役買っているとも考えられるが、開発者には相当なディレンマがあったことだろう。
話は戻って、この!DOCTYPEスイッチには落とし穴が存在していた。IE6研究会によると、XHTML は XML 宣言から始まりますので、文法通りに書くと表示が後方互換モードになってしまいます
とのこと。XML宣言を見て「DOCTYPE宣言がない」と判断してしまうらしい。道理でおかしな解釈をするわけだ。
XML宣言を見て後方互換モードに入るようでは、MSIEに対してはXML宣言を出力しないほかない。文字エンコーディングにUTF-8(あるいはUTF-16)を用いていればXML宣言を省略できるため、迷わず省略することに決めた。
標準準拠モードでレンダリングさせてもいくらかのバグは残るが、後方互換モードに比べると随分とよくなっている。MSIE6とは先が長いだろうから(MSIE7が普及するとは思えない)、この仕様を知っておいて損はない。Webデザインにおいて「駄目だ」と切り捨てるのはまだ早いと思い改めた。
gzip圧縮転送とは、ファイルを圧縮した状態で転送する技術のことである(元々圧縮されているファイルを転送することではない)。圧縮転送されたファイルはクライアントサイドで展開されるが、ユーザが圧縮や展開を意識することは通常ない(気づかない)。ファイルを圧縮するとファイルサイズが当然に減少するため、gzip圧縮転送を用いると転送量の削減が期待できる。
gzip圧縮転送を導入するには、Apacheのモジュール(mod_gzip)か、PEAR(PHP; --with-zlibを要す)を使う。ちょうどサーバに--with-zlibがあったため、今回はPEARを使うことに決めた。
HTTP_Compress(PHP-library.com)の例ではcompress.phpを呼び出しているが、手元のphp\PEARディレクトリには見当たらず、サーバにも存在しないようだった。「いつの間にかパッケージから消えている」との情報もあり、まずはcompress.phpを探すことになる。
compress.phpは検索するとすぐに見つかり、キャッシュファイルではあったがコードを入手できた。
compress.phpで呼び出しているPEAR.phpは手元(php\PEAR\go-pear-bundle)にもサーバ(require関数で呼び出しているため、include_pathのディレクトリから自動的に探してくれる)にもあり、これを探す必要はない。
compress.phpを適当なディレクトリに用意したら、ファイルの先頭(共有のヘッダファイルでも構わない)に次のコードを記述する。
require_once "foo/compress.php";
HTTP_Compress::start();
ファイルの末尾には次のコードを記述する。
HTTP_Compress::output();
無論、これらはPHPのコードであるから、単一で使う場合は<?php ~ ?>とする必要がある。
gzip圧縮転送を利用するには、HTTPリクエストヘッダのAccept-Encodingフィールドに値gzipを含んでいる必要があり、必ずしもすべてのブラウザが利用できるわけではない。
OperaやFirefoxといった最近のブラウザであれば問題ないが、MSIE6はインターネットオプション > 詳細設定でHTTP/1.1を有効にしておく必要がある。HTTP/1.1を有効にしない場合は、圧縮を行わない通常のデータが送出される。
XHTML文書などのテクストファイルであれば、60%前後のサイズダウンが見込める。実際の効果は、Compression Check(Port80 Software)で確認すると分かりやすい。

17090バイトのファイルが圧縮によって5718バイトになり、11372バイトの転送量を節約している。ファイルサイズは67.0%カットされ、(理論上の)転送速度は以前の2.9倍である。
CSSファイルも圧縮転送できるが、XHTML文書と違っていくつかの手順を踏む必要がある。
まずは、拡張子.cssのファイルでPHPを処理できるようにするため、.htaccessに次の指定を加える。CSSファイルを拡張子.phpにしてしまうなら、この指定は不要である。
AddType application/x-httpd-php .css
CSSファイルの先頭には次のコードを記述する。
<?php
require_once "foo/compress.php";
HTTP_Compress::start();
header ("content-type: text/css; charset=UTF-8");
?>
そして、CSSファイルの末尾に次のコードを記述すれば完了だ。
<?php
HTTP_Compress::output();
?>
Compression Check(Port80 Software)で確認すると、しっかり圧縮転送されていることが分かる。

ファイルサイズは70.0%もカットされ、転送速度は3.2倍となった。
CSSを用いる際に<meta http-equiv="Content-Style-Type" content="text/css" />という記述をhead要素に含めることがある。これは.htaccessにHeader set Content-Style-Type: "text/css"と記述しても等価だが、実際にはContent-Style-Typeそのものが不要であると分かった。
私がよくお世話になったflyson氏のXHTML リファレンス(WEB ARCHIVES[http://fls.moo.jp/]; 閉鎖)では、Content-Style-TypeについてSTYLE や style 属性 などのイベントハンドラで使用するスタイルシートを指定します。
という解説がなされていた。つまり、style要素型やstyle属性を用いる場合に指定する必要があり、外部スタイルシートのみを使用する分には不要なのである。
<link rel="stylesheet" type="text/css" media="screen,projection" href="/rhongomyniad.css" />
外部スタイルシートを使用する際は、以上の指定(type="text/css")で十分だ。
Content-Style-Typeを一切指定しない状態でCSSファイルをリクエストすると、次のHTTPレスポンスヘッダが得られた。

サーバの設定によるが、CSSファイルのContent-Typeはtext/cssとなっている。HTTPレスポンスヘッダの取得にはProxomitronを利用した。
Content-Style-Typeについては前々から気になっていたものの、いつしか忘れてしまっていた。たまたまリダイレクト時のHTTPレスポンスヘッダを見ていて思い出したため、.htaccessからContent-Style-Typeの記述を取り除くにいたる。