-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
The Drupal displacement API sets --drupal-displace-offset-top to an empty string "" for anonymous users, not undefined. This breaks CSS var() fallbacks in calc() expressions, causing fixed headers to overlap content.
Steps to reproduce
- Enable "Fixed Header on Mobile" in theme settings
- Log out (view as anonymous user)
- Visit any page on mobile viewport
- Observe the fixed header overlaps page content
Example Project
Reproducible on any DXPR Theme installation with fixed header enabled.
What is the current bug behavior?
For anonymous users, body padding is 0px instead of the header height. The CSS rule matches but produces invalid CSS:
calc(40px + "") → invalid → ignored → 0px
What is the expected correct behavior?
Body should have padding-top equal to the header height (e.g., 40px) to prevent fixed header from overlapping content.
Relevant logs and/or screenshots
DevTools evidence:
| User Type | --drupal-displace-offset-top |
Body Padding |
|---|---|---|
| Anonymous | "" (empty string) |
0px ❌ |
| Admin | "83px" |
40px ✓ |
Screenshots: https://github.com/dxpr/dxpr_theme/tree/pr-760-review-screenshots/pr-760-screenshots
Possible fixes
All calc() usages with displacement API variables:
| File | Line | Code | Selector Context | Status |
|---|---|---|---|---|
scss/components/dxpr-theme-header--mobile.scss |
290 | calc(var(--dxt-setting-header-mobile-height) + var(--drupal-displace-offset-top, 0)) |
&:has(#navbar.header-mobile-fixed) |
❌ BROKEN |
scss/components/dxpr-theme-header--top.scss |
53 | calc(var(--drupal-displace-offset-top, 0) + 30px) |
&.dxpr-theme-header--overlay |
❌ BROKEN |
features/sooper-header/header-theme-settings-css.inc |
70 | calc($header_top_height_var + var(--drupal-displace-offset-top, 0px)) |
.body--dxpr-theme-nav-desktop.body--dxpr-theme-header-fixed |
❌ BROKEN |
scss/components/dxpr-theme-header--mobile.scss |
280 | calc(var(--drupal-displace-offset-top, 0) - 1px) |
&.gin--vertical-toolbar, &.gin--horizontal-toolbar, etc. |
✓ Safe |
scss/components/dxpr-theme-header--mobile.scss |
285 | calc(var(--drupal-displace-offset-top, 0) - 6px) |
&.gin--navigation |
✓ Safe |
scss/components/dxpr-theme-header--top.scss |
329 | calc(var(--drupal-displace-offset-top, 0) - 1px) |
.gin--vertical-toolbar |
✓ Safe |
scss/components/dxpr-theme-header--top.scss |
346 | calc(var(--drupal-displace-offset-top, 0) - 1px) |
.gin--classic-toolbar, .gin--core-navigation, etc. |
✓ Safe |
scss/components/dxpr-theme-header--top.scss |
354 | calc(var(--drupal-displace-offset-top, 0) - 6px) |
.gin--navigation |
✓ Safe |
scss/base/layout.scss |
55 | calc(100vw - var(--drupal-displace-offset-left, 0)) |
body.toolbar-tray-open |
✓ Safe |
scss/dxpr-theme.admin.themesettings.scss |
34 | calc(var(--dxt-setting-header-top-height, 100px) + var(--drupal-displace-offset-top, 0px)) |
html:has(#system-theme-settings) |
✓ Safe (admin) |
scss/dxpr-theme.admin.themesettings.scss |
100 | calc(var(--drupal-displace-offset-right, 0) - var(--dxt-admin-sidebar-width)) |
#system-theme-settings |
✓ Safe (admin) |
scss/dxpr-theme.admin.themesettings.scss |
153 | calc(var(--drupal-displace-offset-right, 0) - var(--dxt-admin-sidebar-width)) |
#system-theme-settings |
✓ Safe (admin) |
scss/dxpr-theme.admin.themesettings.scss |
218 | calc(var(--drupal-displace-offset-right, 0) - var(--dxt-admin-sidebar-width)) |
#system-theme-settings |
✓ Safe (admin) |
scss/dxpr-theme.admin.themesettings.scss |
919 | calc(var(--drupal-displace-offset-top, 0px) + 80px) |
#system-theme-settings |
✓ Safe (admin) |
JS fallback exists but doesn't work:
js/dist/header/dxpr-theme-header.js:90-94 attempts to set --drupal-displace-offset-top: 0px but:
- Only runs inside
resizeevent handler, not on initial page load - Only runs when
#dxpr-theme-main-menu .navexists
Recommended fix pattern:
// Instead of calc() with displacement variable for all users:
// Split into toolbar vs non-toolbar contexts
// Anonymous/regular users - no toolbar
&:has(#navbar.header-mobile-fixed):not(.toolbar-horizontal, .toolbar-vertical, .toolbar-fixed) {
padding-top: var(--dxt-setting-header-mobile-height) !important;
}
// Admin users with toolbar - displacement API returns valid value
&:has(#navbar.header-mobile-fixed):is(.toolbar-horizontal, .toolbar-vertical, .toolbar-fixed) {
padding-top: calc(var(--dxt-setting-header-mobile-height) + var(--drupal-displace-offset-top)) !important;
}