CSSだけで要素に行番号を強引に付ける
前からはてなブログなどの<pre>
なんかで使いたいと思ってました。
結果、こんな感じで作れました。
See the Pen Line number by nju33 (@nju33) on CodePen.
詳しくは続きから。
<pre>
では次のプロパティが重要です。
position: reltive
とすることで行番号を配置する基準位置を、この<pre>
の左上に設定しています。
padding
では行番号と重ならないに、左側に3em
の余白を取っています。
.pre { /* 略 */ position: relative; padding: 1em 1em 1em 3em; }
行番号は、擬似要素:before
を内側へ作成しそこへ記述します。
上で見せたCODEPENのモノはSassで書いていてちょっと違いますが、アレをCSSで書くとこうなります。
.pre:before { content: " 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20"; display: block; height: 86%; width: 2em; position: absolute; left: 0; word-wrap: break-word; overflow: hidden; }
まず、content
へ行番号となる数値の文字列を書きます。
width: 2em
とword-wrap: break-word
によってcontent
を数値ごとに改行させて表示させます。
:before
はインライン要素なのでそのままではwidth
を設定できません。display: block
でブロック要素にします。
これで数値の文字列を縦に並ばすことができました。次に、適切な位置に配置させます。
position: absolute
とleft: 0
で、<pre>
で設定した基準位置の一番左側へ行番号を配置します。
最後に、height
で行番号の高さを調整します。
今回のコードでは<pre>
で下にpadding
をかけた結果、height: 100%
では12行目まで表示されるようになってしまいました。「うわ、なんか下にだけ余白がない感じになってる・・・」ってことで、最後の一行分がはみ出るよう高さを調整。はみ出た行番号は、overflow
で隠すことで下にもちゃんとpadding
が設定されてるようにできました。
CODEPENの例では、content
の文字列を書くのは面倒たったので、SassのMixinを使い作成しています。コレを使えば、999までは1~999まで手打ちするとかいう面倒なことはせずに済みます!(すんごい長いコードになりそうですが)
=line-number($num) $result: " 1" $pre: "" @for $i from 2 through $num $pre: "" @if $i < 10 $pre: " " @else if $i < 100 $pre: " " $result: $result + "#{$pre}#{$i}" content: $result // +line-number(20)
行間や色、背景色はお好みで設定です。