画像を使わずCSSだけで任意の間隔の破線を描く

2014-02-28 (lastmod: 2023-01-05) /Development #CSS 150 users

cssで破線を使おうと思ったらdotteddashedの2種類しか用意されていないので、それ以外の間隔の破線を使用したい場合にはあらかじめ白黒のgif画像を用意して、背景に繰り返して使用する事が多いです。

しかしCSS3のlinear-gradientを使用すれば任意の間隔の破線を描画する事が可能です。

CSS3を使用するので対応ブラウザがちょっと狭くなりますが 1 2 、画像を用意するのとくらべて線分や間隔の調整も容易になりますし、Retinaディスプレイにも対応する事を考えたら(奇数の破線を使用する場合など)2種類の画像を用意する手間が省けますのでCSSで描画する方が楽チンです。

手順

やり方は下記の4つの指定をすれば良いだけです。

  1. 破線の部分はbackground-imageを使用して背景画像として描画します
  2. 縞模様はlinear-gradientを使用してグラデーションの濃淡で表現します
  3. color-stopsを使用して線分と間隔の開始と終了の位置をそれぞれ設定します
  4. 最後に縞模様1ブロック分をbackground-sizeで区切ります

SassとCompassを使用するとこんな感じで4行で指定できます。

コピーしました
.dotted
  +background-image(linear-gradient(left, color-stops(#000, #000 50%, transparent 50%, transparent 100%)))
  background-size: 2px 2px
  height: 1px

color-stopsの部分を調整すれば破線の間隔を変更する事が可能です。px指定も勿論可能です。

破線の場合は色をつける部分とつけない部分の2色なのでcolor-stopsの指定がそんなに面倒では無いです。線分の終了位置と余白の開始位置を同じに設定すれば境目はグラデーションにならずに綺麗に描画されます。間隔の部分は透過させるのでtransparentで区切っておきます。

Mixin作った

Sassを使っているので、使い回しがきくようにMixinにしておきました。

コピーしました
=dotted($color:rgba(#000, 1.0), $stripe: 1, $spacing: 4, $height:1)
  +background-image(linear-gradient(left, color-stops($color, $color ($stripe/($stripe+$spacing))*100%, transparent ($stripe/($stripe+$spacing))*100%, transparent 100%)))
  background-size: ($stripe+$spacing)*1px ($stripe+$spacing)*1px
  height: $height*1px
  border: none

呼び出す時には+dotted(色, 線分, 間隔, 高さ)で呼び出すだけなので簡単に使用できます。

コピーしました
.dotted
  +dotted(#000, 1, 1)
コピーしました
%hr.dotted

斜線もできそう

repeating-linear-gradientを使用すると斜線もできるようなので、ちょっと試してみました。

codepenで斜線バージョンも見る

コピーしました
@import compass

=shaded($deg:135deg, $color:rgba(#000, 1.0), $stripe: 1, $spacing: 7, $height:12px)
  $_stripe: $stripe
  $_spacing: $spacing
  $_diagonal: ceil(($_stripe+$_spacing)*1.414)
  $_pattern: $deg, $color, $color ($_stripe)*1px, transparent ($_stripe)*1px, transparent ($_diagonal)*1px, $color ($_diagonal)*1px
  background-image: -webkit-repeating-linear-gradient($_pattern)
  background-image: -moz-repeating-linear-gradient($_pattern)
  background-image: -o-repeating-linear-gradient($_pattern)
  background-image: -ms-repeating-linear-gradient($_pattern)
  background-image: repeating-linear-gradient($_pattern)
  background-size: (($_stripe+$_spacing)*2)*1px (($_stripe+$_spacing)*2)*1px
  height: $height

hr
  border: none
  margin-top: 30px

.shaded
  +shaded(135deg, #000, 1, 1, 10px)

.shaded--2
  +shaded(45deg, #000, 1, 4, 10px)

.shaded--3
  +shaded(135deg, #000, 1, 6, 10px)

.shaded--2alt
  +shaded(45deg, #000, 5, 1, 10px)

.shaded--3alt
  +shaded(135deg, #000, 10, 1, 10px)
コピーしました
%hr.shaded
%hr.shaded--2
%hr.shaded--3
%hr.shaded--2alt
%hr.shaded--3alt

錯視みたいですね。

辛うじて表示できているように見えますが、入力している値によってはたまにズレが出てしまいます・・・

  1. linear-gradientを使用するので古いIEでは表示ができません。対応していないブラウザ用にはbackgroundで普通に背景色を指定しておくと良いかと思います。
  2. https://caniuse.com/?search=linear-gradient IEも10から対応しているので↑の対応はもういらなさそう…

追記

  • 23-01-05 追記: ダークモードで見えなくなっていた箇所を修正
  • 23-01-05 追記: footnotesの2つめを追加
Comment
comments powered by Disqus
Profile

石原 悠 / Yu Ishihara

デザインとプログラミングと編み物とヨーグルトが好きです。