CSS Variables are All You Need
The CSS variables work automatically - just use them:
padding-top: var(--safe-area-top);
padding-bottom: var(--safe-area-bottom);
Important: Use var()
not env()
- these are Despia custom properties.
Optional: Loading Screen for Perfect Animations
The callback is cosmetic only - the CSS variables will work without it. But if you want to know exactly when to remove a loader for smooth animations:
window.safeAreaReady = function(insets) {
// This tells you when safe areas are ready
// Perfect time to hide your loader
console.log('Ready to remove loader', insets);
};
Smart Loading Screen Pattern
Show a loader only in native Despia apps, automatically hiding it when safe areas are ready:
// Initial state - show loader only in Despia native app
let showLoader = navigator.userAgent.includes('despia');
window.safeAreaReady = function(insets) {
// Function called = safe areas ready, hide loader
if (navigator.userAgent.includes('despia')) {
showLoader = false;
// Hide your loading screen
}
};
This pattern ensures:
-
Loader only appears in native apps (checks for "Despia" user agent)
-
Loader automatically hides when
safeAreaReady
is called -
No loader shown on web browsers (non-native)
Direct Access (Debugging)
You can also access safe areas directly using:
window.safeAreaInsets()
// Returns: { top: 47, bottom: 34 } when available
// Returns: undefined if not yet calculated
Note: This function only returns values when available. In low power mode, hot from charging, or with many apps open, it may return undefined. We recommend using the event listener approach above. The direct function is primarily for debugging or testing purposes. If you only use CSS variables without the listener, you may experience content jumping when values load.
Platform Examples
WeWeb
window.safeAreaReady = function(insets) {
// Option 1: Call a workflow that will set variables for you
wwLib.wwWorkflow.executeGlobal('YOUR_WORKFLOW_ID', {
safeAreaTop: insets.top,
safeAreaBottom: insets.bottom,
isReady: true
});
// Option 2: Directly set WeWeb variables (if you don't need workflow logic)
};
Wized
Add this to your "On page loaded" event:
window.safeAreaReady = function(insets) {
// Set Wized variables
v.safeAreaTop = insets.top;
v.safeAreaBottom = insets.bottom;
v.safeAreaReady = true;
// Hide loading element using Wized's visibility settings
// Configure in Wized UI: Show when v.safeAreaReady = false
};
Nordcraft / Toddle
Add this to a Custom Action attached to page load:
window.safeAreaReady = function(insets) {
// Trigger a Custom Action event
ctx.triggerActionEvent("onSafeArea", {
safeAreaTop: insets.top,
safeAreaBottom: insets.bottom,
isReady: true
});
};
For Nordcraft/Toddle - install the "Despia" Package from: https://toddle.dev/projects/despia_package/branches/main
Basic HTML Example
<style>
.app {
padding-top: var(--safe-area-top);
padding-bottom: var(--safe-area-bottom);
}
#loader {
/* Your loading screen styles */
}
</style>
<div id="loader">Loading...</div>
<div class="app">Your content</div>
<script>
window.safeAreaReady = function(insets) {
document.getElementById('loader').style.display = 'none';
};
</script>
Tips
-
The callback ensures smooth animations even when devices are slow
-
Values adjust automatically for notches, home indicators, and rounded corners
-
Consider adding a loading indicator for the best user experience
-
Safe areas update automatically on device rotation