From e9ae85cec3b4b71860ba57e027bc612158e5cf28 Mon Sep 17 00:00:00 2001 From: Chad Lavimoniere Date: Tue, 30 Sep 2025 15:19:28 -0400 Subject: [PATCH] Fix top calculations for paneled view Many sticky elements calculate their top offset based on an assumption that they must take into account certain other sticky or fixed elements, like the performance bar, the top bar, and any admin banners. This is (happily) not true in the paneled layout, as these elements must only make themselves sticky relative to their parent panel and any sticky elements that should appear further up the page from them. This can be easily achieved by setting the CSS variables for various element heights to `0px` inside the panel, allowing for a baseline value of `0px` that will have the heights of any other sticky elements added to it. Changelog: fixed --- .../issues/show/components/app.vue | 5 +- .../framework/application-chrome.scss | 53 ++++--------------- app/assets/stylesheets/pages/issues.scss | 6 ++- 3 files changed, 17 insertions(+), 47 deletions(-) diff --git a/app/assets/javascripts/issues/show/components/app.vue b/app/assets/javascripts/issues/show/components/app.vue index 7871be7c85ecde..329842f765e40d 100644 --- a/app/assets/javascripts/issues/show/components/app.vue +++ b/app/assets/javascripts/issues/show/components/app.vue @@ -496,10 +496,7 @@ export default { }, showStickyHeader() { - // only if scrolled under the issue's title - if (this.$refs.title.$el.offsetTop < window.pageYOffset) { - this.isStickyHeaderShowing = true; - } + this.isStickyHeaderShowing = true; document.body.classList?.add(STICKY_HEADER_VISIBLE_CLASS); }, diff --git a/app/assets/stylesheets/framework/application-chrome.scss b/app/assets/stylesheets/framework/application-chrome.scss index 8e917cfe696fcc..ea6b76911e6107 100644 --- a/app/assets/stylesheets/framework/application-chrome.scss +++ b/app/assets/stylesheets/framework/application-chrome.scss @@ -183,11 +183,6 @@ } } - // Todos page sticky header - .todos-bulk-bar.is-sticky { - top: 0 !important; - } - } /* @@ -249,6 +244,17 @@ .panels-container { @apply gl-relative gl-grow gl-flex gl-pr-0 gl-pb-0; + // Inside the panels container, everything that calculates an offset from + // the top needs to ignore application header height, system header height, + // performance bar height, header height and top bar height, since these + // all lie outside of the panels. Note that the `px` IS REQUIRED here for + // these variables to function properly. + --application-header-height: 0px; // stylelint-disable-line length-zero-no-unit + --system-header-height: 0px; // stylelint-disable-line length-zero-no-unit + --performance-bar-height: 0px; // stylelint-disable-line length-zero-no-unit + --header-height: 0px; // stylelint-disable-line length-zero-no-unit + --top-bar-height: 0px; // stylelint-disable-line length-zero-no-unit + .panel-content-inner, .vue-portal-target .work-item-drawer-content { height: calc(100% - #{$header-height} - #{$gl-spacing-scale-3}); @@ -413,7 +419,6 @@ // Issue sticky header .issue-sticky-header:not(.merge-request-sticky-header) { @apply gl-w-full gl-border-b-subtle; - top: -1px !important; .work-item-sticky-header-text { @apply @xl/panel:gl-px-4 gl-py-2; @@ -428,15 +433,6 @@ } } - // Merge request sticky header wrapper - .merge-request-sticky-header-wrapper, - .merge-request-sticky-header::after, - .issue-sticky-header.merge-request-sticky-header { - @include media-breakpoint-up(md) { - top: 0 !important; - } - } - // Legacy merge request sticky header (Firefox) .issue-sticky-header.merge-request-sticky-header .issue-sticky-header-text { @apply gl-px-6 @xl/panel:gl-px-4; @@ -478,34 +474,16 @@ } } - // Sticky headers below top bar - .right-sidebar, - .issue-sticky-header:not(.merge-request-sticky-header), - .settings-sticky-header, - .rd-diff-file-header-sticky { - top: -1px !important; - } - // Sticky flash alert .flash-container:has(.gl-alert) { top: auto !important; } - // Sticky settings header - .settings-sticky-header::after { - top: 2.5rem !important; - } - // Fix drawer height .gl-drawer { height: calc(100% - #{$header-height}); } - // MR: File tree sidebar alignment - .rd-app-sidebar { - top: calc(#{$mr-sticky-header-height} + 1rem + -1px) !important; - } - // Compare revision: File tree sidebar alignment .rd-app .rd-app-sidebar { top: calc(1rem + -1px) !important; @@ -605,15 +583,6 @@ @apply gl-grow; } - // Vulnerability dashboard - .security-dashboard-filters { - top: 0 !important; - } - - .vulnerability-list thead { - top: var(--sticky-container-height) !important; - } - } /* diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index 7f269641edd225..1b727b6aded7a2 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -248,7 +248,11 @@ ul.related-merge-requests > li gl-emoji { .md-header-preview { z-index: 1; position: sticky; - top: calc(#{$calc-application-header-height} + var(--issuable-sticky-header-height, 0px) - 2px); + // note: only either --work-item-sticky-header-height or + // --issuable-sticky-header-height will be defined. + // --issuable-sticky-header-height is maintained for incidents, all other + // work items use --work-item-sticky-header-height. + top: calc(#{$calc-application-header-height} + var(--work-item-sticky-header-height, 0px) + var(--issuable-sticky-header-height, 0px) - 2px); margin-left: 1px; @apply gl-bg-default; } -- GitLab