Skip to main content

Documentation

No results found.
Features

Smart Header Padding

When a page uses a fixed-style header (transparent or pill), WebProCMS automatically adds extra top padding to the first hero or section row so the header always has breathing room above it — without affecting any other row on the page.


The problem

Transparent and pill headers are position: fixed — they sit on top of the page rather than pushing content down. With no compensation, the first row on the page renders at y=0 and the floating header visually overlaps it. Static headers (clean, dark, centered) don't have this issue because they take up space in the document flow.

A naive fix — adding top padding to every section — solves the crowding but breaks the vertical rhythm between mid-page rows. A naive fix in the other direction — adding padding only to <main> — leaves a strip of body background showing above heroes that were meant to bleed under the header.

The fix

WebProCMS adds the extra padding to the first eligible <section> only, and grows the section's existing top padding rather than replacing it. The hero's background still bleeds full-bleed to the top of the page (because the section grew, not shifted), and every other row keeps its normal spacing.

Only sections with py-section-hero or py-section qualify. A py-section row that lands after a hero is never affected — the targeting uses :first-of-type, so once a hero has claimed the bump, no later section gets it.

Per-header values

Each fixed-style header declares the bump it needs. Values are added on top of the section's existing top padding, so the final result respects the row's design.

Header group Extra top padding
Transparent (E1, E2) 3rem
Pill (G1, G2) 2rem
Everything else 0 (no-op)

Transparent headers occupy 6rem at rest with zero gap to a 6rem hero; the bump opens a real gap. Pill headers float at top-4 with h-13, leaving a smaller visible footprint, so the bump is correspondingly smaller.

How it works

RowGroupRegistry::headerPad() returns the value for the active header. The public layout reads it once per request and sets --header-pad as an inline style on <body>. A CSS rule in public.css adds it to the first eligible section via calc():

main > :first-child > section.py-section-hero:first-of-type {
    padding-top: calc(var(--spacing-section-hero) + var(--header-pad, 0px));
}

When no fixed-style header is active, --header-pad is unset, the calc resolves to the section's normal token value, and there is no visual change.

What lives where

Path Purpose
app/Support/Rows/RowGroupRegistry.php headerPad() returns the bump for a given header template name.
resources/views/layouts/public.blade.php Looks up the active header's pad and sets --header-pad on <body>.
resources/css/public.css The @layer utilities rules that target the first eligible <section> and add --header-pad to its padding-top.

Notes

  • The CSS rule covers both the live page structure (main > div > section) and the page editor's preview iframe structure (main > div > [data-editor-row] > section), so the editor reflects the live result.
  • The bump never affects bottom padding — only padding-top is grown.
  • No row-level opt-in / opt-out is required. Heroes that should bleed full-bleed under the header are the default; the extra padding lives inside the hero, so the hero still extends to y=0.