How does the header is created? What options exist?
# Header Background System Documentation
## Overview
The header background system allows dynamic, field-driven header backgrounds on Drupal pages with support for images (media) or gradients, customizable heights, overlays, text positioning, animations, and a parallax scrolling effect.
---
## Drupal Field Configuration
The system reads configuration from the following Drupal node fields:
### Required Fields
| Field Name | Type | Description |
|------------|------|-------------|
| `field_header_activation` | List (text) | Controls whether header is active and what type. Values: `none`, `media`, `gradient` |
### Optional Fields
| Field Name | Type | Description |
|------------|------|-------------|
| `field_header_media` | Media reference | The background image (when activation = `media`) |
| `field_header_gradient` | List (text) | Gradient name from predefined list (when activation = `gradient`) |
| `field_header_text` | Text (formatted) | The headline text to display. Supports token replacement. |
| `field_header_height` | List (text) | Height option: `slim`, `standard`, `statement`, `full` |
| `field_header_overlay` | List (text) | Overlay type: `none`, `black_transparent`, `black_transparent_center`, `white_transparent`, `white_transparent_center` |
---
## Height Options
Heights are defined as: **menu height + visible content area**
| Option | Desktop Visible Area | Mobile Visible Area | Use Case |
|--------|---------------------|---------------------|----------|
| `slim` | 120-200px (14.6dvh) | 100-180px (18dvh) | Minimal headers, breadcrumb-style |
| `standard` | 180-320px (23.6dvh) | 150-280px (28dvh) | Default, balanced appearance |
| `statement` | 300-520px (38.2dvh) | 250-450px (42dvh) | Prominent, impactful headers |
| `full` | 100dvh (full viewport) | 100dvh | Hero-style, full-screen |
**CSS File:** `/css/components/header-heights.css`
---
## Overlay Options
| Value | Effect |
|-------|--------|
| `none` | No overlay |
| `black_transparent` | Uniform 40% black overlay |
| `black_transparent_center` | Radial gradient - darker in center, fading to edges |
| `white_transparent` | Uniform 40% white overlay |
| `white_transparent_center` | Radial gradient - lighter in center, fading to edges |
**CSS File:** `/css/components/header-overlays.css`
---
## Available Gradients
Predefined gradients in `/css/gradients.css` and mapped in `upmarkit_theme.theme`:
- `amethyst-erde`, `aprikose-preussen`, `aprikose-smaragd`
- `flieder-preussen`, `flieder-rubin`
- `heide-rubin`, `heide-smaragd`
- `himmel-erde`, `himmel-himmel-erde`, `himmel-kornblume`, `himmel-rubin`
- `licht-amethyst`, `licht-rubin`, `licht-zinnober`
- `meer-rubin`, `meer-smaragd`, `meer-zinnober`
- `smaragd-aquamarin`, `smaragd-erde`
---
## Parallax Effect
### How It Works
The parallax effect makes the header text scroll slower than the background, creating depth.
**Implementation:** JavaScript-based (`/js/header-parallax.js`)
**Why JavaScript instead of CSS:**
- CSS `position: sticky` is blocked by `clip-path` and `overflow: hidden` on media/image backgrounds
- JavaScript provides consistent behavior for both gradients and media
- Allows smooth, configurable easing effects
### Technical Details
| Setting | Value | Description |
|---------|-------|-------------|
| Parallax Strength | 0.35 | Text moves at 35% of scroll speed |
| Transition | 0.5s | Duration of smooth movement |
| Easing | cubic-bezier(0.22, 0.61, 0.36, 1) | Smooth, lazy deceleration |
### Behavior
1. **Initial State:** Text is vertically centered in the visible area (below menu) via CSS flexbox
2. **On Scroll Down:** Text moves down slower than the page scrolls (parallax effect)
3. **On Scroll Up:** Text smoothly returns to centered position with lazy easing
4. **Boundaries:** Text stays within the header container (overflow: hidden)
---
## Animation Sequence
On page load, header elements animate in sequence:
| Element | Animation | Duration | Delay |
|---------|-----------|----------|-------|
| Background layer | Fade down | 0.35s | 0s |
| Image/Gradient | Fade in | 0.35s | 0.05s |
| Overlay | Fade in | 0.3s | 0.1s |
| Text content | Fade up | 0.5s | 0.15s |
**Defined in:** Inline `<style>` block in `page.html.twig`
---
## File Structure
```
/app/
├── css/
│ ├── components/
│ │ ├── header-heights.css # Height options + content centering
│ │ └── header-overlays.css # Overlay styles
│ ├── gradients.css # Gradient class definitions
│ └── style.css # Base styles (compiled Tailwind)
├── js/
│ └── header-parallax.js # Parallax effect
├── templates/
│ └── page.html.twig # Header rendering template
├── config/
│ └── header-backgrounds.yml # Legacy fallback config (deprecated)
├── upmarkit_theme.libraries.yml # Asset definitions
└── upmarkit_theme.theme # PHP preprocessing (field → template)
```
---
## PHP Processing Flow
**File:** `upmarkit_theme.theme`
### Function: `upmarkit_theme_preprocess_page()`
1. Checks if current page is a node
2. Reads `field_header_activation` value
3. If `none` or empty → no header background
4. If `media` → reads `field_header_media`, extracts image URL
5. If `gradient` → reads `field_header_gradient`, maps to CSS value
6. Reads other fields (height, overlay, text)
7. Builds `$header_background` array
8. Passes to template as `header_background` variable
### Fallback Behavior
If no node fields are set, the system falls back to `/config/header-backgrounds.yml` for path-based configuration (legacy, to be removed).
---
## Template Structure
**File:** `page.html.twig`
```twig
<section class="header-background [height-class] [has-parallax]">
<!-- Background Layer -->
<div class="header-bg-layer">
<!-- Image OR Gradient -->
<div class="header-bg-image/gradient">...</div>
<!-- Overlay (if set) -->
<div class="header-bg-overlay [overlay-type]">...</div>
</div>
<!-- Content Layer -->
<div class="header-bg-content">
<div class="site-container">
<div class="header-bg-headline">
{{ headline text }}
</div>
</div>
</div>
</section>
```
---
## CSS Class Reference
### On `.header-background` section:
- `header-height-slim/standard/statement/full` - Height option
- `has-parallax` - Added for media backgrounds (enables clip-path)
### On `.header-bg-content`:
- Flex container for centering
- `padding-top: var(--header-h)` - Pushes content below sticky menu
### On `.header-bg-headline`:
- Contains the actual text
- Parallax transform applied here via JS
### On `.header-bg-overlay`:
- `header-bg-overlay-black-transparent`
- `header-bg-overlay-black-transparent-center`
- `header-bg-overlay-white-transparent`
- `header-bg-overlay-white-transparent-center`
---
## Key CSS Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `--header-h` | 100px | Menu/header bar height |
| `--header-h-scrolled` | 64px | Menu height when scrolled |
---
## Troubleshooting
### Parallax not working on media/images
- Check that `clip-path` is not being overridden
- Verify JS file is loading (check browser console for errors)
### Text not centered
- Ensure `header-heights.css` is loaded after `style.css` (check library weights)
- Verify `.header-bg-content` has flex centering rules
### Animations not playing
- Check for `prefers-reduced-motion` media query (removed for this implementation)
- Verify inline styles in `page.html.twig` are present
### Gradient not showing
- Check gradient name matches exactly (case-sensitive, use hyphens)
- Verify `_upmarkit_theme_get_gradient_css()` function has the gradient mapped
---
## Future Improvements (Backlog)
1. **Extract inline animations** to separate CSS file for maintainability
2. **Remove legacy YAML fallback** once field-based system is confirmed stable
3. **Add parallax strength field** to allow per-page customization
4. **Add more animation options** (slide-up, zoom, etc.)