This is an automated email from the ASF dual-hosted git repository. shahar pushed a commit to branch fix-ui-fouc in repository https://gitbox.apache.org/repos/asf/airflow-site.git
commit 5ad553f40b816f9619e79605a30ee5ee7bbb9a1a Author: Shahar Epstein <[email protected]> AuthorDate: Sat Jan 3 18:25:58 2026 +0200 Fix FOUC issues and dark mode button --- landing-pages/site/assets/js/dark-mode-init.js | 35 ++++++++++++++++++++++ landing-pages/site/assets/js/dark-mode.js | 4 +-- landing-pages/site/assets/scss/_base-layout.scss | 4 +++ landing-pages/site/assets/scss/_header.scss | 3 +- landing-pages/site/layouts/partials/head-css.html | 5 ++++ .../site/layouts/partials/hooks/head-end.html | 18 +++++++++++ landing-pages/src/js/headerAnimation.js | 7 +++++ 7 files changed, 73 insertions(+), 3 deletions(-) diff --git a/landing-pages/site/assets/js/dark-mode-init.js b/landing-pages/site/assets/js/dark-mode-init.js new file mode 100644 index 0000000000..3b21b7fe91 --- /dev/null +++ b/landing-pages/site/assets/js/dark-mode-init.js @@ -0,0 +1,35 @@ +(() => { + 'use strict' + + const style = document.createElement('style') + style.innerHTML = '* { -webkit-transition: none !important; -moz-transition: none !important; -ms-transition: none !important; -o-transition: none !important; transition: none !important; }' + document.head.appendChild(style) + + window.addEventListener('DOMContentLoaded', () => { + setTimeout(() => { + style.remove() + }, 0) + }) + + const themeKey = 'td-color-theme' + const getStoredTheme = () => localStorage.getItem(themeKey) + + const getPreferredTheme = () => { + const storedTheme = getStoredTheme() + if (storedTheme) { + return storedTheme + } + + return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' + } + + const setTheme = theme => { + if (theme === 'auto') { + document.documentElement.setAttribute('data-bs-theme', (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light')) + } else { + document.documentElement.setAttribute('data-bs-theme', theme) + } + } + + setTheme(getPreferredTheme()) +})() diff --git a/landing-pages/site/assets/js/dark-mode.js b/landing-pages/site/assets/js/dark-mode.js index 856cb6ff0b..b5d7f04b8f 100644 --- a/landing-pages/site/assets/js/dark-mode.js +++ b/landing-pages/site/assets/js/dark-mode.js @@ -27,7 +27,7 @@ * Licensed under the Creative Commons Attribution 3.0 Unported License. */ -(() => { +;(() => { 'use strict' const themeKey = 'td-color-theme' @@ -104,7 +104,7 @@ }) window.addEventListener('DOMContentLoaded', () => { - showActiveTheme(getPreferredTheme()) + showActiveTheme(getStoredTheme() || 'auto') document.querySelectorAll('[data-bs-theme-value]') .forEach(toggle => { diff --git a/landing-pages/site/assets/scss/_base-layout.scss b/landing-pages/site/assets/scss/_base-layout.scss index 69241171c8..98d25d08a3 100644 --- a/landing-pages/site/assets/scss/_base-layout.scss +++ b/landing-pages/site/assets/scss/_base-layout.scss @@ -19,6 +19,10 @@ @import "media"; @import "fonts"; +html { + overflow-y: scroll; +} + .base-layout { // padding: 123px 0 40px; padding: 163px 0 40px; // TEMP - accommodate Airflow Summit banner (123 + 40) diff --git a/landing-pages/site/assets/scss/_header.scss b/landing-pages/site/assets/scss/_header.scss index 7e0b7a37ac..bbb354fa5a 100644 --- a/landing-pages/site/assets/scss/_header.scss +++ b/landing-pages/site/assets/scss/_header.scss @@ -125,7 +125,8 @@ // Dark mode styles [data-bs-theme="dark"] { #header { - // background-color handled by canvas animation + background-color: #1a1a1a; + isolation: isolate; } #header-canvas { diff --git a/landing-pages/site/layouts/partials/head-css.html b/landing-pages/site/layouts/partials/head-css.html index 738714bdc7..313c1475ce 100644 --- a/landing-pages/site/layouts/partials/head-css.html +++ b/landing-pages/site/layouts/partials/head-css.html @@ -16,6 +16,11 @@ specific language governing permissions and limitations under the License. */}} +<link rel="preload" href="/external/css/OpenSans.css" as="style"> +<link rel="preload" href="/external/css/Rubik.css" as="style"> +<link rel="preload" href="/external/css/Roboto.css" as="style"> +<link rel="preload" href="/external/css/RobotoMono.css" as="style"> + {{ $scssMain := "scss/main.scss"}} {{ if hugo.IsServer }} {{/* Note the missing postCSS. This makes it snappier to develop in Chrome, but makes it look suboptimal in other browsers. */}} diff --git a/landing-pages/site/layouts/partials/hooks/head-end.html b/landing-pages/site/layouts/partials/hooks/head-end.html new file mode 100644 index 0000000000..c06de4db71 --- /dev/null +++ b/landing-pages/site/layouts/partials/hooks/head-end.html @@ -0,0 +1,18 @@ +{{ $darkModeInit := resources.Get "js/dark-mode-init.js" | minify }} +<script> + document.documentElement.classList.add('preload'); + {{ $darkModeInit.Content | safeJS }} + window.addEventListener('DOMContentLoaded', () => { + document.documentElement.classList.remove('preload'); + }); +</script> + +<style> + .preload * { + -webkit-transition: none !important; + -moz-transition: none !important; + -ms-transition: none !important; + -o-transition: none !important; + transition: none !important; + } +</style> diff --git a/landing-pages/src/js/headerAnimation.js b/landing-pages/src/js/headerAnimation.js index 9b77f3a49d..8e7c19f860 100644 --- a/landing-pages/src/js/headerAnimation.js +++ b/landing-pages/src/js/headerAnimation.js @@ -233,6 +233,13 @@ export function initHeaderAnimation() { logoArea = createLogoArea(sketch, canvas, title, subtitle, button); boxes = createBoxes(sketch, vw, vh, logoArea, colors); sketch.createCanvas(vw, vh); + + const isDarkMode = document.documentElement.getAttribute("data-bs-theme") === "dark"; + if (isDarkMode) { + sketch.background(26, 26, 26); // #1a1a1a to match dark navbar background + } else { + sketch.background(255, 255, 255); + } }; sketch.draw = () => {
