如何使用 CSS 定位旁注

How to position sidenotes with CSS

我想要的

旁注。当然,最重要的问题是将它们放置在相对于引用它们的文本的高度。我可以用 JavaScript 来做到这一点,查看注释参考的 offsetTop 属性,但是我还必须处理视口调整大小和缩放,而 CSS解决方案会将其留给浏览器。因此,CSS 解决方案更可取。

背景和动机

这是博客响应式设计的一部分。如果页边空白处有足够的空间,则注释应显示为旁注;否则,它们应作为脚注出现。 This post 更详细地解释了它。请记住,超过一定宽度后,无论如何我们都会有边距,因为文本行如果要保持可读性就不能超过一定长度,所以我们也可以使用未使用的 space。 Tufte 是该解决方案的知名支持者。

我试过的

到目前为止,我已经尝试了两种方法。它们都在标记 (a <sup>) 上使用相对定位,以便能够将注释 (a <span>) 定位为相对于引用文本的顶部偏移。


我第一次尝试使用绝对定位:

article {
   width: 50%;
   margin-left: auto;
   margin-right: auto;
}

sup {
   /* Needed to position sidenotes */
   position: relative;
}

.sidenote {
   width: 20%;
   position: absolute;
   
   /* BTW: This should be proportional to the note's height,
      so as to make its vertical center align with the text
      referencing it */
   top: -100%;
}

/* How could I set the notes' horizontal position relative to the margin or to an element other than the enclosing <sup>? */
.sidenote.l {
   right: 0;
}
.sidenote.r {
   left: 15vw;
}
<article>
   <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat<sup>1<span class="sidenote r">Several variations of this sentence are known.</span></sup>. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
   </p>
</article>

这里的问题是水平定位。由于我们的引用是 <sup>,因此将边注设置在页边距附近变得很棘手。使用 JavaScript 可能可行,但每次调整视口大小时我都必须更新偏移量。不期待。

This post 提出了类似的方法,但没有显示应该将哪个父级设置为相对定位的参考。如果是 <p>,问题就来了,我们每个段落的每一面只能有一个注释,这是我宁愿避免的限制。


我的第二次尝试围绕 CSS 网格:

article {
   display: grid;
   grid-template-columns: 15% auto 15%;
}

p {
   grid-column: 2;
}

sup {
   position: relative;
}

.sidenote.l {
   grid-column: 1;
}

.sidenote.r {
   grid-column: 3;
}
<article>
   <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat<sup>1<span class="sidenote r">Several variations of this sentence are known.</span></sup>. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
   </p>
</article>

但是,似乎无法将子项(<span>)与其父项(<sup>)所属的网格列放在不同的网格列中。

您可以使用 margin 而不是 absolute 来定位旁注。

基本示例...

fiddle

article {
  width: 50%;
  margin-left: auto;
  margin-right: auto;
}

.sidenote {
  width: 20%;
  float: right;
  clear: right;
  margin-right: -33%;
}
<article>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat<sup>1</sup><span class="sidenote">Several variations of this sentence are known.</span>.
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</article>

您可以在旁注元素上使用 float: right;(使其右对齐)和等于或大于旁注本身宽度的负值 margin-right 并将移动主文本容器之外的旁注元素。浮动还确保它始终处于相关文本的高度。

(其他位置设置不用,此时可以删除)

评论后的补充:要将其向上移动以使其垂直居中,您可以在其上使用 position: relative;transform: translateY(-50%);,这应该将其向上移动其自身高度的一半。但是,出于某种原因,它向上移动了太多,所以我在代码片段中将其更改为 30% - 尝试找到适合您的值...

(但是,当它位于column/page的顶部时,这可能会导致问题)

article {
  width: 50%;
  margin-left: auto;
  margin-right: auto;
}
.sidenote {
  float: right;
  width: 20%;
  margin-right: -21%;
  position: relative;
  transform: translateY(-30%);
}
<article>
  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat<sup>1<span class="sidenote">Several variations of this sentence are known.</span></sup>.
    Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
  </p>
</article>