Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix header padding fouc (2nd version w/ sticky header, implemented w/ position:fixed) #1930

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/_markbind/layouts/default.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<include src="headers/header.md" />

<div id="flex-body">
<div id="content-wrapper" class="fixed-header-padding">
<div id="content-wrapper" class="sticky-header-padding">
{{ content }}
</div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions docs/_markbind/layouts/devGuide.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<include src="headers/header.md" />

<div id="flex-body">
<nav id="site-nav" class="fixed-header-padding">
<nav id="site-nav" class="sticky-header-padding">
<div class="site-nav-top">
<div class="fw-bold mb-2" style="font-size: 1.25rem;">Developer Guide</div>
</div>
Expand All @@ -27,10 +27,10 @@
</site-nav>
</div>
</nav>
<div id="content-wrapper" class="fixed-header-padding">
<div id="content-wrapper" class="sticky-header-padding">
{{ content }}
</div>
<nav id="page-nav" class="fixed-header-padding">
<nav id="page-nav" class="sticky-header-padding">
<div class="nav-component slim-scroll">
<page-nav />
</div>
Expand Down
4 changes: 3 additions & 1 deletion docs/_markbind/layouts/headers/header.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
<link rel="stylesheet" href="{{baseUrl}}/css/main.css">
</head-bottom>

<header fixed>
This is a breaking change

<header sticky>
<navbar type="dark">
<a slot="brand" href="{{baseUrl}}/index.html" title="Home" class="navbar-brand"><img src="{{baseUrl}}/images/logo-darkbackground.svg" height="20"></a>
<li><a highlight-on="exact" href="{{baseUrl}}/index.html" class="nav-link">HOME</a></li>
Expand Down
6 changes: 3 additions & 3 deletions docs/_markbind/layouts/userGuide.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<include src="headers/header.md" />

<div id="flex-body">
<nav id="site-nav" class="fixed-header-padding">
<nav id="site-nav" class="sticky-header-padding">
<div class="site-nav-top">
<div class="fw-bold mb-2" style="font-size: 1.25rem;">User Guide</div>
</div>
Expand Down Expand Up @@ -44,10 +44,10 @@
</site-nav>
</div>
</nav>
<div id="content-wrapper" class="fixed-header-padding">
<div id="content-wrapper" class="sticky-header-padding">
{{ content }}
</div>
<nav id="page-nav" class="fixed-header-padding">
<nav id="page-nav" class="sticky-header-padding">
<div class="nav-component slim-scroll">
<page-nav />
</div>
Expand Down
4 changes: 2 additions & 2 deletions docs/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ mark {
margin: 0 auto;
min-width: 0;
max-width: 1000px;
padding: 0.8rem 20px 0 20px;
padding: 0 20px;
margin-top: 0.8rem;
transition: 0.4s;
-webkit-transition: 0.4s;
}
Expand All @@ -66,7 +67,6 @@ mark {
position: sticky;
top: 0;
flex: 0 0 auto;
padding-top: 1rem;
max-width: 300px;
width: 300px;
}
Expand Down
20 changes: 10 additions & 10 deletions docs/userGuide/tweakingThePageStructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ Next, edit the layout file to your liking, and add the `{% raw %}{{ content }}{%
<link rel="stylesheet" href="{{baseUrl}}/css/main.css">
</head-bottom>

<!-- Fix the header to the top while scrolling using the fixed attribute in a <header> tag -->
<header fixed>
<!-- Create a sticky header using the sticky attribute in a <header> tag -->
<header sticky>
<navbar type="dark">
<a slot="brand" href="{{baseUrl}}/index.html" title="Home" class="navbar-brand">
<img src="{{baseUrl}}/images/logo-darkbackground.svg" height="20">
Expand All @@ -70,8 +70,8 @@ Next, edit the layout file to your liking, and add the `{% raw %}{{ content }}{%
</header>

<div id="flex-body">
<!-- Push content downward when using a fixed header with the fixed-header-padding class -->
<nav id="site-nav" class="fixed-header-padding">
<!-- Push content downward when using a sticky header with the sticky-header-padding class -->
<nav id="site-nav" class="sticky-header-padding">
<div class="site-nav-top">
<div class="fw-bold mb-2" style="font-size: 1.25rem;">User Guide</div>
</div>
Expand All @@ -87,11 +87,11 @@ Next, edit the layout file to your liking, and add the `{% raw %}{{ content }}{%
</site-nav>
</div>
</nav>
<div id="content-wrapper" class="fixed-header-padding">
<div id="content-wrapper" class="sticky-header-padding">
<!-- Insert the page's content into the layout using the {{ content }} variable -->
{{ content }}
</div>
<nav id="page-nav" class="fixed-header-padding">
<nav id="page-nav" class="sticky-header-padding">
<div class="nav-component slim-scroll">
<!-- Insert a page navigation menu using the <page-nav /> component -->
<page-nav />
Expand Down Expand Up @@ -150,16 +150,16 @@ If you wish insert scripts at the bottom, before MarkBind's scripts, simply inse

### Fixing the header to the top

Headers are commonly included inside the html `<header>` tag. In encouraging this, a convenient interface to implement <tooltip content="Headers that stick to the top of the page while scrolling the content">fixed headers</tooltip> surrounding the `<header>` tag is provided that ensures page anchors work correctly.
Headers are commonly included inside the html `<header>` tag. In encouraging this, a convenient interface to implement sticky headers using the `<header>` tag is provided that ensures page anchors work correctly.

****To fix the `<header>`****
1. Add the `fixed` attribute to your `<header>` element in the layout per the above example.
1. Add the `sticky` attribute to your `<header>` element in the layout per the above example.

2. Then, to add the necessary top padding for the main content, add the `fixed-header-padding` class to **elements that should be shifted down** in accordance with the fixed header.
2. Then, to add the necessary top padding for the main content, add the `sticky-header-padding` class to **any other elements that should be shifted down** in accordance with the sticky header.

<box type="tip" seamless>

If you are not sure where to put the `fixed-header-padding` attribute, you may also refer to the default template for `markbind init`, which already has this setup.
If you are not sure where to put the `sticky-header-padding` attribute, you may also refer to the default template for `markbind init`, which already has this setup.
</box>

---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@
<include src="headers/header.md" />

<div id="flex-body">
<nav id="site-nav" class="fixed-header-padding">
<nav id="site-nav" class="sticky-header-padding">
<div class="site-nav-top">
<div class="fw-bold mb-2" style="font-size: 1.25rem;"><markdown>## {{ layoutName or "Default Layout" }}</markdown></div>
</div>
<div class="nav-component slim-scroll">
<include src="navigation/site-nav.md" />
</div>
</nav>
<div id="content-wrapper" class="fixed-header-padding">
<div id="content-wrapper" class="sticky-header-padding">
{{ content }}
</div>
<nav id="page-nav" class="fixed-header-padding">
<nav id="page-nav" class="sticky-header-padding">
<div class="nav-component slim-scroll">
<page-nav />
</div>
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/test/functional/test_site/stylesheets/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ mark {
margin: 0 auto;
min-width: 0;
max-width: 1000px;
padding: 0.8rem 20px 0 20px;
padding: 0 20px;
margin-top: 0.8rem;
transition: 0.4s;
-webkit-transition: 0.4s;
}
Expand All @@ -66,7 +67,6 @@ mark {
position: sticky;
top: 0;
flex: 0 0 auto;
padding-top: 1rem;
max-width: 300px;
width: 300px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ mark {
margin: 0 auto;
min-width: 0;
max-width: 1000px;
padding: 0.8rem 20px 0 20px;
padding: 0 20px;
margin-top: 0.8rem;
transition: 0.4s;
-webkit-transition: 0.4s;
}
Expand All @@ -66,7 +67,6 @@ mark {
position: sticky;
top: 0;
flex: 0 0 auto;
padding-top: 1rem;
max-width: 300px;
width: 300px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ mark {
margin: 0 auto;
min-width: 0;
max-width: 1000px;
padding: 0.8rem 20px 0 20px;
padding: 0 20px;
margin-top: 0.8rem;
transition: 0.4s;
-webkit-transition: 0.4s;
}
Expand All @@ -66,7 +67,6 @@ mark {
position: sticky;
top: 0;
flex: 0 0 auto;
padding-top: 1rem;
max-width: 300px;
width: 300px;
}
Expand Down
35 changes: 30 additions & 5 deletions packages/core-web/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ function scrollToUrlAnchorHeading() {
}
}

function detectAndApplyFixedHeaderStyles() {
function detectAndApplyStickyHeaderStyles() {
jQuery(':header').each((index, heading) => {
if (heading.id) {
jQuery(heading).removeAttr('id'); // to avoid duplicated id problem
}
});

const headerSelector = jQuery('header[fixed]');
const isFixed = headerSelector.length !== 0;
if (!isFixed) {
const headerSelector = jQuery('header[sticky]');
const isSticky = headerSelector.length !== 0;
if (!isSticky) {
return;
}

Expand All @@ -49,6 +49,31 @@ function detectAndApplyFixedHeaderStyles() {
}
};

/*
Handle dynamic sticky header listener to
prevent FOUC from sudden quick movement of padding-top application.
see https://www.w3schools.com/howto/howto_js_sticky_header.asp
*/
let headerOffsetTop = headerSelector[0].offsetTop;
let isFixed = false;
const dynamicStickyHeaderListener = () => {
if (window.scrollY > headerSelector[0].offsetTop
&& !isFixed
) {
// Keep track of the offset "at the time it becomes sticky"
// still a wip
headerOffsetTop = headerSelector[0].offsetTop;
isFixed = true;
document.documentElement.style.setProperty('--header-padding', 'var(--header-height)');
document.documentElement.style.setProperty('--header-position', 'fixed');
} else if (window.scrollY <= headerOffsetTop) {
isFixed = false;
document.documentElement.style.setProperty('--header-padding', '0');
document.documentElement.style.setProperty('--header-position', 'static');
}
};
window.addEventListener('scroll', dynamicStickyHeaderListener);

let lastOffset = 0;
let lastHash = window.location.hash;
const toggleHeaderOnScroll = () => {
Expand Down Expand Up @@ -125,7 +150,7 @@ function restoreStyleTags() {
function executeAfterMountedRoutines() {
restoreStyleTags();
scrollToUrlAnchorHeading();
detectAndApplyFixedHeaderStyles();
detectAndApplyStickyHeaderStyles();
}

window.handleSiteNavClick = function (elem, useAnchor = true) {
Expand Down
21 changes: 15 additions & 6 deletions packages/core-web/src/styles/markbind.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
:root {
--header-height: 0;
--header-padding: 0;
--header-position: 'static';
}

a {
Expand Down Expand Up @@ -127,15 +129,16 @@ code.hljs.inline {

/* Header */

header[fixed] {
header[sticky] {
position: var(--header-position);
top: 0;
max-height: 100%;
position: fixed;
transition: max-height 0.6s ease-in;
width: 100%;
z-index: 1001;
}

header[fixed].hide-header {
header[sticky].hide-header {
max-height: 0;
transition: max-height 0.6s ease-out;
}
Expand All @@ -145,12 +148,18 @@ span.anchor {
top: calc(-1 * var(--header-height) - 1rem);
}

header[fixed] .nav-menu-open {
header[sticky] .nav-menu-open {
max-height: calc(-1 * var(--header-height) + 100% + 50px);
}

.fixed-header-padding {
padding-top: var(--header-height) !important;
/*
Prevent sudden quick movement of page content with the dynamically sticky header.
The padding-top property is set dynamically according to the header height in index.js.
(see https://www.w3schools.com/howto/howto_js_sticky_header.asp)
*/
.sticky-header-padding {
padding-top: var(--header-padding) !important;
transition: padding-top 0s linear !important;
}

/* #app is treated as the main container */
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/Site/siteConvertLayout.njk
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<link rel="stylesheet" href="{% raw %}{{baseUrl}}{% endraw %}/stylesheets/main.css">
</head-bottom>

<header fixed>
<header sticky>
<navbar placement="top" type="inverse">
<a slot="brand" href="{% raw %}{{baseUrl}}{% endraw %}/index.html" title="Home" class="navbar-brand">
<i class="far fa-file-image"></i>
Expand All @@ -18,7 +18,7 @@
</header>

<div id="flex-body">
<nav id="site-nav" class="fixed-header-padding">
<nav id="site-nav" class="sticky-header-padding">
<div class="site-nav-top">
<div class="fw-bold mb-2" style="font-size: 1.25rem;">Template</div>
</div>
Expand All @@ -28,10 +28,10 @@
</site-nav>
</div>
</nav>
<div id="content-wrapper" class="fixed-header-padding">
<div id="content-wrapper" class="sticky-header-padding">
{% raw %}{{ content }}{% endraw %}
</div>
<nav id="page-nav" class="fixed-header-padding">
<nav id="page-nav" class="sticky-header-padding">
<div class="nav-component slim-scroll">
<page-nav />
</div>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/html/NodeProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ class NodeProcessor {
setHeadingId(node, this.config);
}

// If a fixed header is applied to the page, generate dummy spans as anchor points
// If a sticky header is applied to the page, generate dummy spans as anchor points
if (isHeadingTag && node.attribs.id) {
cheerio(node).prepend(`<span id="${node.attribs.id}" class="anchor"></span>`);
}
Expand Down
8 changes: 4 additions & 4 deletions packages/core/template/default/_markbind/layouts/default.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<link rel="stylesheet" href="{{baseUrl}}/stylesheets/main.css">
</head-bottom>

<header fixed>
<header sticky>
<navbar type="dark">
<a slot="brand" href="{{baseUrl}}/index.html" title="Home" class="navbar-brand">Your Logo</a>
<li><a href="{{baseUrl}}/contents/topic1.html" class="nav-link">Topic 1</a></li>
Expand All @@ -20,7 +20,7 @@
</header>

<div id="flex-body">
<nav id="site-nav" class="fixed-header-padding">
<nav id="site-nav" class="sticky-header-padding">
<div class="site-nav-top">
<div class="fw-bold mb-2" style="font-size: 1.25rem;">Template</div>
</div>
Expand All @@ -35,10 +35,10 @@
</site-nav>
</div>
</nav>
<div id="content-wrapper" class="fixed-header-padding">
<div id="content-wrapper" class="sticky-header-padding">
{{ content }}
</div>
<nav id="page-nav" class="fixed-header-padding">
<nav id="page-nav" class="sticky-header-padding">
<div class="nav-component slim-scroll">
<page-nav />
</div>
Expand Down
Loading