CSSのborderの点線はlinear-gradientかSVGを使おう

CSSのborderの点線は見た目が悪い

Webサイトで下線に点線を描画する際はCSSのborder-styleのdashedかdottedを使用している人が多いが、border-styleだと点線がきれいに描画されない。

例えばCSSのborderでdashedで点線を描画した場合は以下のようになる。

.bdr1 {
  border-bottom: 10px dashed blue;
}

点線のサンプル

Chromeだと点線がきれいに描画されていると思うが、Safariだと下図のように点線の長さや感覚が不均一で描画されてしまうため、汚い見た目になってしまう。

border-bottom: 10px dashed blue;
border-bottom: 10px dashed blue;

また、Chromeではきれいに描画されているが、点線の横幅と間隔はCSSのborder-styleのdashedでは変えることができないため、デザイナーなどが正方形で等間隔の点線のデザインを作成した場合はborderでは同じ見た目にすることができない。

linear-gradientで点線描画

前述の問題はlinear-gradientを使用すれば解決できる。

要素の背景にbackground-image: linear-gradientで点線描画する関係上、padding-bottomも必要。

.bdr2 {
  padding-bottom: 10px;
  background-image: linear-gradient(to right, #00f, #00f 10px, transparent 10px, transparent 20px);
  background-repeat: repeat-x;
  background-position: left bottom;
  background-size: 20px 10px;
}

点線のサンプル

linear-gradientを使用する方法だと複雑な形や位置の点線には対応できないため、linear-gradientで実装できない点線の場合は次に説明するSVGを使用した方法を使用する。

SVGで点線描画

まず点線に使用するSVGをテキストエディタで作成する。

<svg width="20" height="10" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <rect x="0" y="0" width="10" height="10" fill="blue" />
</svg>

これをs.svgなどの適当なファイル名で保存してbackgroundで背景画像として読み込んで点線を以下のように表示させる。

.bdr3 {
  padding-bottom: 10px;
  background: url(s.svg) repeat-x left bottom;
}

点線のサンプル

SVGはCSS内にインラインで直接書くこともできる。

.bdr4 {
  padding-bottom: 10px;
  background: url("data:image/svg+xml;utf8,<svg width='20' height='10' version='1.1' xmlns='http://www.w3.org/2000/svg'><rect x='0' y='0' width='10' height='10' fill='blue' /></svg>") repeat-x left bottom;
}

点線のサンプル

上下左右が点線の場合はborderが自然

上下左右の点線をlinear-gradientやSVGで描画することもできるが、要素が可変であればborderのほうが等間隔にはできないが自然な仕上がりになる。

.bdr5 {
  height: 100px;
  padding: 10px;
  box-sizing: border-box;
  background: red;
  background-image: linear-gradient(to right, #00f, #00f 10px, transparent 10px, transparent 20px),
                    linear-gradient(to bottom, transparent, transparent 10px, #00f 10px, #00f 20px),
                    linear-gradient(to left, #00f, #00f 10px, transparent 10px, transparent 20px),
                    linear-gradient(to top, transparent, transparent 10px, #00f 10px, #00f 20px);
  background-repeat: repeat-x, repeat-y, repeat-x, repeat-y;
  background-position: left top, right top, left bottom, left top;
  background-size: 20px 10px, 10px 20px, 20px 10px, 10px 20px;
}

この範囲に
点線を追加

.bdr6 {
  height: 100px;
  padding: 10px;
  border: 5px dashed blue;
  box-sizing: border-box;
  background: red;
}

この範囲に
点線を追加

円形のドット描画ならSVG

円形のドット描画ならborderのdottedよりもSVGのほうがサイズや間隔を細かく調整できるので適している。

.brd7 {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  background-color: red;
  background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 100 100' version='1.1' xmlns='http://www.w3.org/2000/svg'><circle cx='50' cy='50' r='45' stroke='%23fff' stroke-width='5' stroke-dasharray='0 10.5' stroke-linecap='round' fill='transparent' /></svg>");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}

ちなみにborder: 10px dotted #fff;で描画すると始点と終点がくっついて見栄えが悪くなってしまう。

※ 追記: 現在はGoogle Chromeが修正されて、くっつかずに描画されます👍

さらに円形の内側にドットを表示させるためにdivを内側に追加する必要があるのでタグが増えてしまう。

.brd8 {
  width: 200px;
  height: 200px;
  padding: 10px;
  border-radius: 50%;
  background-color: red;
}
.brd8 > div {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  border-radius: 50%;
  border: 10px dotted #fff;
}

iOSとiPadOSはdottedが丸くまらない

Safari、iOS、iPadOSはdottedが丸くならないため、border-styleをdottedで指定するのは避けたほうが良いだろう。

iOSとiPadOSはdottedが丸くまらない
iOSとiPadOSはdottedが丸くまらない
カテゴリーcss