remarkのfootnoteを無理やり連番対応した話 snippets 1/29/2019 ポエム 力技

remarkのfootnoteを無理やり連番対応した話

まとめ

  • このコミット みてください
  • よいエンジニアの皆さんは、プラグインを探したり、作ったりしましょう、 remark ならそれができます

背景

このサイト を最近、Contentful Nuxt.js の構成に変えています。

その際、Markdown表示に remark を使いました。

このremarkでは、footnoteがオプションで用意されていますが this_is_footnote、以前のVuePressに比べて利便性が悪くなっていたので、手を加えました。

何が課題だったか

remarkで、footnoteはオプションを渡してあげると使うことができますが、この状態では課題が3つありました。 (1つは解決していません)

      return remark()
        .data('settings', { footnotes: true })
        .use(html)
        .processSync(this.markdown).contents

参照がテキストになっている。連番がいい

これthis がデフォルトでは、以下のように表示されてしまいます。

this

この様になってしまっても、下のfootnoteには、その文字列は書いてありません。 これでは、複数のfootnoteがあったときに対応がわからなくなるかもしれません。

これは問題なので、下のfootnoteにあわせて連番にしたいと思います。

アンカーリンクでは、遷移先が最上部になるので、Headerの分隠れてしまう

footnoteと参照部の往来は、リンクで行います。どちらにもidが付与されているわけです。 しかし、このサイトでは、StickyするHeaderが存在しているため、通常のリンクで遷移してしまうと、参照先が見えなくなってしまいます。

スクロール位置をちょっとだけ下にしたいですよね。

上下の行き来が面倒 (未解決)

純粋にfootnoteの上下の行き来が面倒ですよね。

PCのユーザには、hoverすることで中身を見られるようにしたいですが、HTMLを触るのが面倒なのでやっていません。

力技 (CSS) で解決しよう

CSS で連番対応

CSSの counter-increment を使います。MDN を見てください。MDNに勝るドキュメントはありません。 CSSでカウンタがあつかえる。いい時代です。

.md {
  counter-reset: number;

  .footnote-ref {
    counter-increment: number;
    &:before {
      content: '[' counter(number) ']';
    }
  }      
}

これを使って、.fotnote-ref の出現ごとにカウンタを1増やし、連番を付与することができました。

このようになります。 that

あとちょっとです。

あとは、邪魔な文字列を消してしまいましょう。

.md {
  counter-reset: number;

  .footnote-ref {
    position: relative;
    left: -10000px;
    display: inline-block;
    width: 1rem;
    counter-increment: number;
    opacity: 1;

    &:before {
      position: relative;
      left: 10000px;
      content: '[' counter(number) ']';
    }
  }
}

浮かせて画面外に持っていきます。パワープレーです。 これで問題解決です。

CSS で見かけ上の位置をずらす

察しのいい皆様なら、おわかりですね。 先程、cssを使って、本来の文字列を左に飛ばしました。

これを、左上に飛ばすことでリンク先をいい感じに調整することができます。 アイディアは複数の問題を解決するのですね。(他の問題を生み出しているのは許して)

.md {
  counter-reset: number;

  .footnote-ref {
    position: relative;
    top: -200px;
    left: -1000px;
    display: inline-block;
    width: 1.8rem;
    color: transparent;
    counter-increment: number;
    opacity: 1;

    &:before {
      position: relative;
      top: 200px;
      left: 1000px;
      margin: 0 0.2rem;
      font-size: $large-font-size;
      font-weight: bold;
      color: $DARK_SKY;
      content: '[' counter(number) ']';
    }
  }
}

今回は、 top の調整を行いました。これで一件落着です。

ポエム

CSSは本当に力強くて、筋の悪い解決策を導いてくれます。 多くの実行環境、利用ユーザーがいる中で、力技はできればするべきではないですし、 アクセシビリティなどを考えると良いものかどうかはわかりませんね。

しかしながら、JavaScriptを書かなくても、この程度のことならできてしまうというのは学びです。

では。


  1. footnoteはこれです。
  2. ←を見ればわかるようにもとの文字列はわからないのです