16

In the Magento 2 DevDoc it says

To include a CSS file, add the <css src="<path>/<file>" media="print|<option>"/> block in <head> section in a layout file.

However it doesn't say how we can influence the order of our CSS files. And if we add CSS files this way in a custom theme which has a parent theme the result is that the files are added quite at the top of the <head> section with a lot of other CSS files below them, meaning their priority is quite low and we cannot easily override rules from the parent theme or extensions.

There were similar problems in Magento 1 and there were workarounds. Some were more clean others less.
What is the best way to order a CSS file of a custom theme at the bottom of <head> in Magento 2 - if possible complying the Magento 2 layout guidelines for custom themes?

5 Answers 5

16

Magento2 has no built-in mechanism for this so I decided to treat it as an opportunity to write my first Magento2 extension. The Quickshiftin\Assetorderer extension is now available on GitHub!

Once you have the extension installed you can specify an order attribute in your css XML tags.

<head>
  <css src="css/page/home.css" order="100"/>
</head>

You can also use the order attribute in layout XML files such as default_head_blocks.xml. Any css tags you don't specify an order for are treated as if they have an order of 1.

10
  • Many thanks. Your extension worked for me. But faced two issues one in di.xml and one in Quickshiftin\Assetorderer\View\Asset\File class. Commented May 24, 2016 at 9:27
  • Hi @PankajPareek, that's good news and bad. Any chance you can elaborate on GitHub and possibly contribute a pull request? It would be nice to make the extension useful for everyone! Commented May 24, 2016 at 12:52
  • @quickshiftin This extension worked in v2.0, but not v2.1.1. However, I found out by chance that it's no longer required in v2.1.1 because when I add order="1" the file gets ordered correctly. It doesn't matter what the attribute is as long as you add an extra attribute. To make it validate, you can change it to data-order="1" and it would still work.
    – thdoan
    Commented Oct 17, 2016 at 7:19
  • order work for js file also. Commented Sep 5, 2017 at 6:19
  • @quickshiftin have you updated your module for the M2.2.2
    – PЯINCƎ
    Commented Apr 19, 2018 at 10:52
8

You can add the media attribute to the css element. This will add it to the end of all the included CSS in the head.

<head>
    <css src="css/styles.css" media="all" />
</head>
3
  • What if I want it first? Commented Feb 21, 2017 at 9:52
  • This will still load custom CSS before main magento 2 core CSS files :( Commented Oct 11, 2017 at 17:15
  • As of M2.2.1 it is the only solution that worked for me. Adding 'order="X"' to the <css> node throw an error as this attribute is not allowed.
    – Dynomite
    Commented Mar 30, 2018 at 19:23
7

I answered in detail here about how magento renders css and how the ordering is happening behind the scene.

Some extra points I need to mention here is:

  1. If you want to render your custom css file after style-m.css and stlyle-l.css, then you need to define your css file like below:

    <css src="Magento_Theme:css/path/file.css" media="all" />
    
  2. If you want to load your custom css file before style-m.css and stlyle-l.css, then you need to include your css file through the layout xml file default_head_blocks.xml and add your custom css file above style-m.css and stlyle-l.css.

  3. CSS properties are finite and are well defined in the layout schema. According to the layout schema, you can use following properties in your css file.

    File: vendor/magento/framework/View/Layout/etc/head.xsd

    <xs:complexType name="linkType">
        <xs:attribute name="src" type="xs:string" use="required"/>
        <xs:attribute name="defer" type="xs:string"/>
        <xs:attribute name="ie_condition" type="xs:string"/>
        <xs:attribute name="charset" type="xs:string"/>
        <xs:attribute name="hreflang" type="xs:string"/>
        <xs:attribute name="media" type="xs:string"/>
        <xs:attribute name="rel" type="xs:string"/>
        <xs:attribute name="rev" type="xs:string"/>
        <xs:attribute name="sizes" type="xs:string"/>
        <xs:attribute name="target" type="xs:string"/>
        <xs:attribute name="type" type="xs:string"/>
        <xs:attribute name="src_type" type="xs:string"/>
    </xs:complexType>
    

    This simply means you cannot use order or any other properties along with css definition in your layout xml file. By doing so, you will get an exception which indicates schema validation fails.

1
  • It worked perfectly for me. Thanks Commented Jun 4, 2021 at 18:42
1

You can make your CSS rules more or less important than the core CSS rules by adding or removing additional parent selectors.
For example, let's see a sample CSS rule in the core:

.cart.table-wrapper .item .col.item {
    padding: 20px 8px 20px 0;
}

You can make your custom rule more important by adding a parent selector, for example:

body .cart.table-wrapper .item .col.item {
    padding: 10px 8px 20px 0;
}

or

body .cart.table-wrapper .item td.col.item {
    padding: 10px 8px 20px 0;
}

You can make your custom rule less important by removing a parent selector, for example:

.item td.col.item {
    padding: 30px 8px 20px 0;
}
3
  • 3
    Sure and I also could simply smack down !important (but of course your approach is still better than that) or implement a vendor prefix class with LESS. Still this adds unnecessary overhead and complexity. Why prefixing hundreds or more rules when a simple order change of the CSS would do it? So I'm still looking for a good way to solve this on the Magento side...
    – Jey DWork
    Commented Dec 24, 2015 at 15:18
  • Besides when it comes to other resources than CSS positioning might get even more important as workarounds could get even uglier.
    – Jey DWork
    Commented Dec 24, 2015 at 15:21
  • 6
    That's not an answer
    – Ahmad Alfy
    Commented Mar 17, 2016 at 14:23
1

As I am checking in Magento 2.3.4 there is a arrtibute "order" on linkType tag to achive the that.

Here is the snap of the file vendor\magento\framework\View\Layout\etc\head.xsd

enter image description here

1
  • I can confirm that Magento 2.3.5 can do this: <css src="Vendor_Module::css/test.css order="999" /> . This ensures you can change the sort order to your requirements. Commented May 31, 2021 at 13:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.