border-image プロパティについて

border-imageってなに?どういうときにつかうの?

今回はboder-imageについて書きます。

まずはboder-imageってそもそもなに?ということからなのですが、実例を見て紹介します。

スマホのサイトを作るとき、

f:id:ruirui_0923:20121116161129p:plain
こういったボタンをよく使うと思います。


このボタンなんですが、「戻る」以外にも「キャンセル」などにも使用したいので、background-imageで画像を設定してしまうと、言葉を入れる部分(四角部分)の長さを、自由に変えられない(入れたい言葉の長さごとのボタン画像を用意しなければいけない)ので、普通cssで記述しますよね。


でもcssだったら左側のちょぼの影が付けられなかったり、グラデーションを使いにくかったりと不便なことがあるので、

  • ちょぼは画像
  • 四角い部分はcss

というコーディングをしている方が多いと思います。


でも、それだったらボタンの種類を変えたい時に、

  • ちょぼの部分の画像を変更する
  • 四角い部分のcssの記述も変更する

という2ステップを踏まなくてはいけません。

でも、大丈夫なのです。1ステップで変更できるのです!
そうborder-imageならね。

機能そのものは

border-image-CSS3リファレンス

こちらのサイトに非常に良くまとまっています。

で、こちらのサイトが非常に便利にborder-imageを生成してくれます。
ローカルからファイルを上げても大丈夫なのでかなり便利!
f:id:ruirui_0923:20121116180026p:plain

border-image-generator


一度こちらを使ってある程度作っておいて、細かいところはエディターで修正していくのが良いのでは。

わかりにくい値

border-image-slice: fill

9等分した時に真ん中に囲まれている四角の部分をどうするか、です。
fillに設定すると、元画像の真ん中の部分が記述されてできたボックスの真ん中に、fillに設定しないと生成されたボックスの真ん中が透過されます。

border-image-repeat
  • stretch:画像がborderの領域に合うように、拡大縮小される。
  • repeat:画像がタイル状に繰り返される。タイル数が整数にならないとき、余った部分を切り捨てる。
  • round:画像がタイル状に繰り返される。タイル数が整数にならないとき、一番近い整数になるようにタイル状の画像が拡大縮小される。
  • space:画像がタイル状に繰り返される。タイル数が整数にならないとき、余った余白スペースをそれぞれのタイル間の余白として使う。


では次に、今回使ってみて躓いたところを次で見ていきます。。



躓いたところ

幅や高さがあわない

あくまで「border-image」なので、height指定やwidth指定をしてもその外側にborderがついてしまう。。よってborder-widthを指定し、それを考慮した上でした上でその要素のheight指定やwidth指定を行わなければならないということ。

つまり

.hoge {
  height: 60px;
  width: 20px;
  border-width: 10px 5px;
  border-image: url(hoge.jpg) 10 5;
}

という風に記述するとborderとその中の要素をあわせて、目に見える画像のサイズは

height: 80px;
width: 30px;

になるということだ。

t32kに聞いたらどうやらbox-sizingという便利なプロパティがあるらしい。
このプロパティの値にborder-boxを指定すると、widthとheightで指定する幅と高さがボーダーボックスに対して適用されるみたい。
なので

.hoge {
  box-sizing: border-box;
  height: 60px;
  width: 20px;
  border-width: 10px 5px;
  border-image: url(hoge.jpg) 10 5;
}

という具合に記述してあげれば、

height: 60px;
width: 20px;

のボックスができる。


border-widthとborder-image-sliceの比率関係


例えば

.hoge {
  border-width: 10px 5px 15px 10px;
  border-image: url(hoge.jpg) 10 15 30 10;
}

上記のようにコーディングしたとする。

すると、
上側と左側は元画像のとおり出力されるが、
右側は幅が1/3倍になり、
下側は高さが1/2倍になる。

そのため、右下は幅は1/3倍だが高さは1/2倍というおかしい状況になる。

今回僕がコーディングしたケースでは影などの関係から左右は1/2倍で、上下は1倍のままでというようにしたかったのだが、それをしてしまうと角丸の形が崩れてしまうためできなかった。


結局上下のsliceの位置を調節することでこの問題はクリアーできたが、なんらかの事情によりsliceの位置を変更できないときに、左下のブロックだけの幅高さの割合を指定したりする方法は現状では見つけれていないので知っている人いたら教えて下さい。

css spriteって使えるの?

border-imageはcss spriteに対応しているのかなのですが、現状では対応していないみたいです。

CSS Backgrounds and Borders Module Level 3

このサイトによると
backgroundとborder-imageは違うものですよ。
ということで別々に定義している。

なので、background-positionのようにborder-image-positionというプロパティがあればcss spliteのような機能も使えたかもしれない。
しかしborder-imageのプロパティの部分を見れば分かる通り、まだそういった機能は用意されていないのでborder-imageでがcss spriteは使えないようだ。



最後に

border-imageを使えばサイトの編集を行うときにかなり便利になるが、css spriteを使えないためonclickで画像変更を行うなどの時は、画像を1枚ずつ読み込ませないといけないので、表示速度が若干遅くなってしまう。

うーん、どっちが良いのか。。
ケース・バイ・ケースですねー。