Before we dive in to create our own custom child theme in Magento, a little about why there is need to create a custom child theme in Magento.

Magento comes with many pre-loaded features and a 100% open-source e-commerce framework. When it comes to front-end design in any of Magento themes, it may be a little bit disappointing compared to modern designs and trends.

There are three themes in Magento - base, default, and RWD. To meet the latest design trends or client requirements we may need to customize the front-end design.

There are many free and paid themes available at magentocommerce already. First look there to find best suitable design and layout that meet your expectation.

But if you do not find any then you can create your own custom theme in Magento. Let's see how can we customize the default look and feel without breaking the core.

Let's see how directories and files are organized in Magento.

app 
|---code
|---design
| |---frontend
| |---base
| |---default
| |---MyPackage
| | |---myTheme
| | |---etc
| | | |---theme.xml
| | |
| | |---layout
| | | |---local.xml
| | |
| | |---template
| |
| |---rwd
|
skin
|---frontend
|---base
|---default
| |---css
| |---images
|
|---MyPackage
|---MyTheme
|---css
| |---myStyle.css
|
|---images
|---js
|---myScript.js

Layout folder contains XML files which are used to define and control structural and content blocks of the theme.
All the theme template files are with .phtml extension and reside in app/design/frontend/{packageName}/{themeName}/template which holds the markup for each Magento blocks which are used for displaying the frontend.
Skin folder contains all the CSS, images, js, Sass etc.

Magento uses searching strategy which is quite managable. For example, if you are using MyPackage/MyTheme which is a child theme of rwd/default then to show a product, Magento will search view.phtml in the directories in following order -

1. app/design/frontend/MyPackage/MyTheme/template/catalog/product/view.phtml
2. app/design/frontend/rwd/default/template/catalog/product/view.phtml
3. app/design/frontend/base/default/template/catalog/product/view.phtml

So, there is no need to duplicate all the layout, template, and skin files across to the rwd/default theme. You should duplicate only those files that you want to modify. Any unchanged files will be located and loaded from the parent theme.

Creating Child theme

Step 1: Creating folders and file structure for Magento's child theme.

Goto app/design/frontend and create your package and following folders and files in it. You have noticed there are already three packages named - base, default, and rwd.

We are going to create a child theme of rwd theme which is responsive.

app/design/frontend/{packageName}/{themeName}/etc
app/design/frontend/{packageName}/{themeName}/etc/theme.xml
app/design/frontend/{packageName}/{themeName}/layout
app/design/frontend/{packageName}/{themeName}/layout/local.xml
app/design/frontend/{packageName}/{themeName}/template

replace the {packageName} with your package name and same for {themeName}. In our case, the package name is MyPackage and theme is MyTheme respectively.

app/design/frontend/MyPackage/MyTheme/etc
app/design/frontend/MyPackage/MyTheme/etc/theme.xml
app/design/frontend/MyPackage/MyTheme/layout
app/design/frontend/MyPackage/MyTheme/layout/local.xml
app/design/frontend/MyPackage/MyTheme/template

Magento custom theme directory structure

As we are done with files and directories now we need to tell Magento that our parent theme is rwd for MyPackage/MyTheme.
To do so open app/design/frontend/MyPackage/MyTheme/etc/theme.xml and edit the theme.xml as below -

<?xml version="1.0" ?>
<theme>
      <parent>rwd/default</parent>
</theme>

Now go to skin/frontend/ and create your package's skin folders and files as follows.

skin/frontend/MyPackage/MyTheme/css
skin/frontend/MyPackage/MyTheme/css/myStyle.css
skin/frontend/MyPackage/MyTheme/images
skin/frontend/MyPackage/MyTheme/js
skin/frontend/MyPackage/MyTheme/js/myScript.js

Step 2: Telling Magento to load the child theme's CSS and js files.

Since we have created our CSS and js files as css/myStyle.css and js/myScript.js respectively, we need to hook these files to our child theme. Open app/design/frontend/MyPackage/MyTheme/layout/local.xml and put the following XML code as it is -

<?xml version="1.0"?>
    <layout version="0.1.0">
      <default translate="label" module="page">
        <reference name="root">
        <reference name="head">
 
         <!-- Loading css/myStyle.css file -->
         <action method="addItem"><type>skin_css</type><name>css/myStyle.css</name></action>

         <!-- Loading myScript.js file -->
         <action method="addItem"><type>skin_js</type><name>js/myScript.js</name></action>
 
        </reference> 
        </reference>
     </default>
    </layout>

Similarly, we can hook multiple files to our theme like font-awsome.css etc.

Above XML will load our myStyle.css successfully but here is a problem. It hooks the CSS on very top under the head tag before all the default CSS files along with parent styles.css.
This will not allow us to override the theme customization. So to override the parent's theme design, we need to hook it after the parent's CSS. To do this we will remove the parent's styles.css first and then add it again in the below sequence. So, the updated local.xml will be -

<?xml version="1.0"?>
   <layout version="0.1.0">
     <default translate="label" module="page">
      <reference name="root">
         <reference name="head">
 
           <!-- Remove the rwd parent's styles.css file -->
           <action method="removeItem"><type>skin_css</type><name>css/styles.css</name></action>
 
           <!-- Add it again before your css/myStyle.css file -->
           <action method="addItem"><type>skin_css</type><name>css/styles.css</name></action>
 
           <!-- Loading css/myStyle.css file just after parent's styles.css -->
           <action method="addItem"><type>skin_css</type><name>css/myStyle.css</name></action>
 
           <!-- Loading myScript.js file -->
           <action method="addItem"><type>skin_js</type><name>js/myScript.js</name></action>
 
         </reference> 
      </reference>
     </default>
   </layout>

Step 3: Saving the child themes' configuration in the admin panel.

Now login to Magento admin panel and go to System > Configuration > General > Design and update as below

Package Option - 
        Current Package Name - MyPackage 
Theme option - 
        Skin (Images / CSS) - MyTheme
        Default - MyTheme

Magento custom theme admin settings


Once done save the configuration, clear the cache and reload the homepage. If everything is done carefully you will see the loaded myStyle.css and myScript.js in the source code with the URL of newly created Magento child theme package like -

http://example.com/skin/frontend/MyPackage/MyTheme/css/myStyle.css
http://example.com/skin/frontend/MyPackage/MyTheme/css/myScript.js

That is all.

We have successfully created the custom Magento child theme. Now you can safely customize the design of your theme in your myStyle.css file and all your custom JavaScripts will be in myScript.js

Note: Do not copy entire parent theme to create the child theme. Copy only those files from YourParentTheme/Default or base/default theme which you need to edit.

Magento follows the simple rule- If a file is in custom theme load it else looks for the file in the parent theme if any. If the file is not there too then it looks in the base package. So we should never play with base package and theme because that is Magento's theme fallback.