Magento 2: style-m.css vs style-l.css

These files are generated through LESS.

In theory style-m.css should have less code and to have styles only for mobile devices than style-l.css in order to load on mobile devices faster.

This is not completely correct. The styles-m.css contains CSS rules for both mobile and desktop and thus is generally bigger than the styles-l.css which contains rules for desktop. However, the goal is still this same, this way, mobile devices do not need to download CSS rules for desktop devices.

Regarding the question of how styles can be "placed" in either of those files, this is done via the Magento UI library media queries which help Magento create these two files from your LESS rules.

To give you an example, a media block like the following one would be placed in styles-m as both desktop and mobile devices have rules within this block "in common":

& when (@media-common = true) {
  h1 {
    font-size: 12px;
  } 
}

A media query block like this would be for devices which have a min resolution of "screen_xs", which are mobile devices with a screen resolution of 480px and bigger, meaning it would still be placed in styles-m but would not necessarily affect all mobile devices:

.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__xs) {
  h1 {
    font-size: 18px;
  }  
}

Changing the (@extremum = 'min') to (@extremum = 'max') would change the rule to its opposite and thus only affect devices with a width smaller than 480px.

And a block like this would only concern desktop devices and thus be placed in styles-l, as everything 'above' screen__m is considered a desktop device (by default):

.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
  h1 {
    font-size: 24px;
  }  
}

You can read more about these break points in the Magento developer guide.


According to the default_head_blocks.xml in the blank theme layout:

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <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"/>
    </head>
</page>

From what I understand, styles-l.css is only applied for large screens (above 768px) and styles-m.css is applied all the time.

So that's the reason why styles-m.css have more code because it contains the mobile code as well as the code that applies whatever the screen width is. styles-l.css only contains the code for larger screens.


You define that with your media query functions and less guard functions. For example & when (@media-common = true) { ... } go to styles-m.css because those styles should be available everywhere.

Speaking about media queries, this goes to the desktop file:
.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {}

You might want to check my Slides on how to deal with styles here:
https://slidr.io/toh82/how-to-deal-with-styles-in-magento-2#1