LoginSignup
12
13

More than 5 years have passed since last update.

CSSでコードブロックの行番号を表示する

Posted at

Qiita APIから取得した投稿内容を自分のサイトに表示するときコードブロックに行番号を表示させたかったので、JavaScriptを使わず実装する方法を考えた。

APIで取得した内容の一部
<div class="code-frame" data-lang="JavaScript">
<div class="code-lang"><span class="bold">app.js</span></div>
<div class="highlight"><pre><span></span>  <span class="k">for</span><span class="p">(</span><span class="kd">let</span> <span class="nx">url</span> <span class="k">of</span> <span class="nx">urls</span><span class="p">){</span>
    <span class="nx">await</span> <span class="nx">chromy</span><span class="p">.</span><span class="kr">goto</span><span class="p">(</span><span class="nx">url</span><span class="p">)</span>
<span class="line-numbers-rows"><span></span><span></span></span></pre></div>
</div>

目標

  • pre要素の左側に行番号を表示
  • コードをコピーする時に邪魔にならない
  • できればJavaScriptは使いたくない

イメージは下記URLの通り。
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters

実装方法

HTML

HTML
<pre>
    # 1行目
    # 2行目
    # 3行目
    <div class="line-numbers"><span></span><span></span><span></span></div>
</pre>

pre要素の中なので改行や空白がそのまま表示されるので注意。
<div class="line-numbers">内に行数分だけ<span></span>を設置する。あまりスマートでは無いのでJavaScriptかテンプレートエンジンで行数分ループするのがよさそう

Pythonだとこんな感じ
print('<div class="line-numbers">'+'<span></span>'*3+'<div>')

CSS

CSS
pre {
    position: relative;
    padding: 20px 50px;
}

.line-numbers {
    position: absolute;
    top: 0;
    left: 0;
    padding: 20px 5px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    border-right: 1px solid #999;
    width: 50px;
}

.line-numbers > span {
    float: left;
    display: block;
    counter-increment: linenumber;
    text-align: right;
    width: 100%;
}

.line-numbers > span::after {
    content: counter(linenumber);
}

JavaScriptを使わずに行番号を加算していくのにCSS countersを使って実装した。
counter-increment: linenumber;でlinenumber変数を加算して疑似要素の::afterの中にcontent: counter(linenumber);で表示させる。

表示結果

コード全体

index.html
<html>
<body>


<pre>
    <span># 1行目</span>
    <span># 2行目</span>
    <span># 3行目</span>
    <div class="line-numbers"><span></span><span></span><span></span></div>
</pre>


<style>
body{
    margin:50px;
    background:#ddd;
}
pre {
    position: relative;
    padding: 20px 50px;
}

.line-numbers {
    position: absolute;
    top: 0;
    left: 0;
    padding: 20px 5px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    border-right: 1px solid #999;
    width: 50px;
}

.line-numbers > span {
    float: left;
    display: block;
    counter-increment: linenumber;
    text-align: right;
    width: 100%;
}

.line-numbers > span::after {
    content: counter(linenumber);
}
</style>


</body>
</html>
12
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
13