Prologue
At two in the morning, Beijing’s sky held no stars — only haze and neon. I sat at my computer, staring at the butterflies on screen — they were supposed to dance gracefully over a pink gradient background, yet in fullscreen mode they vanished without a trace.
This reminded me of the butterfly from Zhuangzi — I couldn’t tell whether Zhuang Zhou had dreamed of the butterfly, or the butterfly had dreamed of Zhuang Zhou. Except my butterflies were trapped inside the browser’s Fullscreen API, caught between a rock and a hard place.
Origin
The project was simple: an English word dictation tool that needed a butterfly theme. When not fullscreen, the butterflies fluttered happily across the screen; when fullscreen, they went on collective strike, as if trapped by some invisible barrier.
The client asked me: “Why are the butterflies not shown in fullscreen, but shown when not fullscreen?”
I stared at the screen and recalled my master’s words: “A bug is like life — seemingly complex, yet actually simple. You just haven’t found the right angle yet.”
First probe: the fog of z-index
My first thought was a z-index problem. The butterflies might be pressed underneath other elements — just like us in life, often buried under trivia, struggling to breathe.
/* Original code */
<div className="fixed inset-0 pointer-events-none z-0">
I changed z-0 to z-10, thinking the butterflies would finally see the light of day. Saved, refreshed, fullscreen — still no butterflies.
This reminded me of myself falling in love for the first time, thinking that giving more would earn a glance in return. But reality is always more complicated than imagination.
Second probe: the overflow trap
If it wasn’t z-index, could overflow be the culprit? I carefully inspected the code and found the butterfly theme’s container had overflow-hidden set.
// The trap in the theme config
butterfly: {
background: 'bg-gradient-to-br from-pink-50 via-purple-50 to-blue-50 relative overflow-hidden',
}
overflow-hidden — the name itself is full of zen — hiding the overflow, just as we hide our true feelings in life and pretend everything is fine. But butterflies don’t need to hide; they need to fly free.
I removed overflow-hidden, saved, refreshed, fullscreen — still no butterflies.
Enlightenment: the barrier of the Fullscreen API
At three in the morning, I brewed a cup of strong tea. The leaves unfurled in the hot water, much like code unfolding in an editor. It suddenly dawned on me that the problem might not be in CSS at all, but in the JavaScript Fullscreen API itself.
I re-examined the fullscreen implementation:
await gameContainerRef.current.requestFullscreen();
requestFullscreen() — the method’s name sounds so peaceful, yet in my code it built an invisible wall. The butterflies danced outside the wall, while users inside couldn’t see their beauty.
I finally understood: when an element enters fullscreen mode, only that element and its children are elevated to the fullscreen layer. Every other element — including my butterflies — is mercilessly ignored by the browser.
Breaking through: reconstructing the DOM
With the root cause found, the solution followed naturally. I needed to move the butterflies inside the fullscreen barrier.
// DOM structure before refactor
<div className="min-h-screen relative">
<ButterflyBackground /> {/* butterflies outside the barrier */}
<div ref={gameContainerRef}> {/* the fullscreen barrier */}
{/* content */}
</div>
</div>
// DOM structure after refactor
<div className="min-h-screen relative">
<div ref={gameContainerRef}> {/* the fullscreen barrier */}
<ButterflyBackground /> {/* butterflies inside the barrier */}
{/* content */}
</div>
</div>
It’s that simple. Sometimes, the key to solving a problem isn’t adding more code, but rethinking the structure of the code — just like life: sometimes what you need isn’t more effort, but a different angle on the world.
Epilogue
At four in the morning, I reopened the browser, entered the word dictation tool, switched to the butterfly theme, and clicked the fullscreen button.
The pink gradient background filled the entire screen, and the butterflies danced lightly across it, their wings shimmering in the early light. They were finally free, finding their own sky in the fullscreen world.
I shut down the computer and walked onto the balcony. Beijing’s haze was still thick, but on the eastern horizon, a faint hint of dawn was breaking through.
I thought of my master’s words: “A bug is like life — seemingly complex, yet actually simple.” The Fullscreen API is like the various constraints in life: they truly exist, but smart programmers — or rather, smart livers — can always find a way to dance within the constraints.
The butterflies taught me: sometimes, what you need isn’t just a higher z-index, but finding the right container.
Just like life: what you need isn’t just more effort, but finding the place that belongs to you.
Technical summary
- The essence of the Fullscreen API:
requestFullscreen()only elevates the specified element and its children to the fullscreen layer - The pitfall of fixed positioning: in fullscreen mode, fixed-position elements outside the fullscreen element become invisible
- The importance of DOM structure: a sensible DOM structure matters more than complex CSS rules
- The art of debugging: sometimes, stepping back to re-examine the essence of a problem is more effective than blindly trying every solution
Code example
// The correct butterfly background component structure
const ButterflyBackground = () => (
<div className="fixed inset-0 pointer-events-none z-10">
{[...Array(8)].map((_, i) => (
<div
key={i}
className="absolute animate-bounce opacity-70"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${i * 2}s`,
animationDuration: `${8 + Math.random() * 4}s`
}}
>
<div className="text-4xl transform hover:scale-110 transition-transform duration-300">🦋</div>
</div>
))}
</div>
);
// The correct component structure
return (
<div className={`min-h-screen ${currentThemeConfig.background} ${currentThemeConfig.text} p-4 md:p-8 relative`}>
<div
ref={gameContainerRef}
className={`max-w-4xl mx-auto ${isFullscreen ? currentThemeConfig.card.split(' ')[0] + ' p-8 h-full overflow-auto' : ''}`}
tabIndex={-1}
>
<ButterflyBackground /> {/* placed inside the fullscreen container */}
{/* other content */}
</div>
</div>
);
May every programmer find their own butterfly in the world of code.