こんにちは。日本にいるのと同じ感覚で、職場の自分の机上にアップル社のiPhoneGを置いていたらいつの間にか盗まれていたmartinです。まだ購入して2ヶ月も経ってなかったと思うけどなぁ。こちらでは、たとえ自分のデスクに置いていても、それが貴重品であれば「どうぞご自由に持っていって下さいませ」ということになるらしい。おかげ様で、今ではトイレに行く際にも、いちいちノートパソコンを隠すようにしています。人を見たら泥棒と思えなんて実践したくはないけど、この国ではしょうがないです。愚痴ったところで、正式版で実装予定のボタンのデザインについてメモしておきます。最終的に目指すのは以下のようなボタンです。
ppBlogのベータ版1.7.3では、Ajax向けのコメント展開ボタンやコメントフォーム表示ボタンをAタグとSPANタグとを組み合わせて、いわゆるSliding doors と呼ばれるよく知られたテクニックを用いて実現していました。
参考サイト
バージョン1.6までは、素直にBUTTONタグを使っていたんですが、これだとデザイン上の制約があるなぁ、と思ってました。各種ブラウザでBUTTONタグに対するpaddingの解釈も違うしなぁというのもあって。でも、デザインに関してこれらの点はクリアできることが分かりました。個人的に、BUTTONタグを使う際にデザイン上のネックであった点を挙げてみると、
- IEで、ボタン内のテキスト左右に指定を無視したパディングが取られること。
- Firefoxで、BUTTON要素内に入れたSPAN要素周りのパディング(マージン?)をなくすことが出来ない。
で、これの回避方法が分からなかったというのもあり、A要素とSPANとを用いていたんですが、解決しました。まず、1番目の実例から。以下のような記述の実際例を下に挙げます。スクリーンショットのように、IEではボタンが横長(縦方向もですが)になり、パディングの指定を無視してるのが分かります。(注:以下に挙げるサンプルは、インライン指定になってますが、これはあくまで説明のためで、最終的にはクラス指定などを用いたスタイルシート指定になります)
<button style="padding: 0;">山のフドウ</button> /* パディングをゼロに */
では、このIEでのパディングをなくすにはどうすれば良いか? ググればいくらか出てきますが(この辺 を参考に)、結論から言えば、以下のようにoverflow: visible;を追加すれば良いです。IE8では廃止が予定されている悪名高きhasLayout 絡みだとは思いますが・・・。この方式では、この指定によって他のブラウザが影響を受けないのがグーです。
<button style="padding: 0; overflow: visible;">山のフドウ</button> /* 左右のパディングをゼロに */
2番目のネック、FirefoxでBUTTON要素の入れ子要素に余分な余白が付く件ですが、これも実例で。次のようにスタイルを指定します。期待するのは、BUTTON要素の背景色である赤が見えずに、入れ子のSPAN要素に適用した背景色の黄のみが見えることです。SPAN要素に display:block 指定をすることでSPANの高さを親要素のBUTTONの高さと一致させていることに注目。
<button style="background: red; height: 24px; border: none; margin: 0; padding: 0; overflow: visible; white-space: nowrap;"> <span style="background: yellow; height: 24px; line-height: 24px; display: block;">雲のジュウザ</span> </button>
さて、実例を見てみましょう。
少なくともFirefox2.0.0.14では(Firefox3 beta 5でも同様)、意図しない余白が左右と上に現れ、BUTTONタグの背景色の赤色が見えると思います。他のブラウザでのスクリーンショットを以下に。IE6だと下の部分にパディングが現れるかもしれません(下に赤いラインが入る)。
珍しくIE7が他のモダンなブラウザと肩を並べています で、このFirefox特有の振る舞いを回避する方法ですが、この構造(BUTTON要素にSPAN要素を入れ子にする)を維持したいのであれば、スタイルシートに以下の指定を追加します。これは色々試してようやく辿りついた方法ですが、左右の余白までは消すことは出来ません。。
button::-moz-focus-inner { border-width: 0 !important; }
どうせなら他のブラウザみたく左右の余白も消し去りたいです。ではどうするか? Sliding doorsのテクニックは使いたいので、入れ子構造は必須です。実は、簡単で、BUTTONタグの中に別の要素を入れ子するのではなく、BUTTONタグを入れ子の対象にしてやれば良いです。具体的には、以下のような感じになります。
<div style="background: red; height: 24px; margin: 0; padding: 0;"> <button style="background: yellow; height: 24px; line-height: 24px; border: none; overflow: visible;">海のリハク</button> </div>
実際のサンプルは下。DIV要素は別にP要素でも構いませんが、BUTTON要素にはブロック要素も含めることが出来るので、そんな場合はインライン要素のみを包括できるP要素では役不足になります。
おや? 余白が消えたのはいいですが、今度はBUTTONタグを囲ったDIV要素の背景色の赤が、ズラッと端まで伸びてます。これはDIVがブロックレベルの要素なので当然の振る舞いです。これを回避するには、具体的な横幅を指定するというのがありますが、長さが予め分かっていて決め打ちなら良いのですが、このブログでの使用例のように(コメント数に応じて)長さが変わることもあります。こんなときはどうするか? よくあるのはフロートを使うやり方。具体的には、DIV要素に
<div style="background: red; height: 24px; margin: 0; padding: 0; float: left;">
とfloat: left;を追加します。この修正をしたのが以下。
正しくレンダリングされていればBUTTONタグの黄色の背景色と黒い文字しか見えないはずです。これでオッケーですね。
うん? ちょっと待ったぁー(ねるとん紅鯨団 風に)。フロートをかませば確かにいいけど、ボタンをセンタリングとかしたいときってどうするの? うーん、確かにフロートを使用すると、この辺りの扱いが難しくなります。フロートを使わないで出来るやり方はないのか? ちゃんとあります。CSSには、ブロックレベルの要素をあたかもインライン要素のように扱える指定があって以下のやつです。そのまんまの名前が付いてます。
display: inline-block; /* 正当な指定。インラインブロックとして振る舞う */ display: -moz-inline-box; /* Firefox2.xは上に未対応なので独自のやつで。 */ zoom: 1; *display: inline; /* hasLayoutをかまし、さらにIEだけにinline指定。 */
何だかちょいと入り組んでます。これは説明が必要ですね。1段目は、まっとうな指定でこれに対応しているのは、Opera9.2xとSafari3x、Firefox3.x、そして条件付きでIEです。Firefox2.xは未対応ですが、独自の-moz-inline-boxで対応できます。さて「条件付きで」IEにも効くと書きましたが、これはどういうことかというと、もともとインライン要素のもの(SPANとかSTRONGとか)に対しては、これを指定するとインラインブロックとして振る舞いますが、もともとブロックレベルの要素(DIVとかPとかH3とか)に対してはこの指定は無効です(それどころか振る舞いが更におかしくなる)。ではどうするか? うまいやり方があって、IEでは、hasLayoutを有効にして、かつdisplay: inline;という指定をするとほぼdisplay: inline-block; と同じ振る舞いをします。DIV要素はもともとはhasLayoutが無効なので、zoom:1;(常にhasLayoutが有効になる)を指定します。その上でdisplay: inline;という指定をしますが、これだと他のブラウザ向けの指定を上書きしてしまうので、IEしか解釈しないように、頭にスター(*)を付けます(スターハック。IE7では効かなくなった* htmlのスターハックとは別物です)。この修正を施したものを見てみましょう。扱いづらいフロート属性はもはや不要です。
ちゃんとセンタリングも出来ますね。
以上の指定でようやく各ブラウザでの差異を吸収できて、ボタンタグを使う準備ができました。IE6は、これらでも完璧にはならないけど、まぁいいか。前置きが長くなりましたが、こうやってパディングやマージンの指定がきちんと効くやり方(最初はゼロを指定してそれがきちんと適用されるか)を抑えておけば、後は、それを弄るのは簡単です。次のページで、背景画像を利用したボタン効果を見ることにします。と、思いましたが、疲れたのはとりあえず今日はここまで。デモページへのリンクを貼っておきます。
1. BENIT — 2008/05/03@15:15:36
いつの間にかeditor.jsから、blockquote要素を挿入するときにp要素が併せて入る処理がなくなりましたが、これは仕様ですか?