Skip to content

Commit 8573bf8

Browse files
fix(core): use Capacitor safe-area CSS variables on older WebViews (#30865)
Issue number: internal --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> The safe area variables are only reliant on `env` variables that are provided by devices. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> Capacitor 8 has released [safe area variable fallbacks](https://capacitorjs.com/docs/apis/system-bars#android-note) to provide consistent behaviors with older Android devices: > Due to a [bug](https://issues.chromium.org/issues/40699457) in some older versions of Android WebView (< 140), correct safe area values are not available via the safe-area-inset-x CSS env variables. This plugin will inject the correct inset values into a new CSS variable(s) named --safe-area-inset-x that you can use as a fallback in your frontend styles. - Updated safe area variables to use the fallbacks provided by Capacitor. ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change: 1. Describe the impact and migration path for existing applications below. 2. Update the BREAKING.md file with the breaking change. 3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer for more information. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Dev build: `8.7.13-dev.11765920447.1a01ab8b` --------- Co-authored-by: Brandy Smith <[email protected]>
1 parent 2c6fac9 commit 8573bf8

File tree

2 files changed

+62
-14
lines changed

2 files changed

+62
-14
lines changed

core/src/components/app/test/safe-area/app.e2e.ts

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,66 @@ configs({ directions: ['ltr'] }).forEach(({ config, title, screenshot }) => {
1818

1919
await expect(page).toHaveScreenshot(screenshot(`app-${screenshotModifier}-diff`));
2020
};
21+
2122
test.beforeEach(async ({ page }) => {
2223
await page.goto(`/src/components/app/test/safe-area`, config);
2324
});
24-
test('should not have visual regressions with action sheet', async ({ page }) => {
25-
await testOverlay(page, '#show-action-sheet', 'ionActionSheetDidPresent', 'action-sheet');
26-
});
27-
test('should not have visual regressions with menu', async ({ page }) => {
28-
await testOverlay(page, '#show-menu', 'ionDidOpen', 'menu');
29-
});
30-
test('should not have visual regressions with picker', async ({ page }) => {
31-
await testOverlay(page, '#show-picker', 'ionPickerDidPresent', 'picker');
25+
26+
test.describe(title('Ionic safe area variables'), () => {
27+
test.beforeEach(async ({ page }) => {
28+
const htmlTag = page.locator('html');
29+
const hasSafeAreaClass = await htmlTag.evaluate((el) => el.classList.contains('safe-area'));
30+
31+
expect(hasSafeAreaClass).toBe(true);
32+
});
33+
34+
test('should not have visual regressions with action sheet', async ({ page }) => {
35+
await testOverlay(page, '#show-action-sheet', 'ionActionSheetDidPresent', 'action-sheet');
36+
});
37+
test('should not have visual regressions with menu', async ({ page }) => {
38+
await testOverlay(page, '#show-menu', 'ionDidOpen', 'menu');
39+
});
40+
test('should not have visual regressions with picker', async ({ page }) => {
41+
await testOverlay(page, '#show-picker', 'ionPickerDidPresent', 'picker');
42+
});
43+
test('should not have visual regressions with toast', async ({ page }) => {
44+
await testOverlay(page, '#show-toast', 'ionToastDidPresent', 'toast');
45+
});
3246
});
33-
test('should not have visual regressions with toast', async ({ page }) => {
34-
await testOverlay(page, '#show-toast', 'ionToastDidPresent', 'toast');
47+
48+
test.describe(title('Capacitor safe area variables'), () => {
49+
test('should use safe-area-inset vars when safe-area class is not defined', async ({ page }) => {
50+
await page.evaluate(() => {
51+
const html = document.documentElement;
52+
53+
// Remove the safe area class
54+
html.classList.remove('safe-area');
55+
56+
// Set the safe area inset variables
57+
html.style.setProperty('--safe-area-inset-top', '10px');
58+
html.style.setProperty('--safe-area-inset-bottom', '20px');
59+
html.style.setProperty('--safe-area-inset-left', '30px');
60+
html.style.setProperty('--safe-area-inset-right', '40px');
61+
});
62+
63+
const top = await page.evaluate(() =>
64+
getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-top').trim()
65+
);
66+
const bottom = await page.evaluate(() =>
67+
getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-bottom').trim()
68+
);
69+
const left = await page.evaluate(() =>
70+
getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-left').trim()
71+
);
72+
const right = await page.evaluate(() =>
73+
getComputedStyle(document.documentElement).getPropertyValue('--ion-safe-area-right').trim()
74+
);
75+
76+
expect(top).toBe('10px');
77+
expect(bottom).toBe('20px');
78+
expect(left).toBe('30px');
79+
expect(right).toBe('40px');
80+
});
3581
});
3682
});
3783
});

core/src/css/core.scss

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,10 +252,12 @@ html.plt-ios.plt-hybrid, html.plt-ios.plt-pwa {
252252

253253
@supports (padding-top: env(safe-area-inset-top)) {
254254
html {
255-
--ion-safe-area-top: env(safe-area-inset-top);
256-
--ion-safe-area-bottom: env(safe-area-inset-bottom);
257-
--ion-safe-area-left: env(safe-area-inset-left);
258-
--ion-safe-area-right: env(safe-area-inset-right);
255+
// `--safe-area-inset-*` are set by Capacitor
256+
// @see https://capacitorjs.com/docs/apis/system-bars#android-note
257+
--ion-safe-area-top: var(--safe-area-inset-top, env(safe-area-inset-top));
258+
--ion-safe-area-bottom: var(--safe-area-inset-bottom, env(safe-area-inset-bottom));
259+
--ion-safe-area-left: var(--safe-area-inset-left, env(safe-area-inset-left));
260+
--ion-safe-area-right: var(--safe-area-inset-right, env(safe-area-inset-right));
259261
}
260262
}
261263

0 commit comments

Comments
 (0)