背景画像の上にテキストボックスを配置する時、下図のように枠線(border)を半透明にしたい場合があります。

上図のように枠線を透過させ、背景をじわりと見せるテクニックです。
主にサイトのヘッダーやサムネイル、広告などに使われることが多いと思います。
しかし、枠線の部分(border)のみ透明にする…となると意外と一筋縄ではいかなったり。
そこで今回は要素全体を透明化させずに、borderのみCSSで透明にする方法を解説します。
もくじ
1.opacityでborderを半透明にする時の問題点
まず、以下のコードのように背景画像を指定した親要素(background_box)内に、テキスト用の子要素(main_content)を配置しているシチュエーションで解説を進めたいと思います。
|
1 2 3 4 5 |
<div class="background_box"> <div class="main_content"> <p>New<br>York<br>City</p> </div> </div> |
一応CSSでは、以下のように親要素のど真ん中に子要素が乗っかるようなスタイルを適用してみます(※本題とは関係ありませんが)。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
div.background_box { /* 背景画像を指定している親要素 */ width: 500px; height: 300px; background-image: url("./sample.jpg"); background-size: cover; position: relative; } div.main_content { /* テキストを配置するための子要素 */ width: 200px; height: 200px; background: #4d0000; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); border: 15px solid #800000; /* borderのみ半透明にしたい */ } |
現時点での表示は以下のような感じです。

これから赤い枠線を透過させ、親ブロックの背景画像(background_box)がうっすらと見えるようにしてみます。
ちなみにCSSの透明化と言えば、真っ先に思いつくのはopacityプロパティです。
しかし、opacityにはborderを透明化するうえで一つ問題があります。
というのも、opacityは要素全体を透明にできますが、要素のうち「枠線(border)のみ」適用させる…といった細かい調整ができないからです。
例えば、以下のようにテキストを配置している子要素にopacityを追加してみましょう。
|
1 2 3 4 5 6 7 8 9 10 11 |
div.main_content { width: 200px; height: 200px; background: #4d0000; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); border: 15px solid #800000; opacity: 0.7; } |
結果を見ればわかるとおり、borderだけでなく内側のテキストまで透過されてしまっています。

これでは、透明度を上げれば上げるほどテキストが読みづらくなってしまいます。
では、枠線だけ透明にするには、どうしたら良いのでしょうか?
2.rgbaを使ってもborderの半透明が効かない?
要素全体を透明にしてしまうopacityの代わりに、個々のプロパティをrgba()で指定する方法があります。
CSSでは、色を指定する際に#ff0000やredなどの値が用いられることが多いですが、rgba()なら色と同時に透明度を指定することが可能です。
例えば以下のコードのように、borderで色を指定する箇所をrgba()に書き換えることができます。
|
1 2 3 4 5 6 7 8 9 10 |
div.main_content { width: 200px; height: 200px; background: #4d0000; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); border: 15px solid rgba(128,0,0,0.7); /* #880000 ⇒ rgba(128,0,0,0.7)に変更*/ } |
これで問題が解決するかと思いきや、表示上、特に変化が見られません。

厳密には、rgba()はきちんと機能しており、元の色よりもやや薄くなっているはずです。
しかし、背景画像の街並みはまったく透けて見えません。
これは、枠線(border)のすぐ背後が自要素の背景色(background: #4d0000)だからです。
つまり透けて見えるのは、親要素の背景画像ではなく自要素の背景色ということです。
この場合、自要素のbackgroundもrgba()に書き換え、背景色を透過させてしまうのも一つの手です。
|
1 2 3 4 5 6 7 8 9 10 |
div.main_content { width: 200px; height: 200px; background: rgba(77,0,0,0.7); /* #4d0000⇒rgba(77,0,0,0.7)に変更 */ position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); border: 15px solid rgba(128,0,0,0.7); } |
こうすると、枠線もうっすら街並みが透けて見えるようになります。

これはこれでお洒落な感じがしますが、正確には半透明な背景色を、さらに枠線が透過している構図なので、枠線が直接背景画像を透過している訳ではありません。
では、当初の目的である「枠線(border)」のみ透明にすることはCSSでは不可能なのでしょうか?
3.borderを半透明にするにはbackground-cripを調整する必要あり
前章では、border-colorの値をrgba()で書き換えることで透明化には成功したものの、自要素の背景色が邪魔をして、親要素の背景画像を透過できませんでした。
しかし、この問題はbackground-cripプロパティを追加することで解決します。
background-cripを使えば、要素に指定された背景色(あるいは背景画像)の領域を調節することができます。
background-cripの値は、主に以下の3パータンです。
| 値 | 解説 |
|---|---|
| border-box | borderまで背景を広げる(←これがデフォルト) |
| padding-box | paddingまで背景を広げる |
| content-box | paddingの内側まで背景を広げる |
background-clipのデフォルト値はborder-boxです。
つまり、枠線を透明にしても親要素を透過しなかったのは、background-clipがデフォルト値のままだったためです。
では、background-clipを調整し、borderの内側まで自要素の背景領域を狭めてみましょう。
|
1 2 3 4 5 6 7 8 9 10 11 |
div.main_content { width: 200px; height: 200px; background: #4d0000; background-clip: padding-box; position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); border: 15px solid rgba(128,0,0,0.7); } |
今回はborderのみ透明にしたいので、background-clipをpadding-boxに指定します。

無事、自要素のうち枠線(border)のみ透明にすることができました。
4.完全に透明にするには?transparentで一発
ここまでborderを半透明にし、親要素を透過するテクニックを解説しました。
では、半透明ではなく完全に透明にするには、どうしたら良いのでしょう?
例えば、先に紹介したrgba()を使うなら、カンマで区切った最後の値を0にすれば、完全に透明にできます。
border: 15px solid rgba(255,255,255,0);
また、以下のようにborderを透明にするための値も用意されていたりします。
border: 15px solid transparent;
色コードの代わりにtransparentを指定することで、表示上borderが完全に見えなくなります。
とは言え、それならそもそもborder: noneと変わらないのでは?と思うかもしれませんが、transparentの場合はborderが占める領域は残ります。
そのため「イベント処理でborderのON/OFFを切り替えたい」「今まで枠線を設けていたけど不要になった」等といった場面で、ページのレイアウトを崩さずにborderを非表示にすることができます。
まとめ
今回は、枠線(border)をCSSで半透明・透明にする方法をご紹介しました。
「枠線のみ」透明にする方法は、要素全体を透明にするよりも少し工程が増えますが、テクニックをマスターしてしまえば簡単です。
最後に、この記事のポイントをまとめておきたいと思います。
opacityは要素全体を透明にするが、枠線だけ透明にできない- 枠線だけ透明にするなら、
borderの色をrgba()で指定しよう - 親要素を透過したい場合は、自要素の背景領域(
background-crip)を枠線の内側(padding-box)まで狭める必要がある。 - 枠線を完全に透明にしたい場合は、
borderにtransparentを指定しよう



