Theme Hierarchy and Inheritance
Magento 2 uses a parent-child theme inheritance system that allows themes to extend other themes without duplicating code.
Default theme hierarchy:
Magento/blank (base theme)
└── Magento/luma (extends blank)
└── Your/CustomTheme (extends luma)
Theme inheritance benefits:
- Custom themes only override what needs to change
- CSS and JS from parent themes are inherited
- Templates can be overridden selectively
- Reduces code duplication significantly
theme.xml configuration:
<!-- app/design/frontend/Vendor/custom_theme/theme.xml -->
<?xml version="1.0"?>
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
<title>Custom Theme</title>
<parent>Magento/luma</parent>
<media>
<preview_image>media/preview.png</preview_image>
</media>
</theme>
Registration:
<?php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::THEME,
'frontend/Vendor/custom_theme',
__DIR__
);
Theme fallback order:
- Custom theme directory
- Parent theme directory
- Magento/blank theme
- Module view directory (
view/frontend/)
This means a template in Vendor/Theme/Magento_Catalog/templates/product/list.phtml overrides the same template in any parent theme or the module itself.
Theme Directory Structure
A custom theme follows a specific directory structure to organize its components.
app/design/frontend/Vendor/custom_theme/
├── registration.php # Theme registration
├── theme.xml # Theme configuration
├── media/
│ └── preview.png # Theme preview image
├── etc/
│ └── view.xml # View configuration (images, fonts, etc.)
├── web/
│ ├── css/ # Custom stylesheets
│ │ ├── source/ # LESS source files
│ │ └── custom-theme.css # Compiled CSS
│ ├── js/ # JavaScript files
│ ├── images/ # Theme images
│ └── fonts/ # Custom fonts
├── Magento_Catalog/ # Module-specific overrides
│ ├── templates/
│ │ └── product/
│ │ └── list.phtml
│ ├── layout/
│ │ └── catalog_product_view.xml
│ └── web/ # Module-specific CSS/JS
├── Magento_Checkout/
│ └── ...
└── i18n/ # Translation files
├── en_US.csv
└── fr_FR.csv
Module override directories (e.g., Magento_Catalog/) contain:
- templates/ - Override module templates
- layout/ - Override or extend layout XML
- web/css/ - Module-specific styles
- web/js/ - Module-specific JavaScript
Files in a theme's module directory take precedence over the module's own files and any parent theme's files for that same module.
view.xml Configuration
The view.xml file configures theme-specific settings like image sizes, fonts, and CSS/JS assets.
<!-- app/design/frontend/Vendor/custom_theme/etc/view.xml -->
<?xml version="1.0"?>
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/view.xsd">
<resources>
<font>
<file>fonts/custom-font.woff2</file>
</font>
<css>
<file>css/custom-theme.css</file>
</css>
<js>
<file>js/custom.js</file>
</js>
</resources>
<vars module="Magento_Catalog">
<var name="product_image">
<var name="width">240</var>
<var name="height">300</var>
</var>
</vars>
<images module="Magento_Catalog">
<image id="product_page_image_small" type="small_image">
<width>135</width>
<height>135</height>
</image>
<image id="product_page_main_image" type="image">
<width>700</width>
<height>700</height>
<constraint>true</constraint>
</image>
<image id="product_page_image_medium" type="image">
<width>500</width>
<height>500</height>
</image>
</images>
<migration>
<increment_suffix>inherit</increment_suffix>
</migration>
</theme>
Key configuration areas:
- resources - CSS, JS, and font files to load
- vars - Module-specific variables (image sizes, colors, etc.)
- images - Image dimensions for different contexts
- migration - Settings for theme migration from older versions
Template and Layout Overrides
Themes can override templates and layout files from any module or parent theme.
Template override example:
To override Magento_Catalog/templates/product/list.phtml:
app/design/frontend/Vendor/custom_theme/Magento_Catalog/templates/product/list.phtml
Layout override example:
To override the product page layout:
<!-- app/design/frontend/Vendor/custom_theme/Magento_Catalog/layout/catalog_product_view.xml -->
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product.info">
<action method="setTemplate">
<argument name="template" xsi:type="string">
Vendor_CustomTheme::product/view.phtml
</argument>
</action>
</referenceBlock>
</body>
</page>
Layout handle override for homepage:
<!-- app/design/frontend/Vendor/custom_theme/Magento_Cms/layout/cms_index_index.xml -->
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd"
layout="2columns-right">
<body>
<referenceContainer name="content">
<block class="Magento\Cms\Block\Block" name="custom.hero">
<arguments>
<argument name="block_id" xsi:type="string">custom-hero-block</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
Best practices for theme customization:
- Create a child theme rather than modifying parent themes
- Override only the files that need changes
- Use layout XML to move/add blocks rather than template edits
- Keep module-specific overrides in the correct module directory
Quiz
1. What is the fallback order for template resolution in Magento 2?
2. Where do you put CSS files specific to the catalog module in a theme?
3. What file configures image sizes and fonts for a theme?
Flashcards
Question
What parent theme does Magento/luma extend?
Click to reveal answer
Answer
Magento/blank
Question
Where are theme translation files placed?
Click to reveal answer
Answer
i18n/ directory in the theme root
Question
How do you override a template in a child theme?
Click to reveal answer
Answer
Place the template in the same relative path under the theme directory
Question
What is the theme media preview image used for?
Click to reveal answer
Answer
Displaying the theme in the admin theme selector
Revision Notes
Key Takeaways
- 1. Themes use parent-child inheritance (blank → luma → custom)
- 2. Theme files override parent and module files via fallback
- 3. view.xml configures image sizes, fonts, and CSS/JS assets
- 4. Module-specific overrides go in {ModuleName}/ directories
- 5. Layout XML and templates are overridden independently
- 6. Themes registered via registration.php with ComponentRegistrar::THEME
Interview Tips
- • Explain the theme inheritance hierarchy and fallback mechanism
- • Describe how to create a custom theme from scratch
- • Discuss when to override templates vs layout XML
- • Explain the view.xml configuration options
- • Know the directory structure for theme module overrides
Cheat Sheet
Theme Cheat Sheet
Theme Path: app/design/frontend/{Vendor}/{theme}/
Registration: ComponentRegistrar::THEME
Config: theme.xml + etc/view.xml
Inheritance: blank → luma → custom
Override Order:
- Custom theme/{Module}/
- Parent theme/{Module}/
- Module view/frontend/
Module Override Dir:
{Theme}/{ModuleName}/
├── templates/
├── layout/
└── web/
├── css/
└── js/