Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request 'fix: frozen column compositing + version badge z-index' (#264) from fix/frozen-bg-compositing-and-version-badge into main

scott efa431e7 92443463

+32 -10
+7
CHANGELOG.md
··· 8 8 ## [0.23.5] — 2026-04-06 9 9 10 10 ### Fixed 11 + - Frozen column background now survives scrolling: compositing layer + inline !important prevent WebKit paint drops and CSS override (#441) 12 + - Version badge no longer overlapped by sheet UI elements (z-index 1→50) (#441) 13 + - Frozen column transparent background in dark mode when scrolling (#440) 11 14 - Sheets: spill system no longer silently overwrites user-entered data in cells that were previously spill targets (#431) 12 15 - Sheets: frozen columns/rows now always have an opaque background in dark mode, preventing scrolled content from showing through (#432) 13 16 ··· 247 250 - Fix E2E test flakiness: replace page reload with addInitScript, add waitForURL before waitForSelector (#305) 248 251 249 252 ### Changed 253 + - QA batch 20: continued edge case coverage expansion (#439) 254 + - QA batch 19: theming, automations, range-highlight, export edge cases (#438) 255 + - QA batch 18: formulas & pivot-table edge cases (#437) 256 + - QA batch 17: more untested pure-logic modules (#436) 250 257 - No unit tests for server API endpoints or WebSocket relay (#413) 251 258 - No unit tests for forms builder, conditional logic, or response pipeline (#412) 252 259 - CSS: dark mode colors use oklch() which is not supported in Firefox <113 or Safari <15.4 - no fallback colors defined (#408)
+8 -2
src/css/app.css
··· 2633 2633 .sheet-grid td.frozen-corner { 2634 2634 position: sticky; 2635 2635 background: var(--color-bg, #fff); 2636 + /* Force own compositing layer — prevents WebKit/Blink from dropping the 2637 + background paint of sticky cells during fast scrolling (oklch + custom 2638 + properties exacerbate the bug). */ 2639 + -webkit-backface-visibility: hidden; 2640 + backface-visibility: hidden; 2636 2641 } 2637 2642 2638 2643 [data-theme="dark"] .sheet-grid td.frozen-row, ··· 7322 7327 font-style: italic; 7323 7328 } 7324 7329 7325 - /* Version badge */ 7330 + /* Version badge — z-index must exceed sticky cells (max 5) and sheet UI 7331 + but stay below modals/dialogs (1000+). */ 7326 7332 .version-badge { 7327 7333 position: fixed; 7328 7334 bottom: 0.5rem; ··· 7332 7338 color: var(--color-text-faint, oklch(0.6 0 0)); 7333 7339 opacity: 0.5; 7334 7340 pointer-events: none; 7335 - z-index: 1; 7341 + z-index: 50; 7336 7342 user-select: none; 7337 7343 } 7338 7344
+17 -8
src/sheets/main.ts
··· 593 593 const cfStyleStr = buildCfStyle(cfResult); 594 594 595 595 // Background on td so inset box-shadow grid lines paint on top. 596 - // Frozen cells MUST have an opaque background to occlude scrolled content behind them. 596 + // Frozen cells use !important so CSS rules (.in-range etc.) can't replace with semi-transparent bg. 597 + const isFrozenCell = c <= freezeC || r <= freezeR; 597 598 const cellBg = getCellBgColor(cellData, cfStyleStr); 598 599 if (cellBg) { 599 - tdStyle += 'background:' + cellBg + ';'; 600 - } else if (c <= freezeC || r <= freezeR) { 601 - tdStyle += 'background:var(--color-bg);'; 600 + tdStyle += 'background:' + cellBg + (isFrozenCell ? ' !important' : '') + ';'; 601 + } else if (isFrozenCell) { 602 + tdStyle += 'background:var(--color-bg) !important;'; 602 603 } 603 604 604 605 const styleAttr = tdStyle ? ' style="' + tdStyle + '"' : ''; ··· 2387 2388 displayDiv.style.cssText = 'padding:0;overflow:hidden;' + getCellStyle(cellData, ''); 2388 2389 } 2389 2390 // Background on td for sparklines too 2390 - // Frozen cells MUST keep an opaque inline background to occlude scrolled content 2391 + // Frozen cells use !important so CSS rules like .in-range can't override with semi-transparent bg 2391 2392 const bg = getCellBgColor(cellData, ''); 2392 - td.style.background = bg || (isFrozen ? 'var(--color-bg)' : ''); 2393 + if (isFrozen) { 2394 + td.style.setProperty('background', bg || 'var(--color-bg)', 'important'); 2395 + } else { 2396 + td.style.background = bg || ''; 2397 + } 2393 2398 hasSparklines = true; 2394 2399 } else { 2395 2400 // Remove sparkline canvas if value is no longer a sparkline ··· 2400 2405 const cfStyleStr = buildCfStyle(cfResult); 2401 2406 displayDiv.style.cssText = getCellStyle(cellData, cfStyleStr); 2402 2407 // Background on td so inset box-shadow grid lines paint on top 2403 - // Frozen cells MUST keep an opaque inline background to occlude scrolled content 2408 + // Frozen cells use !important so CSS rules like .in-range can't override with semi-transparent bg 2404 2409 const bg = getCellBgColor(cellData, cfStyleStr); 2405 - td.style.background = bg || (isFrozen ? 'var(--color-bg)' : ''); 2410 + if (isFrozen) { 2411 + td.style.setProperty('background', bg || 'var(--color-bg)', 'important'); 2412 + } else { 2413 + td.style.background = bg || ''; 2414 + } 2406 2415 // Update wrap class 2407 2416 if (cellData?.s?.wrap) displayDiv.classList.add('cell-wrap'); 2408 2417 else displayDiv.classList.remove('cell-wrap');