Creating a Magento 2 Theme

In order to understand the way theming is done, you should know how to work with Less, CSS,
XML, and PHP.

Creating a new theme

In this sample theme, the files are located in app/design/frontend/<Vendor>/<Theme> .

When a theme is installed through Composer, it will be installed in the vendor directory.

The following are the steps to create a new theme:

  1. First, we start by creating the theme definition file:
<?xml version="1.0"?>
<theme xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
<title>Magento2 Training Sample Theme</title>
  1. Create preview.png for how your theme will look like. (This file needs to be present, but you can start with a blank file and replace this later when your theme is done.) Place this preview image under app/design/frontend/Nhd/default/media/ .
  2. In order to have it installable through Composer, we need to create a composer.json file:

"name": "genmato/sample-theme",
"description": "Nhd Sample Theme",
"require": {
"php": "~5.5.0|~5.6.0|~7.0.0",
"magento/theme-frontend-blank": "100.0.*",
"magento/framework": "100.0.*"
"type": "magento2-theme",
"version": "1.0.0",
"license": [
"autoload": {
"files": [

  1. In order to register the theme when loaded through Composer, it needs registration.php :
  1. Create a static file directory structure in your theme:
  1. Define your logo file and size:

<?xml version="1.0"?>
<page xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<referenceBlock name="logo">
<argument name="logo_file" xsi:type="string">
<argument name="logo_img_width" xsi:type="number">
<argument name="logo_img_height" xsi:type="number">
<referenceBlock name="report.bugs" remove="true"/>

  1. Place your logo file in app/design/frontend/Genmato/default/web/images/; in this example, an SVG is used but you can also define a PNG or JPG file
  2. It is possible to configure your own image sizes for the different images; when generating the static content, all images will be created in the width/height configured in this file:
<?xml version="1.0"?>
<view xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/view.xsd">
<images module="Magento_Catalog">
<image id="category_page_grid" type="small_image">
  1. Create your theme style (Less) file. In this file, all overrides for styles used in the blank theme and Magento UI framework can be specified. This can be used to change default colors in your theme:
@page__background-color: @color-gray20;
@primary__color: @color-gray80;
@genmato__green: #009A4E;
@genmato__blue: #0089CF;
@link__color: @genmato__green;
@link__hover__color: darken(@link__color, 10%);
@button-primary__background: @genmato__green;
@button-primary__border: darken(@genmato__green, 40%);
@button-primary__color: @color-black;
@button-primary__hover__background: darken(@genmato__green, 10%);
@button-primary__hover__border: darken(@genmato__green, 50%);
@button-primary__hover__color: @color-black;
@navigation__background: @genmato__blue;
  1. After all the files are uploaded to the Magento 2 installation, refresh the cache:
    bin/magento cache:clean
  2. Next, generate the static content:
    bin/magento setup:static-content:deploy

You can rerun this command every time you make changes to your theme and need to regenerate the CSS from the Less files. Make sure that you remove your theme-generated files from the following locations:
pub/static/frontend/<Theme Vendor>
var/view_preprocessed/css/frontend/<Theme Vendor>

Otherwise, the changes in the Less files in your theme will not be used as the preprocessor checks if there is already a generated CSS file available.
Check the Using Grunt for CSS changes section of this tutorial on how to use live reloading of CSS changes without the need of recompiling.

  1. The theme should now be available to select for your store. In order to change the theme, go to the following:
    Stores | [General] Design | Design Theme
    Choose the newly created theme from the drop-down list and save the configuration change.
  2. Navigate to your store frontend and check whether the new theme is visible.

How does these new Magento theme work?

The theme configuration in Magento 2 is more powerful than in Magento 1, allowing you to have better control on changing elements that are available from installed modules. The way in which the fallback is configured makes it easier to create different variants of a theme by defining the parent theme only. During compilation of the theme, all the files are gathered from the right parent and merged into your theme. This improves page rendering as there is no more layout merging done. All static elements such as CSS and images are pregenerated. Building themes for distribution and changing them afterward is now also much easier and can be done without modifying the bought theme.

During the bin/magento setup:static-content:deploy command, the system collects all the Less files from the following:

  • Current active theme
  • The defined parent theme(s); this is done recursively for all parents until there is no parent defined
  • The module files

Next, it will use the built-in PHPLess module to merge all these files into the configured CSS files. In this example, it generated a styles-m.css and styles-l.css as configured in the blank theme ( Magento/blank/Magento_Theme/default_head_blocks.xml ):

<page xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<css src="css/styles-m.css" />
<css src="css/styles-l.css" media="screen and (min-width: 768px)"/>
<css src="css/print.css" media="print" />

The styles files are built from styles-m.less and styles-l.less (found in Magento/blank/web/css/ ) and define all the Less files that should be included. The two files are the definition files for the mobile and desktop versions of the layout. These external Less files are included through the default @import command used in Less. They also contain a special @magento_import command (which has to be commented out in order to avoid breaking the Less preprocessor). During compilation of the theme, Magento replaces these imports with a regular @import command but with a resolved path to the corresponding file location based on the fallback file found. During compilation, all files are stored at the pub/static/frontend/<Vendor>/<theme> location and served as static files to improve load times.

Adding theme variants

Creating a variant of a theme, for example, for seasonal promotions, is easy to add. Here, it is only necessary to create a new theme that has a parent to the default/normal theme; all separate themes need to be located in their own directories. The theme only needs the files that are different from the parent theme; this can be just CSS changes or static files used as backgrounds in the theme.

Layout files

In Magento 2, the layout files are split per layout handle; this makes it easier to modify a specific page only. A layout handle is a unique identifier for the layout definitions that are used to build the page. There are three different types of layout handles:

  • page type layout handles: These identify the page based on the full action names of the controller ( customer_account_create )
  • page layout handles: These are added identifiers based on a product type shown ( catalog_product_view_type_downloadable )
  • custom handles: These are added custom identifiers not referencing to any page

Every file is located in the corresponding Module directory, so for the customer_account_create page handle, the layout file would be located in [Theme Directory]/Magento_Customer/layout/customer_account_create.xml . In the design and building of the pages, the layout is configured based on containers and defines the basic structure of a page (such as the header, footer, and columns—left, main, and right). In the containers, the content is added using blocks ; every block has a template and block class assigned that is used to render the HTML for that block. It is possible to have multiple blocks assigned to a single container, allowing you to assign the order in which they must be shown. During generation, all layout files are merged together for each layout handle, allowing you to modify the output in the theme without the need of including the complete original files from the module.

Template files

Template files are phtml files containing the HTML and PHP code to build the specified content. In order to change or add data with a template in your theme, you will need to copy the original template file to your theme, for example, to change the account registration form, the <customer-module-dir>/view/frontend/templates/form/register.phtml file needs to be copied to <theme-dir>/Magento_Customer/templates/form/register.phtml and can be edited there.

Magento UI library

In Magento 2, there is a UI library available that includes basic interface CSS-class elements that can be used in the templates. The following components are available:

  • actions-toolbar
  • breadcrumbs
  • buttons
  • drop-downs
  • forms
  • icons
  • layout
  • loaders
  • messages
  • pagination
  • popups
  • ratings
  • sections
  • tabs and accordions
  • tables
  • tooltips
  • typography
  • list of theme variables

The CSS definition of all these elements can be altered to find out what variables to alter; check out <magento-root>/lib/web/css/source/lib/variables . In order to modify the way an element is rendered, you can look up the required variable and add your own definition in the <theme-directory>/web/css/source/_theme.less theme file.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s