CSSで枠線(border)を透明・半透明にするには?透明化できない原因と対策
2021/04/06
2021/05/17
背景画像の上にテキストボックスを配置する時、下図のように枠線(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
を指定しよう