Magento theming is built on two inheritance systems working together: theme fallback (child themes override parent templates) and LESS preprocessing (variables and mixins compiling to CSS). Used properly, you change a brand’s look with variables, not 3,000 lines of overriding CSS. Used badly, you inherit a specificity war that makes every upgrade painful. Here is the clean path.
Theme Inheritance Basics
A theme declares its parent in theme.xml:
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<title>Acme Theme</title>
<parent>Magento/luma</parent>
</theme>
The fallback chain for every asset: child theme, parent theme, module view files. Override by placing the same relative path in your theme - Magento_Catalog/templates/product/view.phtml in your theme replaces core’s. The discipline: override the smallest unit that achieves the change - a template, not a layout; a block class via plugin, not a template rebuild.
The LESS Layers
Magento’s LESS compiles from several sources, in cascade order:
- Library variables (
lib/web/css/source/lib/variables) - the base design tokens - Module variables and styles per module
- Theme
_theme.less/_extend.less- your customisation layer
The two theme files differ crucially:
web/css/source/_theme.less: variable overrides - change@color-primary,@button__border-radius, typography scales here. This is the 80 percent case: Luma is extensively variable-driven, and most branding needs no new CSS at allweb/css/source/_extend.less: additional styles layered on top - new components, layout tweaks. New CSS lives here, not by overriding library files
The Anti-Patterns to Refuse
- Copying core
.lessfiles into the theme to edit them: you fork the file and freeze upstream fixes. Override variables or extend - never copy !importantescalation: every!importantis a specificity debt that the next!importantmust outbid. If you need it, you are fighting the cascade instead of using it- Styling by overriding module LESS with heavier selectors: prefer the module’s own variables and mixins; most Magento modules expose them
- Editing
pub/staticdirectly: generated output - gone on next deploy, and a classic staging-vs-production mystery
A Sensible Structure
app/design/frontend/Acme/theme/
web/css/source/_theme.less # variable overrides
web/css/source/_extend.less # genuinely new styles
web/css/source/_typography.less # fonts
Magento_Catalog/... # template overrides, minimal count
Compile with the standard toolchain (setup:static-content:deploy or the frontools/grunt workflow in dev), and purge static caches when LESS changes seem invisible - nine times out of ten it is var/view_preprocessed or browser cache.
Theme inheritance done right means your theme is a thin, legible layer: variables for the brand, a handful of template overrides, minimal new CSS. Thin layers upgrade cheaply - thick ones are why some stores fear theme updates.