/**
* Sets `--header-height` and `--header-group-height` to measured values before first paint.
*
* A few CSS rules position content relative to the header at first paint — a hero sized to
* the remaining viewport, a transparent header's negative margin. Without a measured value
* those rules use the `60px` fallback from `sections/header.liquid`, and the content visibly
* jumps once `header.js` corrects the values after load.
*
* Measuring forces layout mid-parse, so it only runs where a consuming rule exists.
* Callers opt in: the transparent-header branch below, or `snippets/measure-header-heights.liquid`,
* which any new first-paint consumer must render too.
*
* Measures once per page; after load, header.js's ResizeObservers keep the values fresh.
* The group-height walk mimics calculateHeaderGroupHeight() in utilities.js — keep them
* in sync.
*/
window.measureHeaderHeights = (function () {
let measured = false;
return function measureHeaderHeights() {
if (measured) return;
const header = document.querySelector('#header-component');
const headerGroup = document.querySelector('#header-group');
if (!header || !headerGroup) return;
measured = true;
const headerHeight = header.offsetHeight;
let headerGroupHeight = 0;
for (const element of headerGroup.children) {
if (element instanceof HTMLElement) headerGroupHeight += element.offsetHeight;
}
/**
* A transparent header is absolutely positioned, so the loop above counts its section
* wrapper as 0px. When a section follows it in the group, header.liquid pushes that
* section down by the header's height using a margin, which offsetHeight also
* excludes — so the header's height has to be added back manually.
*/
if (header.hasAttribute('transparent') && header.parentElement?.nextElementSibling) {
headerGroupHeight += headerHeight;
}
document.body.style.setProperty('--header-height', `${headerHeight}px`);
document.body.style.setProperty('--header-group-height', `${headerGroupHeight}px`);
};
})();
/**
* Transparent-header rules consume the measured heights at first paint on every
* template, so the transparent case opts in globally here instead of per-section.
*/
if (document.querySelector('#header-component')?.hasAttribute('transparent')) {
measureHeaderHeights();
}
/**
* Sets `--top-row-height`, consumed by the header underlays and submenus. Deferred to a
* rAF so the height read doesn't force layout mid-parse, and scoped to the
* header, where all consumers live, so the write only invalidates the header subtree.
* Mimics the `--top-row-height` write in updateHeaderHeights() in utilities.js
*/
(function setTopRowHeight() {
const header = document.querySelector('#header-component');
const headerTopRow = header?.querySelector('.header__row--top');
if (!headerTopRow) return;
window.requestAnimationFrame(function () {
header.style.setProperty('--top-row-height', `${headerTopRow.getBoundingClientRect().height}px`);
});
})();
/**
* Sets `--transparent-header-offset-boolean` when the first section must offset itself
* under a transparent header. The non-offset case relies on the `0` default declared in
* sections/header.liquid — unlike updateTransparentHeaderOffset() in utilities.js, which
* re-runs on editor changes and must write '0' to reset a previously written '1'.
*/
(function updateTransparentHeaderOffset() {
const header = document.querySelector('#header-component');
const headerSection = document.querySelector('#header-group .header-section');
if (!headerSection || !header?.hasAttribute('transparent')) return;
const hasImmediateSection = headerSection.nextElementSibling?.classList.contains('shopify-section');
if (!hasImmediateSection) {
document.body.style.setProperty('--transparent-header-offset-boolean', '1');
}
})();
/**
* Sets the initial menu style (inline menu vs. drawer) on the header component.
* Mimics setHeaderMenuStyle() in utilities.js
*/
(function setHeaderMenuStyle() {
const headerComponent = document.querySelector('#header-component');
if (headerComponent) {
const isTouchDevice = 'ontouchstart' in window && navigator.maxTouchPoints > 0;
const overflowList = headerComponent.querySelector('overflow-list');
const hasReachedMinimum = overflowList && overflowList.hasAttribute('minimum-reached');
headerComponent.dataset.menuStyle = isTouchDevice || hasReachedMinimum ? 'drawer' : 'menu';
}
})();
Vos choix de confidentialité
Comme décrit dans notre Politique de confidentialité, nous recueillons des renseignements personnels à partir de vos interactions avec nous et notre site web, notamment par le biais de témoins (cookies) et de technologies similaires. Nous pouvons également partager ces renseignements personnels avec des tiers, y compris des partenaires publicitaires. Nous le faisons afin de vous présenter sur d’autres sites web des publicités plus pertinentes par rapport à vos intérêts et pour d’autres raisons décrites dans notre politique de confidentialité.
Le partage de renseignements personnels à des fins de publicité ciblée basée sur votre interaction sur différents sites web peut être considéré comme une « vente », un « partage » ou une « publicité ciblée » en vertu de certaines lois sur la protection de la vie privée des États américains. Selon l’endroit où vous vivez, vous pouvez avoir le droit de refuser ces activités. Si vous souhaitez exercer ce droit de refus, veuillez suivre les instructions ci-dessous.
Si vous visitez notre site web avec le signal de préférence de désactivation du contrôle global de la confidentialité activé, selon l’endroit où vous vous trouvez, nous traiterons cela comme une demande de désactivation de l’activité qui peut être considérée comme une « vente » ou un « partage » de renseignements personnels ou d’autres utilisations qui peuvent être considérées comme de la publicité ciblée pour l’appareil et le navigateur que vous avez utilisés pour visiter notre site web.