Badges: switch to transform-based print centering — fixes Firefox physical printer shift

This commit is contained in:
Scott Idem
2026-03-12 18:08:27 -04:00
parent bc23e8a399
commit 5410bb4a8c
2 changed files with 54 additions and 47 deletions

View File

@@ -162,13 +162,10 @@
<style>
@media print {
/* Full-page reset.
app.css sets `overflow: hidden` on html + body globally. In print,
with display:contents dissolving the intermediate wrappers, body's
only remaining content is the badge (~3.5in wide). overflow:hidden
makes body a BFC that shrinks-to-content — producing a body box that
is badge-width instead of page-width. Overriding with overflow:visible
restores normal block sizing: body fills 100% of the page width. */
app.css sets `overflow: hidden` on html + body globally — override it
so body/html fill the full page (not just the badge width). */
html, body {
display: block !important;
width: 100% !important;
height: 100% !important;
margin: 0 !important;
@@ -176,30 +173,27 @@
overflow: visible !important;
}
/* Body is the sole centering flex container.
.event_badge_wrapper is its only non-hidden flex child
once the intermediate wrappers are collapsed via display:contents. */
body {
display: flex !important;
align-items: center !important;
justify-content: center !important;
}
/* Hide app chrome */
.submenu { display: none !important; }
/* Dissolve layout wrappers so .event_badge_wrapper bubbles up to a real
centering flex container.
/* #ae_main_content becomes the positioning context for the badge.
It fills the full page (100%×100%), and the badge is absolutely
centered within it.
#ae_main_content has overflow:auto — per CSS spec, display:contents
cannot override an element that establishes overflow clipping; Firefox
(spec-compliant) keeps it as a block container, breaking centering.
Fix: reset it as an explicit 100%×100% pass-through flex container
instead. Chrome applies this too (belt-and-suspenders). */
Why not flex: Firefox respects the printer driver's minimum hardware
margins even with @page { margin: 0 }. This makes the available
content area slightly smaller than 100%, throwing off flex centering.
CSS transform-based centering (translate -50%,-50%) is immune to
this: it centers relative to the containing block dimension, which
Firefox computes correctly even when printer margins are applied.
Why not display:contents on this element: #ae_main_content has
overflow:auto. Per spec, display:contents cannot override an element
with overflow clipping; Firefox keeps it as a block box. We reset it
to a positioned block instead. */
#ae_main_content {
display: flex !important;
align-items: center !important;
justify-content: center !important;
position: relative !important;
display: block !important;
width: 100% !important;
max-width: none !important;
height: 100% !important;
@@ -211,17 +205,20 @@
}
/* .main_content and #badge_render_area have no overflow constraints,
so display:contents works on all browsers — they dissolve their boxes
and .event_badge_wrapper becomes a direct flex child of #ae_main_content. */
so display:contents dissolves their boxes in all browsers.
.event_badge_wrapper emerges as a direct child of #ae_main_content. */
.main_content,
#badge_render_area {
display: contents !important;
}
/* Badge wrapper: reset screen-only mx-auto; the @page size = badge size
so margin: 0 fills the page exactly.
gap/padding are stripped to eliminate any whitespace bleed. */
/* Center the badge using CSS transforms — the most reliable cross-browser
print centering method; unaffected by printer margin variations. */
.event_badge_wrapper {
position: absolute !important;
top: 50% !important;
left: 50% !important;
transform: translate(-50%, -50%) !important;
margin: 0 !important;
padding: 0 !important;
gap: 0 !important;
@@ -245,8 +242,7 @@
outline: 4px solid blue !important;
outline-offset: -4px !important;
}
/* Red = #ae_main_content — now a real flex container (full width/height).
Should be VISIBLE and same size as body. */
/* Red = #ae_main_content — should be VISIBLE and fill the page (same as blue). */
#ae_main_content {
outline: 3px dashed red !important;
outline-offset: -6px !important;
@@ -260,7 +256,7 @@
outline: 3px dashed purple !important;
outline-offset: -12px !important;
}
/* Cyan = the actual badge — should be centered inside the red box */
/* Cyan = the actual badge — should be dead-center */
.event_badge_wrapper {
outline: 3px solid cyan !important;
outline-offset: 2px !important;