3.8.3
Stop event banner size shifting
This commit is contained in:
+20
-4
@@ -257,18 +257,34 @@ body {
|
||||
background: rgba(0, 0, 0, 0.55);
|
||||
}
|
||||
|
||||
/* Slide stack. Every active event is rendered and every slide is placed in the
|
||||
same single grid cell, so the strip's height is set by the TALLEST slide and
|
||||
stays put as the rotation cycles — a one-line event followed by a message
|
||||
that wraps to two lines no longer grows the banner and shunts the page. */
|
||||
.event-note-stack {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
align-items: start;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.event-note-slide {
|
||||
grid-area: 1 / 1; /* stack all slides on top of each other */
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px 10px;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
opacity: 1;
|
||||
opacity: 0; /* only .is-active is visible */
|
||||
pointer-events: none;
|
||||
user-select: none; /* keeps hidden copy out of a drag-selection */
|
||||
transition: opacity 0.35s ease;
|
||||
}
|
||||
.event-note-slide.is-fading {
|
||||
opacity: 0;
|
||||
.event-note-slide.is-active {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
user-select: auto;
|
||||
}
|
||||
|
||||
.event-note-emoji {
|
||||
|
||||
+33
-15
@@ -692,9 +692,18 @@ export function UTCIForecast() {
|
||||
const fmtDate = (iso) => iso
|
||||
? new Date(iso + 'T00:00Z').toLocaleDateString('en-GB', { day: 'numeric', month: 'short', timeZone: 'UTC' })
|
||||
: null;
|
||||
const startFmt = fmtDate(ev.start);
|
||||
const peakFmt = fmtDate(ev.peak);
|
||||
const endFmt = fmtDate(ev.end);
|
||||
// Date line for one event — computed per slide because every event is
|
||||
// rendered (see the stack below), not just the visible one.
|
||||
const dateLineFor = (e) => {
|
||||
const startFmt = fmtDate(e.start);
|
||||
const peakFmt = fmtDate(e.peak);
|
||||
const endFmt = fmtDate(e.end);
|
||||
if (!startFmt || !endFmt) return null;
|
||||
if (startFmt === endFmt) return peakFmt ? `Peak ${peakFmt}` : startFmt;
|
||||
return (peakFmt && peakFmt !== startFmt && peakFmt !== endFmt)
|
||||
? `${startFmt} – ${endFmt} · Peak ${peakFmt}`
|
||||
: `${startFmt} – ${endFmt}`;
|
||||
};
|
||||
// Warning banners take their background from the day tabs' weather
|
||||
// palette (ev.tint, set in events/weather-checks.js) so a heat alert
|
||||
// reads the same orange as a hot day tab and a rain alert the same
|
||||
@@ -709,21 +718,30 @@ export function UTCIForecast() {
|
||||
borderColor: `rgb(${ev.tint.map(c => Math.round(c * 0.72)).join(',')})`,
|
||||
};
|
||||
})() : undefined;
|
||||
const dateLine = (startFmt && endFmt)
|
||||
? (startFmt === endFmt
|
||||
? (peakFmt ? `Peak ${peakFmt}` : startFmt)
|
||||
: (peakFmt && peakFmt !== startFmt && peakFmt !== endFmt
|
||||
? `${startFmt} – ${endFmt} · Peak ${peakFmt}`
|
||||
: `${startFmt} – ${endFmt}`))
|
||||
: null;
|
||||
return html`
|
||||
<div class=${`event-note${isPriority ? ' is-priority' : ''}${noteTintStyle ? ' is-tinted' : ''}`} style=${noteTintStyle}>
|
||||
<span class="event-note-accent" style=${{ background: ev.color === '#fdf8ee' ? '#c8922a' : ev.color }} />
|
||||
<div class=${`event-note-slide${noteFading ? ' is-fading' : ''}`}>
|
||||
<span class="event-note-emoji">${ev.emoji}</span>
|
||||
<span class="event-note-title">${ev.title}</span>
|
||||
<span class="event-note-msg">${ev.message}</span>
|
||||
${dateLine && html`<span class="event-note-dates">${dateLine}</span>`}
|
||||
${/* Every slide is rendered, all stacked in one CSS grid cell, so the
|
||||
strip is always as tall as the LONGEST event's copy. Rotating to
|
||||
a two-line message then back no longer resizes the banner and
|
||||
shunts the page up and down. Only the active slide is visible;
|
||||
the rest sit at opacity 0 and are hidden from assistive tech. */''}
|
||||
<div class="event-note-stack">
|
||||
${activeEvents.map((e, i) => {
|
||||
const dateLine = dateLineFor(e);
|
||||
const isActive = i === noteIndex && !noteFading;
|
||||
return html`
|
||||
<div
|
||||
key=${e.id || i}
|
||||
class=${`event-note-slide${isActive ? ' is-active' : ''}`}
|
||||
aria-hidden=${isActive ? undefined : 'true'}
|
||||
>
|
||||
<span class="event-note-emoji">${e.emoji}</span>
|
||||
<span class="event-note-title">${e.title}</span>
|
||||
<span class="event-note-msg">${e.message}</span>
|
||||
${dateLine && html`<span class="event-note-dates">${dateLine}</span>`}
|
||||
</div>`;
|
||||
})}
|
||||
</div>
|
||||
${activeEvents.length > 1 && html`
|
||||
<div class="event-note-dots">
|
||||
|
||||
Reference in New Issue
Block a user