CSSで2重線を付ける方法と注意点

CSSで2重線を付ける時、どう実現するでしょうか?
一番簡単に実装する方法としては、borderのスタイル指定で「double」を指定する事だと思います。しかし、border:doubleはちょっと癖があり、指定によってはブラウザ間で表示が異なる事があるので注意しなければいけません。

border:doubleは太さの指定によってブラウザ間での表示が異なる

検証のためサンプルhtmlを作り、いくつか指定を変えたものをキャプチャに収めました。htmlは以下の通りです。

html
<div class="border">border double テスト</div>

それでは、線の太さを指定するとブラウザでどう表示が違うのかを見ていきます。

線の太さを指定しない場合

.border {
  width: 400px;
  margin: 0 auto;
  padding: 10px;
  text-align: center;

  border: double #000;
}

これは各ブラウザ共に、問題なく表示されています。ブラウザによりフォントレンダリングの差はありますが、概ねどれも同じと言っていいでしょう。

線の太さを4pxにした場合

.border {
  width: 400px;
  margin: 0 auto;
  padding: 10px;
  text-align: center;

  border: 4px double #000;
}

線の太さを4pxに指定すると急に様子がおかしくなります。個人的に期待する結果としては、chrome、firefoxのような表示を期待していたのですが、IE、Edgeは2重線になっているものの、線と線の間に変なグレーの色が付いてしまっています。

なお、この線の間にある色は、線の色を変更すると変化します。

幾つかの色で試してみましたが、どうも線の中間色で間が塗りつぶられるようです。
そしてSafariは2重線にすらなっていません・・・。

線の太さを8pxにした場合

.border {
  width: 400px;
  margin: 0 auto;
  padding: 10px;
  text-align: center;

  border: 8px double #000;
}

線の太さを8pxにすると、上のように各ブラウザ共に線が太くなって表示されます。ここでのブラウザ間での表示差は特に無さそうですが、IE、Edgeはphotoshopなどで拡大してみると分かるのですが、若干線が滲んでいます。

border:doubleを使わずに2重線にする方法

今まで見てきたとおりborder:doubleは手軽なものの、線の太さをによってはブラウザ間での表示が異なる場合があります。また、線自体の太さの調整が出来ず、シャープな2重線を付けることが出来ません。

そこで、border:doubleを使わずに思い通りの2重線を付ける方法をご紹介します。

box-shadowを使う

いくつか2重線を付ける方法はありますが、その中でも一番簡単な方法が「box-shadow」を使う方法です。box-shadowはカンマ区切りで複数指定できる事を利用した方法で、これを使えば思い通りの2重線(に限らず、3重線、4重線も可能)を作る事ができます。

.border {
  width: 400px;
  margin: 0 auto;
  padding: 10px;
  text-align: center;

  box-shadow: 0 0 0 1px #000, 0 0 0 19px #FFF, 0 0 0 20px #000;
}

box-shadowで複数指定すれば上のような余白の大きい2重線も作ることができます。
ただ、拡大するとfirefox、IEでちょっと線が滲んでいますね・・・。

疑似要素を使う

:before、:afterの疑似要素を使い、親要素と同じ見た目のボーダーをずらして表示するというテクニックです。

.border {
  position: relative;
  width: 400px;
  margin: 0 auto;
  padding: 10px;
  text-align: center;
  border: 1px solid #000;
}

.border:before {
  position: absolute;
  content: "";
  width: 100%;
  min-height: 100%;
  top: -10px;
  left: -10px;
  border: 1px solid #000;
  padding-bottom: 19px;
  padding-right: 19px;
}

疑似要素を使った結果です。ブラウザ間での差は特に感じることは無く、拡大してみても線の滲みなどはありません。使えるならこの方法が一番綺麗に表示できそうです。

以前よりも機能的にはブラウザ間の差は無くなってきましたが、レンダリングエンジンの違いから表示上まだ細かい差があるという事が分かりました。当たり前ですが、各種ブラウザ間での表示確認は怠らないように気をつけたいと思いました。