CSSを使ったボタンデザイン

category-icon

 こんにちは。日本にいるのと同じ感覚で、職場の自分の机上にアップル社のiPhoneGを置いていたらいつの間にか盗まれていたmartinです。まだ購入して2ヶ月も経ってなかったと思うけどなぁ。こちらでは、たとえ自分のデスクに置いていても、それが貴重品であれば「どうぞご自由に持っていって下さいませ」ということになるらしい。おかげ様で、今ではトイレに行く際にも、いちいちノートパソコンを隠すようにしています。人を見たら泥棒と思えなんて実践したくはないけど、この国ではしょうがないです。愚痴ったところで、正式版で実装予定のボタンのデザインについてメモしておきます。最終的に目指すのは以下のようなボタンです。

 ppBlogのベータ版1.7.3では、Ajax向けのコメント展開ボタンやコメントフォーム表示ボタンをAタグとSPANタグとを組み合わせて、いわゆるSliding doors Link と呼ばれるよく知られたテクニックを用いて実現していました。

 参考サイト

バージョン1.6までは、素直にBUTTONタグを使っていたんですが、これだとデザイン上の制約があるなぁ、と思ってました。各種ブラウザでBUTTONタグに対するpaddingの解釈も違うしなぁというのもあって。でも、デザインに関してこれらの点はクリアできることが分かりました。個人的に、BUTTONタグを使う際にデザイン上のネックであった点を挙げてみると、

  1. IEで、ボタン内のテキスト左右に指定を無視したパディングが取られること。
  2. Firefoxで、BUTTON要素内に入れたSPAN要素周りのパディング(マージン?)をなくすことが出来ない。

で、これの回避方法が分からなかったというのもあり、A要素とSPANとを用いていたんですが、解決しました。まず、1番目の実例から。以下のような記述の実際例を下に挙げます。スクリーンショットのように、IEではボタンが横長(縦方向もですが)になり、パディングの指定を無視してるのが分かります。(注:以下に挙げるサンプルは、インライン指定になってますが、これはあくまで説明のためで、最終的にはクラス指定などを用いたスタイルシート指定になります

<button style="padding: 0;">山のフドウ</button> /* パディングをゼロに */ 
shot1
左がFirefox、右がIE7。

 では、このIEでのパディングをなくすにはどうすれば良いか? ググればいくらか出てきますが(この辺Link を参考に)、結論から言えば、以下のようにoverflow: visible;を追加すれば良いです。IE8では廃止が予定されている悪名高きhasLayoutLink 絡みだとは思いますが・・・。この方式では、この指定によって他のブラウザが影響を受けないのがグーです。

<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だと下の部分にパディングが現れるかもしれません(下に赤いラインが入る)。

shot2
左から順にFirefox2.0x、IE7、Opera9.27、Safari3.1.1

 珍しく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タグの黄色の背景色と黒い文字しか見えないはずです。これでオッケーですね。

うん? ちょっと待ったぁー(ねるとん紅鯨団Link 風に)。フロートをかませば確かにいいけど、ボタンをセンタリングとかしたいときってどうするの? うーん、確かにフロートを使用すると、この辺りの扱いが難しくなります。フロートを使わないで出来るやり方はないのか? ちゃんとあります。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は、これらでも完璧にはならないけど、まぁいいか。前置きが長くなりましたが、こうやってパディングやマージンの指定がきちんと効くやり方(最初はゼロを指定してそれがきちんと適用されるか)を抑えておけば、後は、それを弄るのは簡単です。次のページで、背景画像を利用したボタン効果を見ることにします。と、思いましたが、疲れたのはとりあえず今日はここまで。デモページへのリンクを貼っておきます。

 http://p2b.jp/demo/cute-buttons.htmlLink

 

— posted by martin at 07:05 pm   commentComment [12]  pingTrackBack [0]

この記事に対するコメント・トラックバック [12件]

scrollUp1. BENIT — 2008/05/03@15:15:36

iPhoneご愁傷様です……(++!)


いつの間にかeditor.jsから、blockquote要素を挿入するときにp要素が併せて入る処理がなくなりましたが、これは仕様ですか?

Owner Comment martin Website  2008/05/04@22:06:34

こんにちは。仕様というか、BLOCKQUOTEの入れ子には色々解釈があるようなので、まぁ何もしないのが良いかなと思ったんだと思います、自分もいつ頃そうしたか把握していませんが・・・。最近の動向を見てから正式版に反映させようと思います。

3. BENIT — 2008/05/04@22:53:28

>色々解釈
なるほどなるほど。
まあどの道、今までのログがあるので、P要素含めての指定を考えておかないといけないんですけどねf(--;

ちなみに、最新版の配布はいつ頃になりそうですか?
ボタンがこのように変わるとなると、CSSをいじらなきゃなー、ということで最新版がかなり気になってます(笑

Owner Comment martin Website  2008/05/05@00:17:21

いやぁ、まぁいつでも良いのですけどね、最近は大きなバグの報告もないようですし。来週中(ウィークデーに)と答えておきます。

5. ぷらむ — 2008/05/05@19:13:55

先ほど、テスト・サイトで、カテゴリを削除しましたら、親カテゴリは削除できたが、子カテゴリでは削除できませんでした。子カテゴリ名が消えませんでした。確認だけお願いします。(すぐ手動でファイルからカテゴリ名を消しましたので、ログのほうはどうだったか、確認しませんでした。)

scrollUpOwner Comment martin Website  2008/05/09@23:11:26

 確かにそうなりました。PHPの処理的に、ちょっと納得がいかない部分があるのですが、うまく行くようにしました。

7. BENIT — 2008/05/05@21:22:32

>Weekday
了解です。とりあえず現行で完成させることにします。

少しだけ気になったのですが、「最新10件のコメント」にも「New」が付くのは、その中に設定時間内のコメントがあるからでしょうか?

Owner Comment martin Website  2008/05/09@23:05:51

 こんにちは。あまり考えたことはありませんが、まぁそうですね。これが気になるようでしたら、index.phpの138行目あたりを、

$p = '最新'.(ENTRY_BOX * 2).'件のコメント'; $new = '';

みたくすればOKかなと思います。

9. BENIT — 2008/05/06@12:27:35

ページ作成画面のローカルプレビューが付いたので大分作るのが楽になったと思うのですが、それについての提案です。

ページのローカルプレビュー時に、div#preViewAreaにclass="page-box"かあるいは順ずるページプレビュー用のクラスを設定するか、#preViewArea内にdiv.page-boxを生成するというのはいかがでしょうか。

ページ用の指定は実質page-boxクラスを元に指定することが多いと思うので、よりローカルプレビューの精度を上げやすくなるかと思います。(現行でも#preViewAreaに対して指定をすれば問題ないと言えばないのですが、エントリのローカルプレビューと干渉してしまうので……)


>サブカテが削除できない
私も確認しました。iniファイルの方にも残ったままですね。

Owner Comment martin Website  2008/05/09@23:09:32

ページ作成の方は、page-boxというクラス名を予め入れ子にするようにしました。カテゴリー、ようやく昨日見てみました。直しました。

scrollUp11. BENIT — 2008/05/10@11:43:12

対応感謝です。

ブログバー、久しぶりに使ってみようかなとテーマに組み込んでみたのですが、これって定期的に生成しなおす必要がありますよね?
そうなると、生成しなおすときに前回の入力値を覚えていてくれないために生成しなおすのが若干面倒になるかと予想されるので、入力値を覚えてくれていると便利かと思います。(特に色とか…)

それと、テーマの削除が出来なくなっているようでした(「Ajax is not defined」というJSエラーが出てます。)

Owner Comment martin Website  2008/05/10@23:16:33

 あれっ、ブログバーは、色とかサイズとかはクッキーに食わせる処理をしているのですが、動いてないですかね。こちらのテスト環境ではちゃんと覚えてくれてるようです。
 テーマは、これまた古い記述が残ってましたね・・・。一応、総検索を掛けて、残骸はないと思っていたんですが、助かりました。ありがとうございました。

[追記]
クッキー処理は、期限の指定が抜けてました。なので、仕様上ブラウザを閉じると消えちゃいますね。このサイトのやつを試して「あれっ?」と思いました。これは長めに設定しておきます。

この記事に対する TrackBack URL:

設定によりTB元のページに、こちらの記事への言及(この記事へのリンク)がなければ、TB受付不可となりますのであらかじめご了承下さい。

コメントをどうぞ。 名前(ペンネーム)と画像認証のひらがな4文字は必須で、ウェブサイトURLはオプションです。

ウェブサイト (U):

タグは使えません。http://・・・ は自動的にリンク表示となります

:) :D 8-) ;-) :P :E :o :( (TT) ):T (--) (++!) ?;w) (-o-) (**!) ;v) f(--; :B l_P~

     
T: Y: ALL: Online:
Created in 0.0219 sec.
prev
2017.2
next
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28