CSSで角を丸めたい - Nifty Corners

CSSで角を丸くする、が気持ち悪い

画像抜き、CSSで角を丸めるNifty Cornersについて断片的な感想を。ことの発端は以下を読んだことから。画像を使わずにCSSだけでブロックの4つの角を丸めようというワザです。おおむね評判が良いらしいのですが・・・・・・

私、第一感で気持ち悪いと思ったのですが、その理由をきちんと表現できる能力があるわけでもなし。上記文献に批判的な以下を読んで勉強してみました。

以上を読んでもなお、釈然としません。私が気持ち悪いと思っていることってなんだろう?と思うわけです。これらの批判的文書の大部分は頷けるのです。しかしこちらはこちらで、どこか変に感じるのです。適宜覚書: 角を丸めたいのは分かるが(3)での、ということで、「自分が使うかと言われれば使う気にはなれないが、バッドノウハウとしてb要素をspan要素に変えDOMで適用するならそれはそれでアリだろう。」というあたりでオチとしたい。、という意見にも首を傾げるのです。また、Nifty Cornersについて考える - 徒書での、元記事であるNifty CornersはWeb標準についても配慮しており、最終的には、HTMLに余計なマークアップを加えることをせず、角を丸くするのに必要な要素はクライアントサイド(ブラウザ側)でDOM(Javascript)を用いて加えるという手法をとっています。、という分析にもすぐには首肯できないのですよね。

こうやって書いているうちに頭が整理されることってよくあるわけでして。なんとか自分なりの言葉が出てくるかな?

気持ち悪さの理由

HTMLは文書のコンテンツとその論理的構造を記述するもので、見栄えなどの装飾や表現方法はCSSにまかせ、論理構造と表現方法の分離を行う、というのが基本的で真っ当な考え方だと思うのですよね。スタイルシートの基本 -- ごく簡単なHTMLの説明 -- The Web KANZAKIをあらためて読み直して復習してみました。良く出来た文書というのは、この分離がきちんと出来ていることだと思います。

しかるに、Nifty Corners: rounded corners without imagesでは、この分離原則が守られていないのです。それゆえにカッコワルイ、気持ち悪い、と私は感じたようです。角を丸めるだけの為に、文書のコンテンツやその論理構造に、本来不要な余計な要素を多量にHTMLに追加しているのですね。色々な意見もあるかと思うのですが、私としては気持ち悪い。htmllintで100点をとろうがなんだろうが気持ち悪い。(htmllintでは100点を取れないと思いますが試していません。)たかだかスタイルシートの都合の為にHTMLを汚すな、ということなのですね。

したがって、Nifty Corners: rounded corners without imagesにおいて、気軽に意味も無くb要素を追加しているからこそ気持ち悪い、という立場を私は取りません。b要素をspan要素やdiv要素に置き換えたところで気持ちよくなるわけではないのです。たかだかスタイルのために余計なものをつっこむなよ、という点ではなんら変わらないからです。

もうひとつ、釈然としないのですが、Nifty Corners: rounded corners without imagesでは、ブラウザで閲覧する前のHTMLソースがW3Cの標準でValidだというところを長所として自賛しています。私に言わせれば、DHTMLでDOMをいじくっているのですから、変更後のDOMレベルでValidであるべき、と思います。当然、b要素をガチャガチャつっこむのは反則だと考えます。ソースレベルでValidを叫んでもそこから後でムチャなことをするわけですから、絶対駄目なのです。

JavaScriptでDOMをいじくろうが最初からHTMLソース上にあろうが、どちらにせよ、コンテンツの論理的構造を破壊してでも特定のスタイルシートを適用したい、というのはどうなのかなぁ、ということになります。気持ち悪さの理由はこれでした。画像を使っていないから素敵だとか、その反対に画像を使えばいいじゃん、ということではないのです。

角を丸くする手法は流行るかも

危険なような気がしますが、この角を丸くする手法は流行る可能性があります。流行る理由としては、徹底的に汎用化を図っているからなのです。あまり深く考えずとも提供されているJavaScriptのライブラリからonLoadで適当な関数を呼び出せば終わりだからです。やけに簡単。きっとあちらこちらのTIPS紹介ページで孫引きされ初心者はとびつくでしょう。「画像を使っていませんよ、かっこいいでしょう」という妙な優越感で。CSSとHTMLの分離の精神を学ぶことなく適当にコードを書いておしまいなのです。そうやって学んだ人々がやがてプロのIT産業のプログラム担当やSEになるかと思うと暗澹とした気持ちになります。言い過ぎですか。ごめんなさい。だいたいこんな大それたことを喋っている私はHTMLもCSSもほとんど何も書けません。苦手です。エラそうに言うのは100万年早いのかもしれませんね。

画像を使っていても駄目な角の丸め方

画像を使おうが使わまいが駄目な場合があるという事例をご紹介して私のつたない意見を補強することを試みます。まずは、IEFirefoxで一見適切に表示される、角の丸め方をご紹介します。不思議なことにOperaでは壊れているようなのですが理由は不明です。Operaファンの人はメーカーに連絡してあげて下さい。)23日追記:186(Quirky) - to id:hoshikuzu:20050321にて綺麗な図表で解説を頂きました。186様、ありがとうございます。大元のスタイルシートに不備があった模様です。追記終り:まずは以下のURLを参照願います。角は4個あるのに画像を1個しか使っていない点は確かにトリッキーだと思います。

上のURLの文書にとって、そのコンテンツの論理的な構造は以下のようなものだと考えられます。

<h1>CSS is so cool</h1><hr>
Simply use this image to make a round-corner block 以下長いので略。

既に間違っているような気もしますが本件と無関係なので無視することとしましょう。

さて、意見も分かれようかと思いますが、私は以下のようなものまでは論理的構造としてギリギリ許容出来るのです。ケースにもよりますけれど。例えば、コンテンツのメニュー部分、ヘッダー部分、フッター部分、メイン部分、といった形でdiv要素でグループ化し、分かち書きした時には意味のあるdiv要素として認めることが出来ます。はてなダイアリーのソースでもそういったdiv要素が登場しています。

<div class="RB">

<h1>CSS is so cool</h1><hr>
Simply use this image to make a round-corner block 

</div>

さて、このブロックに画像を援用しつつスタイルシートで4つの角を丸める表現を与えることが出来るかといえば、CCS1やCCS2では不可能だと思います。ですので、無理やりな手法をとってトリッキーなdiv要素を追加してしまうことになります。

<div class="RoundCorner">
<div class="RC1"></div>
<div class="RC2"></div>
<div class="RC3"></div>
<div class="RC4"></div>
<div class="RB">
<h1>CSS is so cool</h1><hr>
Simply use this image to make a round-corner block 

</div>
</div>

特に空っぽな4つの要素<div class="RC*"></div>等の追加は末期的な誤りだと思います。角の修飾に使っているのでしょうけれど、文書のコンテンツの論理的な構造とは全く無関係になってしまっています。このようなトリックはスタイルシートの都合でHTML構造を歪めるといった意味で反則だと考えています。後から追加されたdiv要素が静的なHTMLとしてあらかじめ記述されていようが、あとからDHTML的にDOMをいじくって追加されようが駄目なものは駄目なのです。

余談ですが私はスタイルシートを書き下す能力はないのですけれど、上記の<div class="RC*"></div>でもって、なにゆえ<div class="RB">のブロックに対する修飾が可能なのかサッパリわかりません。カスケードしてないじゃん、とか思いますがいかがでしょう?ブラウザのバグじゃぁないのでしょうか?わかりやすい説明がどこかにありませんかねぇ>識者さん達23日追記:186(Quirky) - to id:hoshikuzu:20050321にて綺麗な図表で解説を頂きました。186様、ありがとうございます。私の頭の中がバグでした。収容ボックスについて大幅に勘違いをしておりました。

以上の意見は、全くもって、そのまま、Nifty Corners: rounded corners without imagesにも言えることなのです。単純にブロックコンテナがあった場合にその4つの角を全て丸める汎用の手法はCSS2までの範疇では不可能、ありえない、だからあきらめましょう、というのが私の本音です。なにかしら歪みが出てきてしまいますよ、と。

許される角の丸め

私はどんなケースでも駄目だと言っているわけではありません。ブロックコンテナの2個の角を丸めることは制限付きになりますがありえると思っています。私にとって、これならOKだという例を紹介しておきたいと思います。

はてなテーマ別によるスタイルシートサンプル(『Cassis』)をごらん頂きたく思います。(素晴らしいサンプル集を提供して下さっているid:Jehoshaphatさんに感謝申し上げます。)角を綺麗に丸くしています。どういう仕組みなのかをごく簡単に説明を試みます。はてなダイアリーのHTMLを視覚的に説明した画像がありますので説明のために使います。はてなダイアリーガイド「CSSセレクタ - 日記1日分」を併せてご覧下さい。

テーマ『Cassis』では、日記1日分のブロック、div.dayがあり、その中にさらにブロック群があって、その一番先頭がh2要素のブロックです。日付等のヘディングとして使われています。本来不可能な日付1日分のブロックの4つの角を丸める代わりに、『Cassis』では、まずh2要素の上部に横長の蒲鉾型の画像を背景に埋めこんで取り敢えず角を2個丸めてしまいます。さらにdiv.dayの背景画像としてdiv.dayの下側の2個の角を丸めたように見せる逆蒲鉾型の画像を配置しています。そのほかにも微調整の工夫がなされていることかと思います。

ちょっと注意書きですが、『Cassis』の例ではいっぺんに2個ずつの角を1個の蒲鉾画像で丸めていますので、ブロックの横幅(width)は固定となっています。この制限はちょっとキツイかもしれませんね。場合によっては許容できないケースも出てくるかもしれません。

さて、ここで私が駄目駄目だと宣言した悪いケースと、この『Cassis』とを比べます。何故私は『Cassis』ならばOKと言うのでしょうか。それは単純な理由によるのです。はてなダイアリーガイド「CSSセレクタ - 日記1日分」を見てわかる、もともと存在している、はてなダイアリーのHTML構造(ブロックコンテナ群)にスタイルシートを適用しているからOKなのです。悪い例では、角を丸める為に本来存在していないブロックや要素をトリッキーに追加していますが、『Cassis』ではそのような変なマネはしていません。目の付け所がシャープでトリッキーさを感じるとしたら、それは、h2要素とdiv.dayとで分業して画像を使うことでしょうか。(HTMLとCSSについて本当に詳しい人ならば、あるいは、この手法でも欠点があると、あるいは仰るかもしれません。そうであるならば私の不勉強です。申し訳ありません。)

またもや余談なのですが。先にご紹介した、http://www.hedgerwow.com/BLOG/RC/rc.htm では、横幅の固定を必要としていません。なんらかの方法で『Cassis』の方法が横幅フリーになることがありえないかとちょっと考えて見たのですが非力な私には無理でした。とほほ。

美麗な角の丸め

もう一つ、美麗な例です。

ソースの一部は以下のようなものです。ごく簡単で普通なマークアップです。これにスタイルシートで飾り付けをして角を丸くしているのですね。美麗。但し例によって横幅固定ですけれど、宿命かもしれません。

<dl>
    <dt>Mt. Everest</dt>
    <dd>The tallest mountain peak in the world.</dd>
    <dd>29,035 feet</dd>
</dl>

<dl id="blue">
    <dt>Mt. Everest</dt>
    <dd>The tallest mountain peak in the world.</dd>
    <dd>29,035 feet</dd>
</dl>

サンプルを見ていただいていますのでわかると思いますが色指定は簡単に変更可能になっています。但し、body要素など親の背景色は簡単に変えられないようです。背景色ごとに蒲鉾画像をひとつ用意すれば、後はdl要素の色は簡単に複数指定ができるようになっています。

原理は、先のはてなの『Cassis』と同根ですね。dlで最下部の蒲鉾を、dtで最上部の蒲鉾を指定しています。特徴は蒲鉾画像の作り方なんですね。こういう手法がdl要素ばかりでなく汎用で作れればいいのですが、そうは簡単にはいかないと思います。

以下は発展系です。極めて美麗ですね。シンプルなHTML構造とシンプルなスタイルシートです。美麗さにあこがれるあまりに、まさかとか思いますけれど、角を丸める為だけにHTMLの記述の一部分をdl要素でわざわざ書く人はいませんよね(笑)。まずは正しくマークアップしてこそのスタイルシートですのでお間違いのないように。そんな間違いする人はいないと思いますけれどね。

まとまりませんが

角を丸める手法は多種多様、あります。画像の有無で注目を浴びているNifty Cornersですが、目くらましです。画像の有無は本質ではありません。Nifty Cornersは、優れた汎用性を持っていますが、(DOMレベルで)HTMLを汚染せざるを得ませんので推奨できません。HTMLとCSSの役割の分離の原則に抵触しているからです。逆に言えば、HTMLとCSSの役割分離に違反しているからこその汎用性です。HTMLの汚染無しに角を丸められるケースは一般的なものではなく特殊なケースとなります。

その汎用性のゆえにNifty Cornersが流行したり、CSSの優れた事例として紹介されたりとすることが今後予想されますが、残念なことです。

今後、進化したブラウザにCSS3が実装されていくなかで、無理やりに角を丸める変則的なスタイルシートは滅んでいくと思いますが、たとえ現時点の暫定措置であってもNifty Cornersやその亜種は使わない方が良いでしょう。