LESS: How to fully extend two classes when relationships between both of them exist

less, twitter-bootstrap

Solution

The `all` option will add the new selector to all the hierarchical relationships / nested selectors that already exist.

So, in the nested selector `.parent .child` when extending `.parent` with `.newParent` it will extend the nested selector with `.newParent .child`, because this relationship with `.child` has been defined. When extending `.child` with `.newChild`, the nested selector gets extended by `.parent .newChild`, because the relationship between `.child` and `.parent` exists. And you end up with this CSS:

.parent .child,
.newParent .child,
.parent .newChild {
  color: white;
}

Note: This does not create selectors based on nested selectors created with the extension. Prior to the extension there is neither a definition of `.newParent .child` nor is there one of `.parent .newChild`, which could result in `.newParent .newChild` being created after the rule extension.

I am not completely sure how exacty you want your CSS output to look like, but you can always extend the "relationship"/combined/nested selector as well and avoid the `all` option, so that you don't generate all the hybrid selectors (like `.parent .newChild` and `.newParent child`):

.newParent {
  &:extend(.parent);
}
.newChild {
  &:extend(.child);
}
.newParent .newChild {
  &:extend(.parent .child);
}

or in a nested form:

.newChild {
  &:extend(.child);
}
.newParent {
   &:extend(.parent);
   .newChild {
      &:extend(.parent .child);
   }
}

and the CSS output will be:

.parent,
.newParent {
  color: blue;
}
.child,
.newChild {
  color: red;
}
.parent .child,
.newParent .newChild {
  color: white;
}

If desired, you can now simply add all the nested selector combinationsh by adding the `all` option. This will get you all the permutations of the selectors, and acchieve this CSS:

.parent,
.newParent {
  color: blue;
}
.child,
.newChild {
  color: red;
}
.parent .child,
.parent .newChild,
.newParent .child,
.newParent .newChild {
  color: white;
}

Problem

I'll explain with an example. Imagine the following CSS rules ``` .parent { color: blue; } .child { color: red; } .parent .child { color: white; } ``` Now, imagine you want to create a class equivalent to `.parent` and another one equivalent to `.child` using LESS. If you use "extend" you achieve part of the objective: ``` .newParent { &:extend(.parent all); } .newChild { &:extend(.child all); } ``` Will render: ``` .parent, .newParent { color: blue; } .child, .newChild { color: red; } .parent .child, .newParent .child, .parent .newChild { color: white; } ``` Which makes your new classes almost equivalent to you old classes. Missing is `.newParent .newClass` from the last set of rules. Is there a way to achieve this full equivalence? Note: This could be helpful for someone using Bootstrap and who wants to use other names for his classes (to achieve greater abstraction from the framework). For example, imagine you want to change the name for `.input-append` and `.add-on`, for which you'll need to extend all selectors related to both classes, including those in which both of them appear (like `.input-append .add-on { ... }`). Thanks in advance!

Original source