diff --git a/assets/css/_addon/main.scss b/assets/css/_addon/main.scss index 6cbd09f84e6..8f2a690cf9b 100644 --- a/assets/css/_addon/main.scss +++ b/assets/css/_addon/main.scss @@ -671,27 +671,19 @@ kbd { margin: 0 0.3rem; } -sup { - z-index: 1; - &:target { - @extend %anchor; - z-index: 0; - } -} - .footnotes > ol { padding-left: 2rem; margin-top: 0.5rem; > li { - + li { - margin-top: 0.3rem; + &:not(:last-child) { + margin-bottom: 0.3rem; } > p { margin-left: 0.25em; margin-top: 0; margin-bottom: 0; } - &:target > p { + &:target:not([scroll-focus]), &[scroll-focus=true] > p { // [scroll-focus] added by `smooth-scroll.js` background-color: var(--footnote-target-bg); width: fit-content; -webkit-transition: background-color 1.5s ease-in-out; @@ -703,14 +695,14 @@ sup { .footnote { @at-root a#{&} { - margin: 0 0.2em; + @include ml-mr(1px); + @include pl-pr(2px); border-bottom-style: none !important; -webkit-transition: background-color 1.5s ease-in-out; /* Safari prior 6.1 */ transition: background-color 1.5s ease-in-out; } - @at-root sup:target > a#{&} { + @at-root sup:target:not([scroll-focus]), sup[scroll-focus=true] > a#{&} { // [scroll-focus] added by `smooth-scroll.js` background-color: var(--footnote-target-bg); - padding: 0 2px; } } @@ -1204,13 +1196,9 @@ img { justify-content: center!important; } - sup:target { - padding-top: 3.4rem; - } - .footnotes ol > li { padding-top: 3.5rem; - margin-top: -3.2rem !important; + margin-top: -3.2rem; &:first-child { margin-top: -3.5rem; } diff --git a/assets/js/_utils/smooth-scroll.js b/assets/js/_utils/smooth-scroll.js index 0f6316e3c30..7516212e579 100644 --- a/assets/js/_utils/smooth-scroll.js +++ b/assets/js/_utils/smooth-scroll.js @@ -13,30 +13,68 @@ $(function() { .not("[href='#0']") .click(function(event) { - if (location.pathname.replace(/^\//, "") === this.pathname.replace(/^\//, "") - && location.hostname === this.hostname) { + if (location.pathname.replace(/^\//, "") === this.pathname.replace(/^\//, "") + && location.hostname === this.hostname) { - var target = $(decodeURI(this.hash)); + const REM = 16; /* 16px */ - if (target.length) { + const hash = decodeURI(this.hash); + let isFnRef = RegExp(/^#fnref:/).test(hash); + let isFn = RegExp(/^#fn:/).test(hash); + let selector = hash.includes(":") ? hash.replace(/\:/, "\\:") : hash; + const target = $(selector); - event.preventDefault(); + if (target.length) { + event.preventDefault(); - $("html, body").animate({ - scrollTop: target.offset().top - }, 800, function() { - var $target = $(target); - $target.focus(); + if (history.pushState) { /* add hash to URL */ + history.pushState(null, null, hash); + } + + let curOffset = $(this).offset().top; + let destOffset = target.offset().top; + const scrollUp = (destOffset < curOffset); + const topbarHeight = $("#topbar-wrapper").outerHeight(); - if ($target.is(":focus")) { /* Checking if the target was focused */ - return false; - } else { - $target.attr("tabindex", "-1"); /* Adding tabindex for elements not focusable */ - $target.focus(); /* Set focus again */ + if (scrollUp && isFnRef) { + /* Avoid the top-bar covering `fnref` when scrolling up + because `fnref` has no `%anchor`(see: module.scss) style. */ + destOffset -= (topbarHeight + REM / 2); } - }); + + $("html,body").animate({ + scrollTop: destOffset + }, 800, () => { + + var $target = $(target); + $target.focus(); + + const SCROLL_MARK = "scroll-focus"; + + /* clean up old scroll mark */ + if ($(`[${ SCROLL_MARK }=true]`).length) { + $(`[${ SCROLL_MARK }=true]`).attr(SCROLL_MARK, false); + } + + /* Clean :target links */ + if ($(":target").length) { /* element that visited by the URL with hash */ + $(":target").attr(SCROLL_MARK, false); + } + + /* set scroll mark to footnotes */ + if (isFn || isFnRef) { + $target.attr(SCROLL_MARK, true); + } + + if ($target.is(":focus")) { /* Checking if the target was focused */ + return false; + } else { + $target.attr("tabindex", "-1"); /* Adding tabindex for elements not focusable */ + $target.focus(); /* Set focus again */ + } + }); + } } - } - }); /* click() */ + }); /* click() */ });