I am using below code to include my custom CSS file in home page only:
File: app/design/frontend/[Package]/[Theme]/Magento_Theme/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">
<head>
<css src="Magento_Theme::css/home/slider.css" />
</head>
</page>
This includes the css/home/slider.css
file in the HTML but which loads before style-l.css
and after style-m
files included by Magento. I need my CSS file to be included after the style-m.css
and style-l.css
loaded by Magento.
Magento loads its style CSS files via default_head_blocks.xml
which I believe if I use in my case, it will load my custom CSS style in every page which I don't want at all.
So how can achieve the desired behavior via layout updates?
EDIT
As Kishan's answer points out, adding media="all"
did the trick. But I would like to know how that magic happens.
Best Answer
Here is the short answer:
In Details
First of all, There are lot of things happens behind the scene. So in order to make this answer abbreviated as possible, I would love to consider an example here.
Suppose I have 2 layout files as shown below:
File:
vendor/magento/theme-frontend-blank/Magento_Theme/layout/default_head_blocks.xml
and
File:
app/design/frontend/[Package]/[Theme]/Magento_Theme/layout/cms_index_index.xml
With that said, this is how page layout builder
build()
method looks like:Class:
Magento\Framework\View\Layout\Builder
Builder::loadLayoutUpdates()
readsdefaul_head_blocks.xml
first and then readscms_index_index.xml
. As a result, the css assets which will be considered in the following order.This data will be provided to the HEAD config generator class (
Magento\Framework\View\Page\Config\Generator\Head
) and in theprocess()
method all the HEAD assets (This include js, css and meta etc.) will go through different processes such as adding assets, removing assets, processing meta data etc.Addition of assets into the structure happens in
Magento\Framework\View\Page\Config\Generator\Head::processAssets()
Here both
$this->pageConfig->addPageAsset()
andthis->pageConfig->addRemotePageAsset()
will create asset groups based on the asset property and then append the assets to any one of the asset group based on its property..An asset property is an an array of attribute values other than
src
attribute.For example, in the case of the asset
<css src="css/print.css" media="print"/>
, the asset property will be["media" => "print"]
.Each asset group is an instance of
Magento\Framework\View\Asset\GroupedCollection
and the methodMagento\Framework\View\Asset\GroupedCollection::add()
is what creates the asset group creation (if needed) and assignation of assets into the groups.So for the above scenario, 3 groups will be created.
1. Asset Group (
[]
) Holds:2. Asset Group (
["media" => "screen and (min-width: 768px)"]
) Holds:3. Asset Group (
["media" => "print"]
) Holds:As you can see above since the asset property of the asset
Magento_Theme::css/home/slider.css
andcss/styles-m.css
are the same (ie an empty array), both of them will be grouped together. Since this the first group asset which is created, all the assets in that group asset will be rendered first.So in the above case, the asset rendering order will be:
Another Example
Now if our css are configured in the below order:
Then the asset grouping will be like this:
1. Asset Group (
[]
) Holds:2. Asset Group (
["media" => "screen and (min-width: 768px)"]
) Holds:3. Asset Group (
["media" => "print"]
) Holds:4. Asset Group (
["media" => "all"]
) Holds:and hence the css rendering order will be: