diff options
author | Kristóf Marussy <kristof@marussy.com> | 2024-08-16 01:26:43 +0200 |
---|---|---|
committer | Kristóf Marussy <kristof@marussy.com> | 2024-08-16 16:08:43 +0200 |
commit | fd64616e18677384ff27a67a33e5f8b8aad01da8 (patch) | |
tree | 5a65bc448334c608276118e514649e058025b610 /src | |
parent | Reduce FOUC on Refinery screenshot (diff) | |
download | blog-fd64616e18677384ff27a67a33e5f8b8aad01da8.tar.gz blog-fd64616e18677384ff27a67a33e5f8b8aad01da8.tar.zst blog-fd64616e18677384ff27a67a33e5f8b8aad01da8.zip |
CSS workarounds
Diffstat (limited to 'src')
-rw-r--r-- | src/components/TrackActiveSection.tsx | 4 | ||||
-rw-r--r-- | src/components/landing/sections/Software.module.css | 24 | ||||
-rw-r--r-- | src/components/landing/sections/Software.tsx | 60 |
3 files changed, 56 insertions, 32 deletions
diff --git a/src/components/TrackActiveSection.tsx b/src/components/TrackActiveSection.tsx index bb1b2ee..f27d32e 100644 --- a/src/components/TrackActiveSection.tsx +++ b/src/components/TrackActiveSection.tsx | |||
@@ -21,6 +21,10 @@ export default function TrackActiveSection({ | |||
21 | return; | 21 | return; |
22 | } | 22 | } |
23 | const currentID = Array.from(element.children) | 23 | const currentID = Array.from(element.children) |
24 | .map((element) => { | ||
25 | // Allow wrapper `div` elements around `section` elements. | ||
26 | return element.id === '' ? element.firstElementChild : element; | ||
27 | }) | ||
24 | .reverse() | 28 | .reverse() |
25 | .find((child) => child.getBoundingClientRect().top <= 60)?.id; | 29 | .find((child) => child.getBoundingClientRect().top <= 60)?.id; |
26 | const currentHash = | 30 | const currentHash = |
diff --git a/src/components/landing/sections/Software.module.css b/src/components/landing/sections/Software.module.css index 758a848..fddc727 100644 --- a/src/components/landing/sections/Software.module.css +++ b/src/components/landing/sections/Software.module.css | |||
@@ -29,8 +29,6 @@ | |||
29 | grid-row: 1 / span 2; | 29 | grid-row: 1 / span 2; |
30 | min-height: 200px; | 30 | min-height: 200px; |
31 | overflow: hidden; | 31 | overflow: hidden; |
32 | background-size: cover; | ||
33 | background-position: center center; | ||
34 | --ifm-color-primary: #038a99; | 32 | --ifm-color-primary: #038a99; |
35 | --ifm-color-primary-dark: #037c8a; | 33 | --ifm-color-primary-dark: #037c8a; |
36 | --ifm-color-primary-darker: #037582; | 34 | --ifm-color-primary-darker: #037582; |
@@ -73,22 +71,25 @@ | |||
73 | left: 0; | 71 | left: 0; |
74 | width: 100%; | 72 | width: 100%; |
75 | height: 100%; | 73 | height: 100%; |
76 | z-index: 1; | 74 | z-index: -1; |
77 | object-fit: cover; | 75 | object-fit: cover; |
78 | transition: transform var(--ifm-transition-fast) ease; | 76 | transition: transform var(--ifm-transition-fast) ease; |
79 | } | 77 | } |
80 | 78 | ||
81 | .software--refinery:hover .refinery__background, | 79 | .software--refinery:has(.cover-link:hover) .refinery__background, |
82 | .software--refinery:focus-within .refinery__background { | 80 | .software--refinery:has(.cover-link:focus) .refinery__background { |
83 | transform: scale(140%); | 81 | transform: scale(140%); |
84 | } | 82 | } |
85 | 83 | ||
86 | .content { | 84 | .content { |
87 | position: relative; | 85 | position: relative; |
88 | height: 100%; | 86 | height: 100%; |
89 | z-index: 99; | ||
90 | display: flex; | 87 | display: flex; |
91 | flex-direction: column; | 88 | flex-direction: column; |
89 | background-size: cover; | ||
90 | background-position: center center; | ||
91 | /* Force browser rendering before transform. */ | ||
92 | filter: blur(0px); | ||
92 | } | 93 | } |
93 | 94 | ||
94 | .content--refinery { | 95 | .content--refinery { |
@@ -201,6 +202,7 @@ | |||
201 | 202 | ||
202 | .screenshot__backdrop { | 203 | .screenshot__backdrop { |
203 | display: none; | 204 | display: none; |
205 | z-index: -2; | ||
204 | background-size: cover; | 206 | background-size: cover; |
205 | background-position: center center; | 207 | background-position: center center; |
206 | } | 208 | } |
@@ -210,13 +212,17 @@ | |||
210 | display: block; | 212 | display: block; |
211 | } | 213 | } |
212 | 214 | ||
213 | .screenshot, .screenshot__backdrop { | 215 | .screenshot, |
216 | .screenshot__backdrop { | ||
214 | position: absolute; | 217 | position: absolute; |
215 | top: 0; | 218 | top: 0; |
216 | left: 0; | 219 | left: 0; |
217 | width: 100%; | 220 | width: 100%; |
218 | height: 100%; | 221 | height: 100%; |
219 | z-index: 1; | 222 | } |
223 | |||
224 | .screenshot { | ||
225 | z-index: -1; | ||
220 | } | 226 | } |
221 | 227 | ||
222 | .content--screenshot { | 228 | .content--screenshot { |
@@ -336,6 +342,7 @@ | |||
336 | 342 | ||
337 | .software-grid { | 343 | .software-grid { |
338 | grid-template: min-content / 1fr; | 344 | grid-template: min-content / 1fr; |
345 | gap: 1.5rem; | ||
339 | } | 346 | } |
340 | 347 | ||
341 | .software { | 348 | .software { |
@@ -351,6 +358,7 @@ | |||
351 | .overlay--screenshot { | 358 | .overlay--screenshot { |
352 | padding: 1rem 2rem 2rem 2rem; | 359 | padding: 1rem 2rem 2rem 2rem; |
353 | font-size: 1rem; | 360 | font-size: 1rem; |
361 | transform: none; | ||
354 | } | 362 | } |
355 | } | 363 | } |
356 | 364 | ||
diff --git a/src/components/landing/sections/Software.tsx b/src/components/landing/sections/Software.tsx index 577939c..c44a6ad 100644 --- a/src/components/landing/sections/Software.tsx +++ b/src/components/landing/sections/Software.tsx | |||
@@ -23,10 +23,10 @@ import styles from './Software.module.css'; | |||
23 | import FerdiumLogo from './ferdium.svg'; | 23 | import FerdiumLogo from './ferdium.svg'; |
24 | import refineryBackground from './refinery-background.png?placeholder=true&sizes[]=767&sizes[]=997&sizes[]=1534&sizes[]=1920&rl'; | 24 | import refineryBackground from './refinery-background.png?placeholder=true&sizes[]=767&sizes[]=997&sizes[]=1534&sizes[]=1920&rl'; |
25 | import RefineryLogo from './refinery-logo.svg'; | 25 | import RefineryLogo from './refinery-logo.svg'; |
26 | import refineryScreenshotDark from './refinery-screenshot-dark.png?placeholder=true&sizes[]=767&sizes[]=997&sizes[]=1534&sizes[]=1920&rl'; | 26 | import refineryScreenshotDark from './refinery-screenshot-dark.png?placeholder=true&sizes[]=997&sizes[]=1920&format=png&rl'; |
27 | import refineryScreenshotLight from './refinery-screenshot-light.png?placeholder=true&sizes[]=767&sizes[]=997&sizes[]=1534&sizes[]=1920&rl'; | 27 | import refineryScreenshotLight from './refinery-screenshot-light.png?placeholder=true&sizes[]=997&sizes[]=1920&format=png&rl'; |
28 | 28 | ||
29 | function Screenshot() { | 29 | function ScreenshotImage() { |
30 | // Force re-render in browser. | 30 | // Force re-render in browser. |
31 | // https://github.com/facebook/docusaurus/blob/e012e0315862b2ca02cad40c58d11d31c319ff75/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx#L32-L36 | 31 | // https://github.com/facebook/docusaurus/blob/e012e0315862b2ca02cad40c58d11d31c319ff75/packages/docusaurus-theme-classic/src/theme/CodeBlock/index.tsx#L32-L36 |
32 | const isBrowser = useIsBrowser(); | 32 | const isBrowser = useIsBrowser(); |
@@ -48,34 +48,46 @@ function Screenshot() { | |||
48 | /> | 48 | /> |
49 | ); | 49 | ); |
50 | 50 | ||
51 | return isBrowser ? screenshot : <noscript>{screenshot}</noscript>; | ||
52 | } | ||
53 | |||
54 | function Screenshot() { | ||
51 | return ( | 55 | return ( |
52 | <div | 56 | <div |
53 | key={String(isBrowser)} | ||
54 | className={clsx( | 57 | className={clsx( |
55 | styles.software, | 58 | styles.software, |
56 | styles['software--interactive'], | 59 | styles['software--interactive'], |
57 | styles['software--screenshot'], | 60 | styles['software--screenshot'], |
58 | )} | 61 | )} |
59 | style={{ | 62 | style={{ |
60 | aspectRatio: refineryScreenshot.width / refineryScreenshot.height, | 63 | aspectRatio: |
64 | refineryScreenshotDark.width / refineryScreenshotDark.height, | ||
61 | }} | 65 | }} |
62 | > | 66 | > |
63 | <div className={clsx(styles.content, styles['content--screenshot'])}> | 67 | <div className={clsx(styles.content, styles['content--screenshot'])}> |
64 | <div | 68 | <div |
65 | className={clsx(styles.screenshot__backdrop, styles['screenshot__backdrop--light'])} | 69 | className={clsx( |
70 | styles.screenshot__backdrop, | ||
71 | styles['screenshot__backdrop--light'], | ||
72 | )} | ||
66 | style={{ | 73 | style={{ |
67 | aspectRatio: refineryScreenshotDark.width / refineryScreenshotDark.height, | 74 | aspectRatio: |
75 | refineryScreenshotDark.width / refineryScreenshotDark.height, | ||
68 | backgroundImage: `url(${refineryScreenshotDark.placeholder})`, | 76 | backgroundImage: `url(${refineryScreenshotDark.placeholder})`, |
69 | }} | 77 | }} |
70 | /> | 78 | /> |
71 | <div | 79 | <div |
72 | className={clsx(styles.screenshot__backdrop, styles['screenshot__backdrop--dark'])} | 80 | className={clsx( |
81 | styles.screenshot__backdrop, | ||
82 | styles['screenshot__backdrop--dark'], | ||
83 | )} | ||
73 | style={{ | 84 | style={{ |
74 | aspectRatio: refineryScreenshotLight.width / refineryScreenshotLight.height, | 85 | aspectRatio: |
86 | refineryScreenshotLight.width / refineryScreenshotLight.height, | ||
75 | backgroundImage: `url(${refineryScreenshotLight.placeholder})`, | 87 | backgroundImage: `url(${refineryScreenshotLight.placeholder})`, |
76 | }} | 88 | }} |
77 | /> | 89 | /> |
78 | {isBrowser ? screenshot : <noscript>{screenshot}</noscript>} | 90 | <ScreenshotImage /> |
79 | <div | 91 | <div |
80 | className={clsx( | 92 | className={clsx( |
81 | styles.overlay, | 93 | styles.overlay, |
@@ -88,7 +100,7 @@ function Screenshot() { | |||
88 | href="https://refinery.services" | 100 | href="https://refinery.services" |
89 | className={styles.screenshot__link} | 101 | className={styles.screenshot__link} |
90 | > | 102 | > |
91 | Try Refinery in your browser! | 103 | Try Refinery in your browser |
92 | </Link> | 104 | </Link> |
93 | </p> | 105 | </p> |
94 | </div> | 106 | </div> |
@@ -109,23 +121,23 @@ export default function Software() { | |||
109 | styles['software--interactive'], | 121 | styles['software--interactive'], |
110 | styles['software--refinery'], | 122 | styles['software--refinery'], |
111 | )} | 123 | )} |
112 | style={{ | ||
113 | backgroundImage: `url(${refineryBackground.placeholder})`, | ||
114 | }} | ||
115 | > | 124 | > |
116 | <img | ||
117 | src={refineryBackground.src} | ||
118 | srcSet={refineryBackground.srcSet} | ||
119 | width={refineryBackground.width} | ||
120 | height={refineryBackground.height} | ||
121 | sizes="(min-width: 1440px) 767px, (min-width: 1384px) 659px, (min-width: 997px) calc(60vw - 64px), calc(100vw - 32px)" | ||
122 | loading="lazy" | ||
123 | alt="" | ||
124 | className={styles.refinery__background} | ||
125 | /> | ||
126 | <div | 125 | <div |
127 | className={clsx(styles.content, styles['content--refinery'])} | 126 | className={clsx(styles.content, styles['content--refinery'])} |
127 | style={{ | ||
128 | backgroundImage: `url(${refineryBackground.placeholder})`, | ||
129 | }} | ||
128 | > | 130 | > |
131 | <img | ||
132 | src={refineryBackground.src} | ||
133 | srcSet={refineryBackground.srcSet} | ||
134 | width={refineryBackground.width} | ||
135 | height={refineryBackground.height} | ||
136 | sizes="(min-width: 1440px) 767px, (min-width: 1384px) 659px, (min-width: 997px) calc(60vw - 64px), calc(100vw - 32px)" | ||
137 | loading="lazy" | ||
138 | alt="" | ||
139 | className={styles.refinery__background} | ||
140 | /> | ||
129 | <h3 className={styles.refinery__heading}> | 141 | <h3 className={styles.refinery__heading}> |
130 | <RefineryLogo className={styles.refinery__logo} /> | 142 | <RefineryLogo className={styles.refinery__logo} /> |
131 | <Link | 143 | <Link |