読者です 読者をやめる 読者になる 読者になる

latest log

酩酊状態で書いたエンジニアポエムです。酩酊状態で読んでください。

CSS3 の border-image で簡単にリッチなボタンを作れる未来がいつの間にかきてた

画像を使ってリッチでフレキシブルに伸び縮みするボタンやフレームを作る時みなさんはどうしているでしょうか。

従来の方法だと

  1. デザイナーさんが画像を9分割
  2. マークアップで頑張って再現する

というハードワークを強いられていましたが、
昨今のモバイル開発環境では、それ、もう要らない苦労らしいですよ。

CSS3 の border-image を使うと、9 slice(9 patch)を CSS だけで実現可能です。

用意するものは、9つに分割する前のボタン画像です。

f:id:uupaa:20120711120516p:plain

画像を用意したら、http://border-image.com のジェネレーターを使い border-image 用のCSSを生成します。
f:id:uupaa:20120711213617p:plain

-webkit-border-image: url(img/btn.9.png) 27 24 30 25 round;

とすると、

Android Browser 2.3.3
f:id:uupaa:20120711123010p:plain

iPhone 4S (iOS 5.1.1)
f:id:uupaa:20120711122307p:plain

のように表示されます*1

人によっては2~4時間ぐらいショートカットできるとおもいます。ぜひ使ってみるべきかと。

(ε・◇・)з ただし IE はダメで、IE 10 でも非対応らしいぞ。
(ε・◇・)з IE 爆発しないかな…


(ε・◇・)з 9 patch用の画像のファイル名を {{ファイル名}}.9.png とかにするのは android 的流儀らしいよ

資料

http://caniuse.com/#search=border-image ブラウザ毎の対応状況
http://www.w3.org/TR/css3-background/#the-border-image W3Cの仕様

<!DOCTYPE html><html><head><meta charset="UTF-8"><title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<style>
.btn {
    position: absolute;
    left: 20px;
    top: 20px;
    width: 120px;
    height: 40px;
    line-height: 20px;
    font-weight: bold;
    font-size: 24pt;
    text-shadow: 1px 1px 1px white;
    color: #333;
    text-align: center;
    border-width: 15px 15px;
    -webkit-border-image: url(img/btn.9.png) 27 24 30 25 round;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
</style>
</head><body>

<div class="btn">9 patched</div>

</body></html>

Chrome, Android Browser, Mobile Safari で共通して取得可能なスタイルは "WebKitBorderImage" だけです。
"WebKitBorderImageSource" などを個別に取得したいところですが、それはもうちょっと未来のお話になるようです。頑張って文字列を切り出しましょう。

var btn = document.querySelector(".btn");

var style = window.getComputedStyle(btn);

alert(style.WebKitBorderImage);
// -> "url(http://.../img/btn.9.png) 27 24 30 25 round round" (Android 4.0.1)
// -> "ulr(http://.../img/btn.9.png) 27 24 30 25 fill / 1 / 0px round" (Mobile Safari (iOS 5.1.1) )
// -> "ulr(http://.../img/btn.9.png) 27 24 30 25 fill / 1 / 0px round" (Chrome dev 22.0.1201.0 dev-m)
// -> "ulr(http://.../img/btn.9.png) 27 24 30 25 fill / 1 / 0px round" (Chrome for Android beta 2)

追記

Android で 1px の線がなかなか消せずに困っています。

background-color:#EFB03B;
border-radius:10px;

のように背景色とボタンの角丸に合わせてborder-radiusを設定すると多少緩和されますが、対策方法としては不十分なようです。

どなたか上手い方法を発明しましたら、ぜひボクにも教えて下さい。

*1:android で余計な線が出てる…