Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling issue in Bootstrap 3 with namespace

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

like image 807
Overachiever Avatar asked Nov 05 '13 16:11

Overachiever


2 Answers

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.

like image 131
ScottS Avatar answered Nov 03 '22 20:11

ScottS


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.

like image 31
seven-phases-max Avatar answered Nov 03 '22 22:11

seven-phases-max