diff --git a/.changeset/sharp-frogs-change.md b/.changeset/sharp-frogs-change.md
new file mode 100644
index 0000000000..64c2d53937
--- /dev/null
+++ b/.changeset/sharp-frogs-change.md
@@ -0,0 +1,5 @@
+---
+'@swisspost/design-system-components': patch
+---
+
+Fixed issue where the local header behaved inconsistently across different browsers.
diff --git a/packages/components/cypress/e2e/header.cy.ts b/packages/components/cypress/e2e/header.cy.ts
new file mode 100644
index 0000000000..000a09f1e1
--- /dev/null
+++ b/packages/components/cypress/e2e/header.cy.ts
@@ -0,0 +1,59 @@
+describe('header', { baseUrl: null, includeShadowDom: true }, () => {
+ const testFiles = ['post-header', 'post-header-without-title'];
+
+ testFiles.forEach(testFile => {
+ describe(testFile.replaceAll('-', ' '), () => {
+ beforeEach(() => {
+ cy.visit(`./cypress/fixtures/${testFile}.test.html`);
+
+ cy.get('post-header').as('header');
+ });
+
+ function getContentTop() {
+ return cy.get('main').then($main => Math.round($main.position().top));
+ }
+
+ function checkLayoutShift() {
+ // get the content position before the header is visible
+ let initialContentTop: number;
+ getContentTop().then(pos => {
+ initialContentTop = pos;
+ cy.get('@header').should('not.be.visible');
+ });
+
+ // check the content position did not change when the header is visible
+ cy.get('@header')
+ .should('be.visible')
+ .then(() => {
+ getContentTop().should('eq', initialContentTop);
+ });
+ }
+
+ it('should not shift layout on desktop', () => {
+ checkLayoutShift();
+ });
+
+ it('should not shift layout on mobile', () => {
+ cy.viewport('ipad-2');
+ checkLayoutShift();
+ });
+
+ it('should not shift layout on mobile', () => {
+ cy.viewport('iphone-6');
+ checkLayoutShift();
+ });
+ });
+ });
+
+ describe('Accessibility', () => {
+ beforeEach(() => {
+ cy.visit('./cypress/fixtures/post-header.test.html');
+ cy.get('post-header[data-hydrated]').should('be.visible');
+ cy.injectAxe();
+ });
+
+ it('Has no detectable a11y violations on load', () => {
+ cy.checkA11y('post-mainnavigation');
+ });
+ });
+});
diff --git a/packages/components/cypress/fixtures/post-header-without-title.test.html b/packages/components/cypress/fixtures/post-header-without-title.test.html
new file mode 100644
index 0000000000..94a0d43e27
--- /dev/null
+++ b/packages/components/cypress/fixtures/post-header-without-title.test.html
@@ -0,0 +1,137 @@
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+ Homepage
+
+
+
+
+
+
+ Menu
+
+
+
+
+
+
+ DE
+ FR
+ IT
+ EN
+
+
+
+
+
+
+
+
+
+
+ Main Navigation
+
+
+ Briefe
+ Pakete
+
+
+
+ Briefe
+
+
+ Schliessen
+ Briefe title
+
+ Briefe senden
+ Briefe Schweiz
+ Kleinwaren Ausland
+ Waren Ausland
+ Express und Kurier
+
+
+
+ Pakete Schweiz
+ Kleinwaren Ausland
+ Waren Ausland
+ Express und Kurier
+
+
+
+
+ Pakete
+
+
+ Schliessen
+ Pakete title
+
+ Pakete senden
+ Pakete Schweiz
+ Kleinwaren Ausland
+ Waren Ausland
+ Express und Kurier
+
+
+
+ Pakete Schweiz
+ Kleinwaren Ausland
+ Waren Ausland
+ Express und Kurier
+
+
+
+
+
+
+
+
+ Page Content
+
+
+
diff --git a/packages/components/cypress/fixtures/post-header.test.html b/packages/components/cypress/fixtures/post-header.test.html
new file mode 100644
index 0000000000..01e503009b
--- /dev/null
+++ b/packages/components/cypress/fixtures/post-header.test.html
@@ -0,0 +1,140 @@
+
+
+
+
+
+ Document
+
+
+
+
+
+
+
+
+ Homepage
+
+
+
+
+
+
+ Menu
+
+
+
+
+
+
+ DE
+ FR
+ IT
+ EN
+
+
+
+ Application title
+
+
+
+
+
+
+
+
+
+ Main Navigation
+
+
+ Briefe
+ Pakete
+
+
+
+ Briefe
+
+
+ Schliessen
+ Briefe title
+
+ Briefe senden
+ Briefe Schweiz
+ Kleinwaren Ausland
+ Waren Ausland
+ Express und Kurier
+
+
+
+ Pakete Schweiz
+ Kleinwaren Ausland
+ Waren Ausland
+ Express und Kurier
+
+
+
+
+ Pakete
+
+
+ Schliessen
+ Pakete title
+
+ Pakete senden
+ Pakete Schweiz
+ Kleinwaren Ausland
+ Waren Ausland
+ Express und Kurier
+
+
+
+ Pakete Schweiz
+ Kleinwaren Ausland
+ Waren Ausland
+ Express und Kurier
+
+
+
+
+
+
+
+
+ Page Content
+
+
+
diff --git a/packages/components/cypress/fixtures/post-mainnavigation-overflow.test.html b/packages/components/cypress/fixtures/post-mainnavigation-overflow.test.html
deleted file mode 100644
index 30638c9cf0..0000000000
--- a/packages/components/cypress/fixtures/post-mainnavigation-overflow.test.html
+++ /dev/null
@@ -1,172 +0,0 @@
-
-
-
-
-
- Document
-
-
-
-
-
-
-
- Homepage
-
-
-
-
-
-
- Menu
-
-
-
-
-
-
- DE
- FR
- IT
- EN
-
-
-
- Application title
-
-
-
-
-
-
-
-
-
- Main Navigation
-
-
- Item 1
-
-
- Schliessen
- Briefe title
-
- Briefe senden
- Briefe Schweiz
- Kleinwaren Ausland
- Waren Ausland
- Express und Kurier
-
-
-
- Pakete Schweiz
- Kleinwaren Ausland
- Waren Ausland
- Express und Kurier
-
-
-
-
-
- Item 2
- Item 3
- Item 4
- Item 5
- Item 6
- Item 7
- Item 8
- Item 9
- Item 10
- Item 11
- Item 12
- Item 13
- Item 14
- Item 15
- Item 16
- Item 17
- Item 18
- Item 19
-
-
- Item 20
-
-
- Schliessen
- Pakete title
-
- Pakete senden
- Pakete Schweiz
- Kleinwaren Ausland
- Waren Ausland
- Express und Kurier
-
-
-
- Pakete Schweiz
- Kleinwaren Ausland
- Waren Ausland
- Express und Kurier
-
-
-
-
-
-
-
-
diff --git a/packages/components/cypress/fixtures/post-mainnavigation.test.html b/packages/components/cypress/fixtures/post-mainnavigation.test.html
index 8d254364d9..b4eb7e560d 100644
--- a/packages/components/cypress/fixtures/post-mainnavigation.test.html
+++ b/packages/components/cypress/fixtures/post-mainnavigation.test.html
@@ -4,6 +4,10 @@
Document
+
Application title
Main Navigation
-
- Briefe
- Pakete
-
-
-
- Briefe
-
+
+ Item 1
+
-
- Pakete
-
+
+
+ Item 2
+ Item 3
+ Item 4
+ Item 5
+ Item 6
+ Item 7
+ Item 8
+ Item 9
+ Item 10
+ Item 11
+ Item 12
+ Item 13
+ Item 14
+ Item 15
+ Item 16
+ Item 17
+ Item 18
+ Item 19
+
+
+ Item 20
+
diff --git a/packages/components/src/components/post-header/post-header.scss b/packages/components/src/components/post-header/post-header.scss
index 896b23c812..4b7b7f90cc 100644
--- a/packages/components/src/components/post-header/post-header.scss
+++ b/packages/components/src/components/post-header/post-header.scss
@@ -16,16 +16,6 @@
position: relative;
}
-:host(:not(:has([slot='title']))) {
- .local-header {
- padding-block-start: 0;
- }
-
- .local-sub {
- display: none;
- }
-}
-
.d-flex {
display: flex;
}
@@ -119,6 +109,10 @@
);
padding-block-start: 18px;
box-shadow: elevation.$elevation-300;
+
+ &:has(> .local-sub) {
+ padding-block-start: 18px;
+ }
}
@include media.max(lg) {
@@ -137,6 +131,10 @@
&:not(.local-header-mobile-extended) {
box-shadow: elevation.$elevation-300;
}
+
+ &:not(:has(> .local-sub)) {
+ display: none;
+ }
}
}
diff --git a/packages/components/src/components/post-header/post-header.tsx b/packages/components/src/components/post-header/post-header.tsx
index b5ec444a14..c2db52a99b 100644
--- a/packages/components/src/components/post-header/post-header.tsx
+++ b/packages/components/src/components/post-header/post-header.tsx
@@ -66,6 +66,7 @@ export class PostHeader {
@State() device: DEVICE_SIZE = null;
@State() mobileMenuExtended: boolean = false;
+ @State() localSubShown: boolean;
@State() megadropdownOpen: boolean = false;
@@ -115,6 +116,10 @@ export class PostHeader {
this.handleScrollParentResize();
}
+ componentWillRender() {
+ this.localSubShown = this.host.querySelectorAll('[slot="title"]').length > 0;
+ }
+
componentDidRender() {
this.getFocusableElements();
this.handleLocalHeaderResize();
@@ -282,6 +287,11 @@ export class PostHeader {
}
}
+ private checkSlottedTitle(e: Event) {
+ const target = e.target as HTMLSlotElement;
+ this.localSubShown = target.assignedElements().length > 0;
+ }
+
private handleScrollParentResize() {
if (this.scrollParent) {
this.scrollParentResizeObserver = new ResizeObserver(this.updateScrollParentHeight);
@@ -351,11 +361,13 @@ export class PostHeader {
{this.device !== 'desktop' && this.renderNavigation()}
diff --git a/packages/styles/src/components/header/index.scss b/packages/styles/src/components/header/index.scss
index 860eac1340..d3c2788611 100644
--- a/packages/styles/src/components/header/index.scss
+++ b/packages/styles/src/components/header/index.scss
@@ -10,6 +10,7 @@
tokens.$default-map: elements.$post-link;
post-header {
+ --local-header-height: var(--local-header-min-height);
--header-expanded-height: calc(var(--global-header-height) + var(--local-header-height));
--header-reduced-height: calc(
var(--global-header-reduced-height) + var(--main-navigation-height)
@@ -26,27 +27,32 @@ post-header {
--global-header-height: 72px;
--global-header-reduced-height: 24px;
--main-navigation-height: 56px;
- --local-header-height: 112px;
+ --local-header-min-height: var(--main-navigation-height);
}
@include media.max(lg) {
--header-reduced-height: var(--header-expanded-height);
--global-header-height: 64px;
--global-header-reduced-height: var(--global-header-height);
- --local-header-height: 48px;
- --main-navigation-height: 0px; /* stylelint-disable-line length-zero-no-unit */ /* needed for calculation */
+ // stylelint-disable length-zero-no-unit
+ // units are needed for calculation
+ --main-navigation-height: 0px;
+ --local-header-min-height: 0px;
+ // stylelint-enable length-zero-no-unit
}
- @include media.min(md) {
- --local-header-min-height: 56px;
- }
+ &:has([slot='title']) {
+ @include media.min(lg) {
+ --local-header-min-height: 112px;
+ }
- @include media.max(md) {
- --local-header-min-height: 48px;
- }
+ @include media.between(md, lg) {
+ --local-header-min-height: 56px;
+ }
- &:not(:has([slot='title'])) {
- --local-header-height: var(--main-navigation-height) !important;
+ @include media.max(md) {
+ --local-header-min-height: 48px;
+ }
}
&:not(:defined),