添加旁注

𖭀 

总之就是偶然看到 tufte.css 实现了正文 sidenote 的效果,想怎么着也给自己整一个。

tufte.css 的美丽旁注样式

旁注或者说 侧注、Annotations、Marginalia,这几个词各有细微的差别应包含以下几个关键信息:

  • 注释应该在原文位置留有「指针」,用以标记分支点便于读者阅读旁注后回溯。
  • 旁注内容,一般出现在与指针同进度的正文之外。
  • 指针与内容的关联。无论使用连线样式亦或相同的数字,目标都是将指针和旁注内容联系起来。

研究了一下 tufte.css其实就是f12,他在正文中使用 lable 来包裹指针,用 label[for] 实现语义上的关联关系,然后新增了个 span.sidenote 来放旁注内容,先不说这符不符合语义化,这么多种带 attr 的 tag 就明显不适合俺们这种 markdown 作者:我不想在写 md 的时候多写这么多语法,我也记不住。

那就考虑自己实现一份。


从最终使用角度出发,我肯定是想只用加一个 tag 包裹就能将上面三种信息全部录入完成的。理论上也可以:tag 的位置就是 1,tag 包裹的内容就是 2,tag 在 html 流中的位置就是 3。

在语义化的 html tag 选择上:aside 可能和原有的 html 结构重复,导致 css 崩坏;figcaption 还需要 figure 包裹才能符合其「多媒体文件标题」的含义;最终选择了 cite 标签参见 mdn: 引用标签作为包裹标记。

所幸我们能在 hexo 中直接引入 html tag:

前文
<cite>旁注内容[引用标签](https://...)hexo也支持嵌套其他语法</cite>
后文

这时,hexo 渲染出来的 html 长这样:

<p>
  前文
  <cite>
    旁注内容
    <a target="_blank" rel="noopener" href="https://...">引用标签</a>
    hexo也支持嵌套其他语法
  </cite>
  后文
</p>

虽说可以指定 tag 书写 css 了,但只要我们将 cite 脱离文本流,原标签的位置属性便无法再次获取,如果 css 能提供一个「在脱离位置标记/新增」的功能都可以完成该目的,可惜没有。

那没得太多可以说的,就考虑再新增一个元素:

前文
<cite><i>旁注内容</i></cite>
后文

hexo 渲染出来的 html 长这样:

<p>
  前文
  <cite>
    <i>旁注内容</i>
  </cite>
  后文
</p>

这样就好办了,闭着眼或许你还需要了解 css counter就能写出:

body {
  counter-reset: sidenote-counter;
}

cite {
  position: relative;
  counter-increment: sidenote-counter;
  i {
    float: right;
    clear: right;
    margin-right: -50%;
    width: 50%;
    position: relative;
  }
  i::before,
  &::before {
    content: counter(sidenote-counter) " ";
  }
}

然后可以在 hover 的时候 blink 一下,这样方便找到对应数字:

cite:hover {
  &::before,
  i::before {
    animation: blink 2s forwards;
  }
}
@keyframes blink {
  10%,
  30% {
    opacity: 0.4;
  }
  0%,
  20%,
  40%,
  to {
    opacity: 1;
  }
}

为了适配不同尺寸的屏幕,当然会有那么一些些补充这里使用了 css :has 进行包含特定内容的父元素反选,意为「包含旁注的文章container」

.main-ctnr:has(cite) {
  left: calc(50% - 537px); // 如果有旁注,container 就往左移动一些
}

@media screen and (max-width: 1050px) { // 但如果页面宽度小于1050px
  .main-ctnr:has(cite) {
    left: calc(50% - 375px); // 屏幕太窄,那就不用挪 container 了
  }
  cite {
    i {
      float: none;        // 因为我不仅仅将旁注放回了原文
      clear: none;
    }
    &::before {
      display: none;     // 还隐藏了数字
    }
    i::before {
      content: " (";     // 然后还在前后加上了括号
    }
    i::after {
      content: ") ";
    }
  }
}

就是这样!本博也拥有美丽的旁注了。这东西还挺适合咱这种在讲故事的过程中才想起来没有提前补充故事背景的人。