Skip to content

Instantly share code, notes, and snippets.

@sivartravis
Created September 19, 2017 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sivartravis/95ef25dfbe0707c0191b2db34601f764 to your computer and use it in GitHub Desktop.
Save sivartravis/95ef25dfbe0707c0191b2db34601f764 to your computer and use it in GitHub Desktop.
Side Notes
<article>
<header>
<h1>Side Notes</h1>
<p>Automatic side notes for links (showing their titles) and footnote texts.</p>
</header>
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> elit. Aut animi consequatur odit natus suscipit eligendi modi reiciendis quod hic minus id architecto facilis odio earum aliquid
voluptas ipsum, explicabo aperiam! Lorem <a href="https://google.com/" title="Doloremque inventore minima">ipsum dolor sit</a> amet, consectetur adipisicing elit. Doloremque inventore minima voluptatum magnam laborum tempore possimus rerum corporis
ipsum quasi qui quos, quae, perspiciatis fuga, labore voluptates quas at. Nisi.</p>
<p>Aut animi consequatur odit<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> natus suscipit eligendi modi reiciendis<sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> quod hic minus id architecto facilis odio earum
aliquid voluptas ipsum, explicabo aperiam!</p>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut animi consequatur odit natus suscipit eligendi <a href="http://pascalhertleif.de/" title="Lorem ipsum dolor">modi reiciendis quod</a> hic minus id architecto facilis odio earum aliquid
voluptas ipsum, explicabo aperiam!</p>
<h2>Adipisicing Elit</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Aut animi consequatur odit natus suscipit eligendi modi reiciendis quod hic minus id architecto facilis odio earum aliquid voluptas ipsum, explicabo aperiam! Lorem ipsum dolor sit amet, consectetur
<a href="https://medium.com/@killercup" title="Adipisicing et.al.">adipisicing</a> elit. Eaque veritatis quasi cupiditate dicta tempore sapiente quas eos excepturi et, quo facilis amet. Nam voluptates facilis vero, repellendus architecto alias explicabo.</p>
<p>Quia, ab excepturi laudantium, rerum earum voluptates accusantium atque vero, aliquam inventore eaque, aperiam sapiente. <a href="https://twitter.com/killercup" title="Illuminati">Illum</a>, animi, accusantium! Ratione blanditiis corrupti officia.</p>
<hr class="footnotes-sep" />
<section class="footnotes">
<ol class="footnotes-list">
<li id="fn1" class="footnote-item">
<p>Expedita est, perferendis, quidem iusto, ipsam, quia repellendus architecto ullam sapiente tenetur odio. <a href="#fnref1" class="footnote-backref">↩</a></p>
</li>
<li id="fn2" class="footnote-item">
<p>Fugiat vero perferendis iure qui voluptates natus odio nulla. Nisi corrupti, laborum fuga reiciendis optio, tempore maiores culpa porro. <a href="#fnref2" class="footnote-backref">↩</a></p>
</li>
<li id="fn3" class="footnote-item">
<p>Ea praesentium, harum, eos quibusdam omnis earum temporibus? <a href="#fnref3" class="footnote-backref">↩</a></p>
</li>
</ol>
</section>
</div>
</article>
// This expects a modern browser, but does not require any libraries. (Yes, it does not use jQuery.)
// Enable some array methods for results of DOM selectors:
NodeList.prototype.__proto__ = Array.prototype;
function addSidenotes(content) {
const footnotesConverted = content.querySelectorAll('.footnote-ref > a')
.map(function convertFootnoteToSidenote(ref) {
const footnote = document.querySelectorAll(ref.getAttribute('href'))[0];
if (!footnote) { return; }
ref.parentNode.insertAdjacentHTML('afterend',`<span class="sidenote">
<span class="sidenote-number">${ref.textContent}</span>
${footnote.innerHTML}
</span>`);
return 1;
})
.filter((x) => !!x).length;
const linksConverted = content.querySelectorAll('a[title]')
.map(function convertLinkToSidenote(link) {
if (link.href[0] === '#') { return; }
if (link.matches('.sidenote a')) { return; }
const title = link.getAttribute('title');
const hostname = link.hostname;
link.insertAdjacentHTML('afterend', `<span class="sidenote">
<span class="sidenote-title">${title}</span> &ndash;
<a href="${link.href}">${hostname}</a>
</span>`);
return 1;
})
.filter((x) => !!x).length;
if (0 < (footnotesConverted + linksConverted)) {
content.classList.add('has-sidenotes');
}
}
document.querySelectorAll('article .content').map(addSidenotes);

Side Notes

Automatic side notes for links (showing their titles) and footnote texts.

A Pen by Pascal on CodePen.

License.

// Side notes stuff begin at `.sidenote` selector. Scroll down!
html, body {
font-size: 16px;
}
@mixin clearfix {
*zoom: 1;
&:before, &:after {
display: table;
content: "";
}
&:after {
clear: both;
}
}
a {
color: #666;
text-decoration: underline;
&:hover {
color: #000;
background-color: yellow;
}
}
article {
font-family: Georgia, serif;
font-size: 1rem;
line-height: 1.5;
color: #222;
}
.footnote-ref {
// disable onum (Oldstyle Figures)
font-feature-settings: "kern" 1, "liga" 1, "calt" 1, "pnum" 1, "tnum" 0, "onum" 0, "lnum" 0, "dlig" 0, "sups" 0;
a {
text-decoration: none;
}
}
// - - -
// Important stuff begins here!
// - - -
$sidenote-spacing: 0.6em;
$sidenote-color: #666 !default;
$footnote-font: "Helvetica", sans-serif;
$footnote-font-size: 0.65rem;
$footnote-line-height: 1.6;
.sidenote {
// First, disable all this stuff on small devices
display: none;
padding-bottom: $sidenote-spacing;
font-family: $footnote-font;
font-size: $footnote-font-size;
line-height: $footnote-line-height;
color: $sidenote-color;
.footnote-backref {
display: none;
}
.sidenote-title {
&:before {
$rarr: "\2192";
$nbsp: "\00a0";
content: "#{$rarr}";
margin-right: $sidenote-spacing;
font-weight: bold;
}
}
.sidenote-number {
margin-right: $sidenote-spacing;
display: inline-block;
float: left;
font-weight: bold;
}
p {
margin-top: 0;
margin-bottom: 0;
& + p {
margin-top: $sidenote-spacing / 2;
}
}
}
header, .content {
max-width: 32em;
padding: 1em;
margin-left: auto;
margin-right: auto;
}
.content.has-sidenotes {
a, .footnote-ref {
&:hover + .sidenote {
.sidenote-title:before,
.sidenote-number {
background-color: yellow;
}
}
}
}
@media screen and (min-width: 45em) {
$article-with-sidenotes-with: 60em;
$article-width: 70%;
$gutter: 5%;
/**
* Layout:
*
* | ------------------------------------ | | ---------------- |
* | lorem ipsum dolor .................. | | side note ...... |
* | ------------------------------------ | | ---------------- |
*
* based on the sizes:
*
* | ----- $article-width --------------- | | - $side-width -- |
* $gutter --^
*
* where `$side` and $gutter are in percent relative to `$article-width`, but
* only `$article-width` and `$gutter` are given.
*/
$side-width: ((100% - $article-width) * 100% / $article-width);
.content.has-sidenotes {
max-width: $article-with-sidenotes-with;
@include clearfix();
> *:not(.sidenote) {
width: $article-width;
box-sizing: border-box;
}
.sidenote {
display: block;
float: right;
clear: right;
margin-right: -1 * $side-width;
width: $side-width - $gutter;
vertical-align: baseline;
position: relative;
}
.footnotes,
.footnotes-sep {
display: none;
}
}
}
<link href="https://cdn.rawgit.com/kennethormandy/normalize-opentype.css/a8f85affbcf7978622edf0b34c38a1968add9fe6/normalize-opentype.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment