Less fallback
在 Magento 2 如何引入 CSS 文章中说到 Magento 的 CSS 是如何组织的。在 blank 主题中,通过观察其default_head_blocks.xml
文件,可以发现两个重要的 CSS 引入。
1 | <css src="css/styles-m.css" /> |
根据 CSS 的预处理机制,我们可以知道这两个 CSS 是由<theme-frontend-blank>/web/css
下的style-l.less
和style-m.less
解析得到的。
以style-m
为例,
1 | // |
@import
指令引入了更多的 Less 文件。这些 Less 文件大部分位于当前文件目录的source
子目录下,但是@import 'source/lib/_responsive.less';
中source/lib/_responsive.less
在当前文件目录下可找不到。这是因为 Magento 使用了 theme fallback 机制,当他在当前主题中找不到某个文件时,就会一直向上搜寻父主题的目录继续找,Less 这里最终 fallback 到了<magento-root>/lib/web/css/
。
该文件中出现了一个特别的指令//@magento_import
,他其实并不是被注释掉了,这是 Magento 自己的一个指令。
1 | //@magento_import 'source/_module.less'; // Theme modules |
这段指令告诉 Magento 包含如下的 Less 文件。
1 | '<theme-dir>/Magento_Catalog/web/css/source/_widgets.less'; |
可以查看参考文档第一条,获得更详细的官方解释。
上面说到 theme fallback 机制,这里讲讲博主自己的理解,不一定是正确的,如果你发现有误,欢迎批评指正。
Less 的 fallback 就是按照当前主题,父主题,<magento-root>/lib/web/css/
的顺序,查找第一个符合位置名称的文件。举个例子,假设当前主题有web/css/styles-m.less
,父主题也有web/css/styles-m.less
,那么使用的就是当前主题文件,也就是当前主题 override 了父主题的文件。
如何 override 和 extend Magento UI
override
在自定义主题下新建web/css/source/_theme.less
注意,他将会覆盖父主题的web/css/source/_theme.less
,所以如果你想保留父主题的一些样式,请拷贝过来。在_theme.less
中可以重新定义variables
。
extend
在自定义主题下新建web/css/source/_extend.less
。同上,子主题会覆盖父主题。
用哪个文件只是一种约定,并非技术上的强制要求。不过大家都遵守约定,会让我们工作更高效对不?
当然你可以在_extend.less
import 更多 Less 文件,比如@import '_buttons_extend.less'; @import '_navigation_extend.less';
,这样的结构化命名会更清楚。
参考文档
CSS preprocessing
Simple ways to customize a theme’s styles
How do you override LESS in a custom theme?