Skip to content
intermediate Phase 17 · Themes, Libraries & Generated Code

Magento 2 Themes

Theme hierarchy, parent/child themes, theme inheritance, theme configuration, and custom themes.

45m
0 problems
Topic Progress 0%

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:

  1. Custom theme directory
  2. Parent theme directory
  3. Magento/blank theme
  4. 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?

Question 1 options

2. Where do you put CSS files specific to the catalog module in a theme?

Question 2 options

3. What file configures image sizes and fonts for a theme?

Question 3 options

Flashcards

Question

What parent theme does Magento/luma extend?

Answer

Magento/blank

Question

Where are theme translation files placed?

Answer

i18n/ directory in the theme root

Question

How do you override a template in a child theme?

Answer

Place the template in the same relative path under the theme directory

Question

What is the theme media preview image used for?

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:

  1. Custom theme/{Module}/
  2. Parent theme/{Module}/
  3. Module view/frontend/

Module Override Dir:

{Theme}/{ModuleName}/
├── templates/
├── layout/
└── web/
    ├── css/
    └── js/