7

I am trying to customize Twitter Bootstrap's CSS without altering local copies of the bootstrap code.* So I have cloned the Twitter Bootstrap project into one folder and have my application code within its own folder:

/html
    /bootstrap
       ...etc...
       /js
       /less
    /MyApp
       ...etc...
       /common_files
          /less
             style.less

Within my "style.less" file, I define a few LESS variables, then include the bootstrap files:

/* custom settings that deviate from Bootstrap's default values */
@sansFontFamily: Trebuchet MS, Tahoma, sans-serif, Arial;
@baseFontSize: 11px;
@baseLineHeight: 18px;

/* import bootstrap components from bootstrap-dedicated folder */
@import "../../../bootstrap/less/bootstrap.less";
@import "../../../bootstrap/less/responsive.less";

Since LESSCSS variables are really constants, I'm surprised that my @sansFontFamily is not getting picked up when I compile the LESS files into CSS: lessc style.less > MyApp.css --yui-compress

So...what am I missing? Why are my variables being overwritten by the variables defined within Bootstrap's LESS files?

*--I have checked out "Twitter Bootstrap Customization Best Practices", but think taking advantage of constants would be a better approach (if I can get it to work).

Community
  • 1
  • 1
Jeromy French
  • 11,812
  • 19
  • 76
  • 129
  • They really shouldn't! I'm doing it like that too and it works... they're all set as !default, so they can be overwritten in exactly that way. – markus Dec 10 '12 at 22:01
  • "!default"? I can't find a reference to that... – Jeromy French Dec 10 '12 at 22:26
  • 3
    try importing your bootstrap first, and declare the variables afterwards, so the bootstrap ones get overwritten by yours, and not the other way around – Pevara Dec 10 '12 at 22:32
  • @PeterVR--that did the trick. For extra credit, why does setting the variables *after* importing the includes impose the variable sets into the imported files? Is this a lessc compiler thing, and if so, where is the order of operations documented? – Jeromy French Dec 11 '12 at 02:38
  • Hello , Sorry my answer is so late , Please check my answer – ShibinRagh May 17 '13 at 16:14

4 Answers4

9

The correct approach is to import the bootstrap assets first, then define the custom values with LESS variables. So, given the directory structure in the question:

If you're using Bootstrap version 2.x:

/* import bootstrap components from bootstrap-dedicated folder */
@import "../../../bootstrap/less/bootstrap.less";
@import "../../../bootstrap/less/responsive.less";

/* custom settings that deviate from Bootstrap's default values */
@sansFontFamily: Trebuchet MS, Tahoma, sans-serif, Arial;
@baseFontSize: 11px;
@baseLineHeight: 18px;

If you're using Bootstrap version 3.x:

/* import bootstrap components from bootstrap-dedicated folder */
@import "../../../bootstrap/less/bootstrap.less";

/* custom settings that deviate from Bootstrap's default values */
@font-family-sans-serif: Trebuchet MS, Tahoma, sans-serif, Arial;
@font-size-base: 11px;
@line-height-base: 18px;

Complete list of variables can be found in variables.less file.

Jeromy French
  • 11,812
  • 19
  • 76
  • 129
4

PeterVR's advice to move the custom variable declarations below the bootstrap @import statements is correct according to the docs here http://lesscss.org/#-variables. This states:

When defining a variable twice, the last definition of the variable is used, searching from the current scope upwards. For instance:

@var: 0;
.class1 {
    @var: 1;
    .class {
        @var: 2;
        three: @var;
        @var: 3;
    }
    one: @var;
}

Compiles to:

.class1 .class {
    three: 3;
}
.class1 {
    one: 1;
}

(sample code edited - there's a couple of typos in their version!)

So I would guess the compilation sequence is something like:

  1. Process all @imports to build a single chunk of LESS code
  2. Walk through the LESS code and gather up all the variable declarations (per scope block)
  3. Any variable declaration value replaces any previous instance of the same name (per scope block)
  4. Replace variable placeholders with variable values

This would explain why the value of .class1 .class { three: is 3 even though it's declared before the @var: 3; declaration.

mr.perplexed
  • 131
  • 1
  • 1
  • 6
1

Hello I got a better way from random internet search

http://ollomedia.com/using-twitter-bootstrap-the-right-way/

Example source code , Please download and checkout

http://ollomedia.com/wp-content/uploads/sample.zip
ShibinRagh
  • 6,530
  • 4
  • 35
  • 57
0

I did something similar recently and the best approach I found was to create my own "variables_override.less" and import this after importing the standard variables.less in bootstrap.less and responsive.less. Then compile both files as normal and your variables will override the bootstrap defaults

This approach does involve modifing bootsrap.less and responsive.less but in a very minimal way

tocallaghan
  • 8,432
  • 1
  • 28
  • 23
  • Hmm..tell me more. Why was it necessary for you to edit any of the bootstrap includes? Following PeterVR's advice I moved the variable declarations *below* the imports: So I can impose my variable settings and benefit from a "pristine" bootstrap pull... – Jeromy French Dec 11 '12 at 02:30
  • My understanding (and of course I could be wrong, and seem to be) is that when bootstrap is compiling the css files it works through each of the less files and incorporates them into the final css. If you create your variables first it will be overwritten by the bootstrap defaults and if you declare them after it will be too late. Seeing as what Peter has said is working for you I guess compilation takes place only after importing all of the files (which makes sense I guess) – tocallaghan Dec 11 '12 at 03:40