Variablen & Tokens
Das Guppy-Theme nutzt eine durchdachte SCSS-Architektur auf Bootstrap-5-Basis, ergänzt um eigene Functions, Mixins und Token-Sets. Diese Seite ist die vollständige Entwickler-Referenz.
Verzeichnisstruktur
src/Resources/app/storefront/src/scss/
├── overrides.scss # Theme-Hook (lädt vor @DmfGuppyTheme)
├── base.scss # Theme-Hook (lädt nach @DmfGuppyTheme)
├── abstract/
│ ├── functions/
│ │ ├── boolean.scss
│ │ ├── px-to-rem.scss
│ │ └── strip-unit.scss
│ ├── mixins/
│ │ ├── button-adaptive-hover.scss
│ │ ├── focus-style.scss
│ │ └── rlh.scss
│ └── variables/
│ ├── bootstrap.scss
│ └── custom.scss
├── base/ # Accessibility, Container, Typography
├── components/ # Buttons, Cards, Forms, Slider, …
├── elements/ # Skip-Link, Splide-Slider
├── layout/ # Header, Footer, USP, Navigation, …
├── page/ # Account, Checkout, Detail, …
└── skin/shopware/ # Integration in Shopware-Default-Storefront
├── abstract/variables/
│ ├── bootstrap.scss
│ ├── custom.scss
│ └── theme.scss
├── base.scss
├── base/ # base.scss, inter-fontface.scss
└── component/ # cms-block, cms-element, modal, …Build-Reihenfolge
theme.json definiert die Compile-Order:
{
"style": [
"app/storefront/src/scss/overrides.scss",
"@StorefrontBootstrap",
"@Plugins",
"app/storefront/src/scss/skin/shopware/base.scss",
"app/storefront/src/scss/base.scss"
]
}Reihenfolge zählt: overrides.scss lädt vor Bootstrap und ist damit der Ort für frühe Variablen-Overrides; base.scss lädt nach allem und enthält die finalen Selektoren-Styles.
Functions
px-to-rem($px, $base-font-size: 16px)
@function px-to-rem($px, $base-font-size: 16px) {
@return ($px / $base-font-size) * 1rem;
}
.element {
font-size: px-to-rem(18px); // 1.125rem
padding: px-to-rem(24px); // 1.5rem
}strip-unit($value)
@function strip-unit($value) {
@return ($value / ($value * 0 + 1));
}
$value: strip-unit(100px); // 100Bootstrap-Farb-Functions (verfügbar)
shade-color($color, $weight) // dunkler
tint-color($color, $weight) // heller
shift-color($color, $weight) // automatisch (basierend auf Helligkeit)Mixins
rlh($value) und line-height($value)
Responsive Line-Heights via Bootstrap-RFS:
h1 { @include line-height(1.2); }
.title { @include rlh(1.5, line-height); }focus-style
Einheitliche Focus-Styles für Barrierefreiheit:
@mixin focus-style {
outline-offset: $focus-outline-offset;
outline: $focus-outline-color solid $focus-outline-width;
box-shadow: $focus-outline-box-shadow;
}
button:focus-visible { @include focus-style; }button-adaptive-hover($base-color)
Hover-Effekte nur, wenn das Gerät tatsächlich Hover unterstützt:
@mixin button-adaptive-hover($base-color) {
&:hover {
@media (hover: hover) {
background-color: shade-color($base-color, 15%);
}
}
}text-ellipsis und text-clamp($lines)
@mixin text-ellipsis { /* einzeilig */ }
@mixin text-clamp($lines: 2) { /* mehrzeilig */ }visually-hidden
Screen-Reader-only-Inhalte:
.sr-only { @include visually-hidden; }Bootstrap-Variablen (Auszug)
Die wichtigsten Token-Familien aus abstract/variables/bootstrap.scss. Alle binden an $sw-*-Tokens, die wiederum aus der Theme-Konfiguration befüllt werden.
// Farben
$gray-100: $sw-color-gray-100 !default;
$gray-900: $sw-color-gray-900 !default;
// Typography
$font-size-base: $sw-font-size-base !default;
$h1-font-size: $sw-h1-font-size !default;
// Container und Grid
$container-max-widths: (xs: $guppy-container-width-default) !default;
$grid-gutter-width: 1.5rem !default;
// Buttons und Inputs
$btn-font-size: $sw-input-btn-font-size !default;
$btn-border-radius: $sw-input-btn-border-radius !default;
$btn-font-weight: $sw-input-btn-font-weight !default;Custom-Variablen (Auszug)
Guppy-spezifische Tokens in abstract/variables/custom.scss:
// Icons
$icon-base-size: 22px !default;
$icon-base-color: currentColor !default;
$icon-accessibility-touch-size: 44px !default;
// Produktbilder
$product-image-height: 240px !default;
$product-image-aspect-ratio: #{10/9} !default;
$product-image-background: $sw-color-product-image !default;
// Accessibility
$focus-outline-width: 2px !default;
$focus-outline-color: $sw-color-brand-primary !default;
$focus-outline-offset: 2px !default;
$focus-outline-box-shadow: 0 0 0 2px #fff;
// Lieferstatus
$guppy-delivery-shipping-free-color: #023B5A;
$guppy-delivery-shipping-free-background: #CEEDFE;
$guppy-delivery-available-color: #154634;
$guppy-delivery-available-background: #D3F2E7;
$guppy-delivery-restock-color: #5D3B00;
$guppy-delivery-restock-background: #FFEFD4;
$guppy-delivery-soldout-color: #303030;
$guppy-delivery-soldout-background: #EEEEEE;Token-Tabellen
Brand-Farben
| Variable | Default | Verwendung |
|---|---|---|
$sw-color-brand-primary | #215AFF | Primärfarbe |
$sw-color-brand-secondary | #0B1845 | Sekundärfarbe |
$sw-background-color | #FFFFFF | Hintergrund |
$sw-border-color | #CFD1D7 | Rahmen |
$sw-text-color | #1B1F29 | Textfarbe |
$sw-headline-color | #1B1F29 | Überschriften |
Graustufen
| Variable | Default | Verwendung |
|---|---|---|
$sw-color-gray-100 | #F9F9F9 | Hintergründe, Footer |
$sw-color-gray-200 | #EEEEEE | deaktivierte Elemente |
$sw-color-gray-300 | #BCC1C7 | Rahmen, Trenner |
$sw-color-gray-400 | #CED4DA | Input-Rahmen |
$sw-color-gray-500 | #ADB5BD | Platzhalter |
$sw-color-gray-600 | #798490 | Sekundärtext |
$sw-color-gray-700 | #495057 | Text |
$sw-color-gray-800 | #4A545B | Überschriften |
$sw-color-gray-900 | #212529 | Haupttext |
Typografie
| Variable | Default | Verwendung |
|---|---|---|
$sw-font-size-base | 1rem | Basis-Schriftgröße |
$sw-h1-font-size | 32px | H1 |
$sw-h2-font-size | 24px | H2 |
$sw-h3-font-size | 20px | H3 |
$sw-h4-font-size | 18px | H4 |
$sw-h5-font-size | 16px | H5 |
$sw-h6-font-size | 15px | H6 |
$sw-h1-line-height | 44px | H1-Zeilenhöhe |
$sw-h2-line-height | 36px | H2-Zeilenhöhe |
$sw-h3-line-height | 32px | H3-Zeilenhöhe |
Accessibility
| Variable | Default | Verwendung |
|---|---|---|
$focus-outline-width | 2px | Focus-Rahmenbreite |
$focus-outline-color | $sw-color-brand-primary | Focus-Rahmenfarbe |
$focus-outline-offset | 2px | Abstand zum Element |
$focus-outline-box-shadow | 0 0 0 2px #fff | zusätzlicher Schatten |
$icon-accessibility-touch-size | 44px | min. Touch-Target |
Container und Breakpoints
Bootstrap-Standard-Breakpoints:
| Breakpoint | Klassen-Infix | Dimension | Container max-width |
|---|---|---|---|
| Extra small | – | < 576 px | 100 % |
| Small | sm | ≥ 576 px | 540 px |
| Medium | md | ≥ 768 px | 720 px |
| Large | lg | ≥ 992 px | 960 px |
| Extra large | xl | ≥ 1200 px | 1140 px |
| XXL | xxl | ≥ 1400 px | 1320 px |
Guppy-Container-Padding pro Breakpoint:
$guppy-container-default-padding-x-mobile: 10px;
$guppy-container-default-padding-x-sm: 24px;
$guppy-container-default-padding-x-md: 48px;
$guppy-container-default-padding-x-lg: 48px;
$guppy-container-default-padding-x-xl: 48px;
$guppy-container-default-padding-x-xxl: 48px;Breakpoint-Mixins:
@include media-breakpoint-up(md) { /* ≥ 768 px */ }
@include media-breakpoint-down(lg) { /* < 992 px */ }
@include media-breakpoint-between(md, xl) { /* 768–1199 px */ }
@include media-breakpoint-only(lg) { /* 992–1199 px */ }Child-Theme-Overrides
In einem Child-Theme:
// overrides.scss, Variablen-Overrides
$guppy-usp-background-color: #f8f9fa !default;
$product-image-height: 300px !default;
$primary: #007bff !default;// base.scss, zusätzliche Styles
.my-custom-component {
background-color: $primary;
.title { @include line-height(1.3); }
}Reihenfolge nicht aufbrechen
Variablen müssen in overrides.scss (lädt vor Bootstrap) gesetzt werden, in base.scss greifen sie zu spät.
Best Practices
Theme-Variablen statt Hardcodes
// gut
.custom-component {
color: $sw-text-color;
background-color: $sw-color-gray-100;
}
// schlecht
.custom-component {
color: #333;
background-color: #f9f9f9;
}Bootstrap-Breakpoints statt eigene
// gut
@include media-breakpoint-up(md) { display: flex; }
// schlecht
@media (min-width: 768px) { display: flex; }Focus-Styles via Mixin
// gut
.custom-button:focus-visible { @include focus-style; }
// schlecht
.custom-button:focus { outline: 2px solid blue; }Debugging
@debug "Container width: #{$guppy-container-width-default}";
@debug "Primary color: #{$sw-color-brand-primary}";Praktisches Beispiel
// _my-component.scss
.my-component {
background-color: $sw-color-gray-100;
border: 1px solid $sw-border-color;
border-radius: $border-radius;
padding: $spacer;
.title {
font-size: $sw-h3-font-size;
@include line-height($h3-line-height);
color: $sw-headline-color;
}
@include media-breakpoint-up(md) {
display: flex;
gap: $spacer * 2;
}
&:focus-visible { @include focus-style; }
.action-button {
@include button-reset;
@include button-adaptive-hover($sw-color-brand-primary);
}
}Verwandt
- Architektur: Ordnerstruktur und Vererbungs-Reihenfolge.
- Twig-Overrides: Theme-Konfig in Templates konsumieren.
- Theme-Variablen-Referenz: Lookup-Tabelle für
theme.json-Felder.