Magento2: _.extend.less overridden by child theme

Created on 10 Mar 2017  ยท  11Comments  ยท  Source: magento/magento2

_extend.less is not inheriting through multiple parents. Only the most recent _extend.less will be read.

The Magento/blank theme contains //@magento_import 'source/_extend.less';. This and the documentation seem to indicate that the intended behavior of _extend.less should be to inherit styles from all of the parent themes.

Preconditions

  1. Magento 2.1.5

Steps to reproduce

  1. Have two themes, a parent (Example/parent) and a child (Example/child). Example/parent should inherit Magento/blank. Example/child inherits Example/parent.
  2. Create web/css/source/_extend.less in both files.
    In Example/parent, the content of _extend.less should be:
h1 {
    color: blue !important;
}

In Example/child

p {
    font-size: 40px !important;
}
  1. Compile LESS for the project.

Expected result

  1. Both styles are applied on the page. p tags have massive text, h1 tags are bright blue.

Actual result

  1. Only the child style is applied (h1 tags are the normal color). The parent _extend.less has been lost.
  2. To confirm, open pub/static/frontend/Example/child/en_US/css/styles-l.less. There will be only one reference to the child _extend.less, rather than references to both parent and child.

Most helpful comment

I think the cleanest method for getting around this is to :

  1. create a _extend-child.less in both your parent and child themes.
  2. Keep _extend-child.less empty in your parent theme and add it too your parent theme's _extend.less file.
  3. Add a @import '_extend-child.less'; rule to the end of your parent's theme's _extend.less file.
  4. In your child theme add @import or style rules in _extend-child.less to extend parent theme's CSS.
app/design/frontend/Vendor/
โ”œโ”€โ”€ parent
โ”‚ย ย  โ””โ”€โ”€ web
โ”‚ย ย      โ””โ”€โ”€ css
โ”‚ย ย        ย ย โ””โ”€โ”€ source
โ”‚ย ย       ย ย      โ”œโ”€โ”€ _extend-child.less (keep this file empty)
โ”‚ย ย       ย ย      โ””โ”€โ”€ _extend.less
โ””โ”€โ”€ child
 ย ย  โ””โ”€โ”€ web
 ย ย      โ””โ”€โ”€ css
 ย ย       ย ย  โ””โ”€โ”€ source
 ย ย       ย ย      โ””โ”€โ”€ _extend-child.less

All 11 comments

Your Example/child/web/css/source/_extend.less is overriding Example/parent/web/css/source/_extend.less
Between "simple_extend" and "simple override" the last one seems to have an higher priority but it is not clear how to handle multiple levels of theme inheritance in this case.

Correct. The crux of the issue raised is whether or not this is a bug or working as intended.

Given that //@magento_import is used for handling _extend.less in Magento/blank, it would indicate the intention is that this is merged through the entire chain of inheritance, rather than simply overriding as is the current behavior.

If it was intended to be an override, I would expect that it would be a simple @import statement. Otherwise, the issue seems to be that //@magento_import doesn't check parent themes, only modules.

I'm having the same troubles with this (un)intended behaviour. As a workaround I've created a copy of the parents themes '_extend.less' in my child theme and called it '_extend_parent.less'. This file is imported at the top of my child themes '_extend.less'.

@fahu That's the workaround I've been using as well. It works, but it's one more point of failure when creating child themes, and gets messy once you get into child-of-child themes.

We've done it almost like @fahu, but created a symlink from the parent extend.
In your /web/css/source/
ln -s ../../../../<parent_theme>/web/css/source/_extend.less _extend_parent.less
Therefore everytime the parent extend is updated, you have all the extends in your childs as well.

@vkorotun can you please check the issue, and comment on possible solution.

Hi @dersam
It's not a bug - @magento_import is working as expected, this directive collects source files for the current theme that match pattern (i.e. source/_extend.less) according to theme inheritance rules from all modules and current theme web assets folder. Like @slackerzz said _extend.less in child theme will be used instead of respective source file located in the parent theme or module.

As a possible solution - to extend styles of the child theme without overriding, you can add _extend.less file to any module folder in your theme context so it will not intersect with parent's location for example:

app/design/frontend/Example/child/Magento_Theme/web/css/source/_extend.less
or
app/design/frontend/Example/child/Magento_Catalog/web/css/source/_extend.less

Ok, that makes sense. Themes always override, unless it's part of a module folder, in which case //@magento_import will behave as expected and gather everything.

Thanks for the response, I can see the logic in that. I'll close the issue.

I added the following code to <theme_dir>/web/css/source/_theme.less:

//@magento_import '_override.less';

then I can use it to override css on <theme_dir>/Magento_Catalog/web/css/source/_override.less

Themes always override, unless it's part of a module folder, in which case //@magento_import will behave as expected and gather everything.

@dersam I tested that and I am afraid it is not true. extend.less from parent are also overwritten for modules if you have a multi parent theme structure. The only way to extend your parent's extends without overwriting them is editing the styles-m.less and styles-l.less in your child theme. There you can add a custom @magento_import extend for your child:

// styles-m.less

// Original file copied...

// end of file
//@magento_import 'source/_extend.less';
//@magento_import 'source/_extend_2.less';
// styles-l.less

// Original file copied...

// end of file
//@magento_import 'source/_extend.less';
//@magento_import 'source/_extend_2.less';

That way, you can use _extend_2.less files in your latest child to extend the parent's _extend.less without overwriting them.

I think the cleanest method for getting around this is to :

  1. create a _extend-child.less in both your parent and child themes.
  2. Keep _extend-child.less empty in your parent theme and add it too your parent theme's _extend.less file.
  3. Add a @import '_extend-child.less'; rule to the end of your parent's theme's _extend.less file.
  4. In your child theme add @import or style rules in _extend-child.less to extend parent theme's CSS.
app/design/frontend/Vendor/
โ”œโ”€โ”€ parent
โ”‚ย ย  โ””โ”€โ”€ web
โ”‚ย ย      โ””โ”€โ”€ css
โ”‚ย ย        ย ย โ””โ”€โ”€ source
โ”‚ย ย       ย ย      โ”œโ”€โ”€ _extend-child.less (keep this file empty)
โ”‚ย ย       ย ย      โ””โ”€โ”€ _extend.less
โ””โ”€โ”€ child
 ย ย  โ””โ”€โ”€ web
 ย ย      โ””โ”€โ”€ css
 ย ย       ย ย  โ””โ”€โ”€ source
 ย ย       ย ย      โ””โ”€โ”€ _extend-child.less

Was this page helpful?
0 / 5 - 0 ratings