Magento – Change the order of CSS files. Load module’s CSS before theme’s CSS

configurationfrontendlayoutmoduletheme

How can I change the order of CSS files to load module's CSS before theme's CSS? Here are some code examples:

Theme's CSS file (loaded on all pages) added in theme's local.xml:

<default>
    <reference name="head">
        <action method="addItem">
            <type>skin_css</type>
            <name>css/theme.css</name>
        </action>
    </reference>
</default>

Extension's CSS file (loaded only on category pages) added in module's XML layout file:

<catalog_category_layered>
    <reference name="head">
        <action method="addItem">
            <type>skin_css</type>
            <name>css/extension.css</name>
        </action>
    </reference>
</catalog_category_layered>

This is the order of loaded CSS files which I get on the category page, extension's CSS is loaded after theme's CSS:

  • /default/mytheme/css/styles.css
  • /default/mytheme/css/theme.css
  • /default/mytheme/css/extension.css

What I'm trying to achieve: extension's CSS is loaded before theme's CSS.
How can I force this order of CSS files:

  • /default/mytheme/css/styles.css
  • /default/mytheme/css/extension.css
  • /default/mytheme/css/theme.css

I've noticed that if I have many extensions installed, CSS of some extensions loads before theme's CSS and CSS of some other extensions loads after theme's CSS. I assume that it has something to do with the order of modules in Magento, but I don't understand how I can affect the order of CSS (or JavaScript) files on the frontend.

EDIT:

About philwinkle's answer:

but in this case I can't do something like this because it would add layout of the category page to all pages (that CSS file is needed only on category page):

<layout>
    <default>
        <update handle="catalog_category_layered" />
    </default>
    
    <catalog_category_layered>
        <reference name="head">
            <action method="addItem"><type>skin_css</type><name>css/extension.css</name></action>
        </reference>
    </catalog_category_layered>
</layout>

Can this solution be adjusted to my case somehow?

Best Answer

@benmarks has a great approach from this SO thread - though his example is for Javascript it can be adapted for CSS, too:

https://stackoverflow.com/questions/12610949/magento-module-layout-xml-load-order

Another option to try would be to use an directive in your custom module layout XML, as the directives in an are processed before the other directives. This means that jQuery will load before all other files.

<?xml version="1.0" encoding="UTF-8"?>
<layout>
    <default>
        <update handle="add_css_first" />
    </default>

    <add_css_first>
        <action method="addCss" block="head">
            <link>css/custom-styles.css</link>
        </action>
    </add_css_first>
</layout>

There are also community modules which exist to allow you to set an explicit sort-order with a rewrite of page/html_head:

https://github.com/drewhunter/ItemPosition

Which allows you to do this sort of customization:

 <reference name="head">
        <action method="setLast">
            <last>css/custom-styles.css</last>
        </action>
 </reference>