7

Any idea why there are certain styles breaking when I compile Bootstrap 3 using Crunch / WinLESS. I'm using this code to namespace bootstrap.

.namespace-bs {
    @import "less/bootstrap.less";
}

For most styles it works great but there are a few that turn out like this:

.btn-primary .namespace-bs .caret,.btn-success .namespace-bs .caret,.btn-warning .namespace-bs .caret,.btn-danger .namespace-bs .caret,.btn-info .namespace-bs .caret{border-top-color:#fff;}

When I would expect them to be like this:

.namespace-bs .btn-primary .caret,.namespace-bs .btn-success .caret,.namespace-bs .btn-warning .caret,.namespace-bs .btn-danger .caret,.namespace-bs .btn-info .caret{border-top-color:#fff;}

Is there something wrong with my compiler or a bug in the LESS code?

Thanks

Overachiever
  • 865
  • 7
  • 10
  • it could be great you mention Where TF you are editing that first line, that could help other people, instead of only helping you – Santiago Rebella Dec 16 '13 at 17:36
  • Not sure if I understand what you are asking but if you mean where the .namespace-bs { @import "less/bootstrap.less"; } is located, then I made a new .less file with only that line of code in it. – Overachiever Dec 23 '13 at 19:50

2 Answers2

13

Your Issue in Detail

As seven-phases-max described, there are issues with name spacing "when the & is appended to a nested selector." So the Bootstrap code in part has this:

.caret {
  .btn-default & {
    border-top-color: @btn-default-color;
  }
  .btn-primary &,
  .btn-success &,
  .btn-warning &,
  .btn-danger &,
  .btn-info & {
    border-top-color: #fff;
  }
}

Recall that every instance of & is replaced with the full nesting structure, so when you namespace it as you are, you effectively have this:

.namespace-bs {
  .caret {
    .btn-default & {
      border-top-color: @btn-default-color;
    }
    .btn-primary &,
    .btn-success &,
    .btn-warning &,
    .btn-danger &,
    .btn-info & {
      border-top-color: #fff;
    }
  }
}

And the full nested structure is .namespace .caret at the point of the & replacement, which is why you are seeing the selectors look like .btn-primary .namespace-bs .caret etc.

Work Around for LESS 1.4+

The following should work:

  1. Compile bootstrap from its LESS code as normal into a bootstrap.css file. This will resolve all LESS into the "normal" bootstrap css code, and the & will function as expected and desired wherever it is used.

  2. Then in your name spacing LESS file, do this:

.namespace-bs {
    @import (less) "css/bootstrap.css";
}

What we are doing is importing the compiled bootstrap.css file (which has no more & values in it, as it is fully compiled), but as we import it, we are telling LESS to treat the CSS as LESS code by putting the (less) type casting in. So now, your name space should simply append itself to the full selector string of each selector in the bootstrap.css file, and you should end up with what you desire.

ScottS
  • 71,703
  • 13
  • 126
  • 146
  • However this problem seems to have been fixed in version 3.2 – Svakinn Aug 23 '14 at 02:19
  • 3
    @Svakinn No, it's not fixed. v3.2 may fix the particular `.btn` case but there a lot of other classes and styles that gets broken if you wrap "bootstrap.less" into a namespace. In fact, it just *cannot* be fixed with current state of Less and Bootstrap w/o some (quite major) refactoring of both. See [#2052](https://github.com/less/less.js/issues/2052#issuecomment-45681469) and other issues referenced from there. – seven-phases-max Aug 23 '14 at 08:52
  • @Svakinn In other words, the `@import (less) "css/bootstrap.css";` solution is the only solution for the moment (and will be the only solution for a while). – seven-phases-max Aug 23 '14 at 09:18
  • Yes @seven-phases-max you are absolutley right. To believe 3.2 fixed the problem was due to silly mistake on my behalf. Thanks for the correction. – Svakinn Aug 24 '14 at 01:34
  • 2
    FYI - When doing step 1 my compiler doesn't work with step 2 unless the CSS from step 1 isn't minified. – Overachiever Oct 24 '14 at 20:41
  • @Overachiever same issue here. My less compiler is set up to only compile the .min.css and not the unminified css file, so I don't have an unminified bootstrap file to reference. Why doesn't minified css work? It is valid css and less afterall. – wired_in Apr 24 '15 at 22:17
1

No, there's nothing wrong with either compiler or your code. It's just "Bootstrap is not meant to be used this way". Putting a whole less file into namespace is a wise idea but it is incompatible with libraries having selectors using so-called "Parent-Selectors" or similar tricks (i.e. when & is appended to a nested selector).

(Updated) See #2052 and other issues referenced from there for more details.

seven-phases-max
  • 11,765
  • 1
  • 45
  • 57