Refine bottom app bar appearance (#10853)
Changelog Drafter / update_draft_release (push) Waiting to run Details
Changelog Drafter / jenkins_io_draft (push) Waiting to run Details
Label conflicting PRs / main (push) Waiting to run Details

This commit is contained in:
Kris Stern 2025-07-25 20:07:36 +08:00 committed by GitHub
commit 081dc2496c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 48 additions and 52 deletions

View File

@ -30,6 +30,7 @@ THE SOFTWARE.
This area will always be visible at the bottom of the screen.
</st:documentation>
<div class="jenkins-bottom-app-bar__shadow"></div>
<div id="bottom-sticker">
<div class="bottom-sticker-inner jenkins-buttons-row jenkins-buttons-row--equal-width">
<d:invokeBody />

View File

@ -8,6 +8,10 @@
display: flex;
flex-direction: column;
gap: var(--section-padding);
#bottom-sticker {
margin-top: calc(var(--section-padding) * -1);
}
}
.item-copy {

View File

@ -79,7 +79,7 @@ $semantics: (
// App bar
--bottom-app-bar-shadow: color-mix(
in sRGB,
var(--text-color-secondary) 7.5%,
var(--text-color-secondary) 8%,
transparent
);
@ -116,7 +116,7 @@ $semantics: (
--jenkins-border-width: 1.5px;
--jenkins-border-color: color-mix(
in sRGB,
var(--text-color-secondary) 15%,
var(--text-color-secondary) 17.5%,
var(--card-background)
);
--jenkins-border-color--subtle: color-mix(

View File

@ -111,47 +111,38 @@
}
}
.bottom-sticker,
#bottom-sticker {
$bottom-app-bar-padding: 0.875rem;
.jenkins-bottom-app-bar__shadow {
--semi-translucent: color-mix(in sRGB, var(--background) 75%, transparent);
position: sticky;
// This has to be set to -1px so that IntersectionObserver can add the
// &--stuck class when the element is stuck to the bottom of the screen
// https://css-tricks.com/how-to-detect-when-a-sticky-element-gets-pinned/
height: calc(
2.375rem + ($bottom-app-bar-padding * 2) + 1px + var(--jenkins-border-width)
);
bottom: -1px;
margin-left: calc(var(--section-padding) * -1);
width: calc(
100% + calc(var(--section-padding) * 2)
); /* it needs to occupy the entire width or else the underlying content will see through */
z-index: 998; /* behind top-sticker */
}
.bottom-sticker-inner {
position: relative;
padding: 1em var(--section-padding);
z-index: 0;
&::before {
content: "";
position: absolute;
inset: 0;
background: var(--background);
opacity: 0;
z-index: -1;
}
margin-bottom: calc((2.375rem + $bottom-app-bar-padding) * -1);
backdrop-filter: blur(20px);
background: linear-gradient(
to right,
var(--background),
var(--semi-translucent) 3rem,
var(--semi-translucent) calc(100% - 3rem),
var(--background)
);
border-top: var(--jenkins-border-width) solid var(--jenkins-border-color);
z-index: 997;
&::after {
content: "";
position: absolute;
top: -30px;
left: 0;
right: 0;
background: linear-gradient(transparent, var(--bottom-app-bar-shadow) 110%);
max-width: 100%;
height: 30px;
opacity: 0;
transition: var(--standard-transition);
transition: opacity var(--standard-transition);
top: calc((2rem + var(--jenkins-border-width)) * -1);
height: 2rem;
pointer-events: none;
background: linear-gradient(transparent, var(--bottom-app-bar-shadow));
mask-image: linear-gradient(
to right,
transparent,
@ -159,24 +150,24 @@
white calc(100% - var(--section-padding)),
transparent
);
pointer-events: none;
opacity: 0;
}
&--stuck {
.bottom-sticker-inner {
backdrop-filter: blur(15px);
&::before {
opacity: 0.75 !important;
@supports not (backdrop-filter: blur(15px)) {
opacity: 1 !important;
}
}
&::after {
opacity: 1 !important;
}
&::after {
opacity: 1 !important;
}
}
}
.bottom-sticker,
#bottom-sticker {
position: sticky;
bottom: 0;
z-index: 998;
}
.bottom-sticker-inner {
position: relative;
padding: $bottom-app-bar-padding 0;
}

View File

@ -1754,12 +1754,12 @@ function rowvgStartEachRow(recursive, f) {
window.addEventListener("load", function () {
// Add a class to the bottom bar when it's stuck to the bottom of the screen
const el = document.querySelector("#bottom-sticker");
const el = document.querySelector(".jenkins-bottom-app-bar__shadow");
if (el) {
const observer = new IntersectionObserver(
([e]) =>
e.target.classList.toggle(
"bottom-sticker-inner--stuck",
"jenkins-bottom-app-bar__shadow--stuck",
e.intersectionRatio < 1,
),
{ threshold: [1] },