Tthe Belgrade offcanvas navigation still reserves space for the top bar even after the page is scrolled. This creates an empty gap at the top of the offcanvas panel.

Issue fork belgrade-3576769

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

majmunbog created an issue. See original summary.

velmir_taky made their first commit to this issue’s fork.

velmir_taky’s picture

Status: Active » Needs review

The gap happens because top and margin-top on the offcanvas are always set to var(--beo-region-top-bar-height), even when the top-bar has scrolled out of view.

Added an IntersectionObserver in main.js that tracks the top-bar visibility and updates a new --beo-region-top-bar-offset variable — 3.5rem when visible, 0px when not. CSS uses it with fallback to --beo-region-top-bar-height so nothing breaks without JS.

majmunbog’s picture

Status: Needs review » Needs work

@velmir_taky Thanks for looking into this. I'm not sure, but maybe an adjustment to the padding would be a simpler approach?
In any case, --beo-region-top-bar-offset is not really the right name for the variable, we are offsetting the navigation region.

velmir_taky’s picture

Status: Needs work » Needs review

Thanks @majmunbog for the review!

Renamed --beo-region-top-bar-offset to --beo-navigation-region-offset as suggested.

Regarding padding — the issue is the offcanvas position, not its inner spacing. margin-top pushes the entire panel down, leaving a visible gap. Padding would only shift the content inside while the gap remains. The IntersectionObserver approach dynamically updates the offset based on top-bar visibility.

sumi’s picture

Status: Needs review » Needs work

Testing the MR and offcanvas panel is now jumping on scroll.

When the user scrolls with the off-canvas panel open, the panel abruptly shifts upward to occupy the space previously taken by the top bar. The repositioning is visible as a noticeable "jump" rather than a smooth transition. Same jump happens when we scroll back up to position where top bar is visible.

The off-canvas panel should adjust its position seamlessly when the top bar scrolls in and out of view, without a visible jump.

velmir_taky’s picture

Assigned: majmunbog » Unassigned
Status: Needs work » Needs review

Thanks @sumi for testing and the clear report.

The jump was caused by the IntersectionObserver with threshold: 0: it only fires when the last pixel of the top bar enters or leaves the viewport, so --beo-navigation-region-offset flipped instantly between var(--beo-region-top-bar-height) (3.5rem) and 0px. That single 3.5rem step is the visible jump — both scrolling down and back up.

Reworked the behavior to track the top bar continuously instead of as a binary state. On scroll (throttled with requestAnimationFrame) it sets the offset to the height of the top bar still visible in the viewport:

const visible = Math.min(
  Math.max(topBar.getBoundingClientRect().bottom, 0),
  topBar.offsetHeight
);
root.style.setProperty('--beo-navigation-region-offset', `${visible}px`);

Because the offset now follows the top bar's position pixel-by-pixel, the navigation region slides up in lock-step with the top bar and settles at 0px exactly when the bar is gone — no jump in either direction. The Bootstrap show/hidden handlers are no longer needed: the panel opens with whatever offset the last scroll frame set, which is already correct.

CSS/SCSS are unchanged — the var(--beo-navigation-region-offset, var(--beo-region-top-bar-height)) fallback still degrades gracefully without JS.

sumi’s picture

Status: Needs review » Needs work

Tested the latest changes in the MR and there is no longer "jump" on scroll that we had previously but now when we scroll and off-canvas moves up to take space of the top bar on the bottom of the page we are left with a gap in same size as the top-bar for which off-canvas moved up.

Off-canvas should always be full height of the screen and we should not have a gap between the off-canvas and the bottom of the page.

velmir_taky’s picture

Status: Needs work » Needs review

Fixed. The panel now stays full height - the top-bar offset is applied as padding on the content instead of margin on the panel, so no gap at top or bottom. Also gave .region-top-bar position: relative so it stays above the full-height panel. Tested across sizes + RTL.

sumi’s picture

Status: Needs review » Reviewed & tested by the community

Tested the latest changes on the MR and all is looking good.

majmunbog’s picture

Addressed a couple of issues:

  1. offcanvas-top double-offset: removed the margin-top rules from _navigation.scss (including the redundant .region-top-bar ~ & selector). Top drawer offset is now only via top in main-nav.scss.
  2. Scroll listener: listeners now attach on show.bs.offcanvas and detach on hidden.bs.offcanvas, with an immediate measure on open so the offset is correct when the top bar has already scrolled away.
  3. Frontend pipeline / source maps: ran npm run build and committed the updated css/components/main-nav.css.map and css/main.css.map (plus the compiled css/main.css cleanup from the SCSS changes).

Pushed in 09a3a82. Please re-check the pipeline and the offcanvas-top / open-after-scroll cases.

sumi’s picture

Tested the latest changes and all is good.

majmunbog’s picture

Status: Reviewed & tested by the community » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.