Reference a Class/Mixin Without Completely Importing the Less File

Bootstrap & LESS: importing mixins only as reference

Also see: https://stackoverflow.com/a/14463540/1596547. Which says:

No actual code will output from that file as CSS, but all becomes available to use as mixins.

In you case their will be a difference with for example make-sm-column() this mixin contains a media query definition. If you use (reference) when importing mixins.less this media query part is NOT include in your CSS.

// Generate the small columns
.make-sm-column(@columns; @gutter: @grid-gutter-width) {
position: relative;
// Prevent columns from collapsing when empty
min-height: 1px;
// Inner gutter via padding
padding-left: (@gutter / 2);
padding-right: (@gutter / 2);

// Calculate width based on number of columns available
@media (min-width: @screen-sm-min) {
float: left;
width: percentage((@columns / @grid-columns));
}
}

Will give:

.herocontainer {
position: relative;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
}
@media (min-width: 768px) {
.herocontainer {
float: left;
width: 33.33333333333333%;
}
}

With using (reference) you will only got:

.herocontainer {
position: relative;
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
}

NOTE you also use btn-lg with came from buttons.less. For me it seems the best solution to reference button.less but not mixins.less (theoretical mixins should contain mixins only, so referencing should make any difference). Otherwise create a mixins.less with only the mixins you will need.

UPDATE

  1. there is a bug Reference import not importing media queries
  2. when a class in a referenced import calls a mixin from a not referenced import, the output of this mixin will be (unexpected) shown in your css. So in the answer above not using reference for mixins.less will indeed give a lot of unwanted classes

LESS import - reference vs once

Why I can't just import the mixins to the global style.less and use them in each of the other included files?

This method should work fine without any compile errors. It is only if you are trying to compile template-*.less without mixins.less that it will kick up a fuss. It you are getting an error check that the location to mixins.less is correct.

Once and reference

I understand what each of these is doing, but what are the pros & cons of each?

Once

The principle of once is to only import a file once. For example, you may have an import for mixins.less in both of your template-*.less files and in styles.less. This will prevent the file being imported multiple times, resulting in duplicated css styles in your stylesheet.

It is worth noting that once is actually the default behaviour of import so does not need to be specified.

Reference

Reference is quite clever. If you import with reference, when compiled it will only output styles from the imported file that have been used in the parent less file. Typically this would be used for mixin classes and extend classes.

Example

//Mixins.less
.m-bacon {
color: red;
}

.m-smokey {
color: pink;
}

// Styles.less
@import (reference) mixins.less;

.pork {
.m-bacon;
}

If styles.less was compiled it would only contain the pork class.

//Output
.pork {
color: red;
}

Summary

In summary once prevents the same styles being generated multiple times. This is also the default behaviour of @import. reference prevents unreferenced mixin classes and extend classes being generated at compile time.

Howto reference a LESS file without actually importing/overriding variables

Finally I came up with a very easy solution:

Simply import desktop/variables.less at the beginning of mobile/variables.less. This works because the default LESS behavior is import once. Since it is already imported before all modules, the desktop module's @import rule won't cause (re-)importing - therefore won't overwrite any variables:

├ desktop/
│ ├ modules/
│ │ └ foobar.less
│ │ > @import (reference) "../variables.less"
│ ├ main.less
│ │ > @import "variables.less"
│ │ > @import "modules.less"
│ ├ modules.less
│ │ > @import "modules/foobar.less"
│ └ variables.less
│ > @bundle: 'desktop'

└ mobile/
├ main.less
│ > @import "variables.less"
│ > @import "modules.less"
├ modules.less
│ > @import "../desktop/modules/foobar.less"
└ variables.less
> @import (reference) "../desktop/variables.less"
> @bundle: 'mobile'

Mixin bootstrap 3 classes - Undeclared mixin

Columns in Bootstrap LESS source are generated dynamically via mixins in mixins.less.
This is the reason you can't call them directly as mixins.

Anyway I think it's better practice to give .col-lg-12 as a class to the element and not hiding it to your stylesheet. You shouldn't use .row and .col-* in same element either.

There is no such thing as .row-fluid in Bootstrap 3.

<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<div class="page-header"> ... </div>
</div>
</div>
</div>

LESS Mixins aren't available in other imported LESS files

The problem wasn't the importing at all, really.

I made a mistake in how I was using media queries.

Both files had the same media query since they were both for the desktop CSS (hence the "d"). However, the second one, in containers-d-1.less was OVERWRITING the first one and blowing away all my mixins! I clearly need to wrap the import block in a single media query for that section instead of redeclaring it inside each less file.

LESS CSS: Reuse generated .@{name} class as a mixin

Unfortunately. The selector interpolation is just string interpolation, and the string gets then printed into css, so no class object is generated in the less run.

So you can design a generator/mixin, that includes your operation:

#genMarginTop (@size) {
margin-top: @size;
}

But then build classes by calling the mixins / generators:

.mtStandard {#genMarginTop(40px);}
.mtHalf {#genMarginTop(20px);}

And this way they are class objects that you can use for mixin =)

.someClass {
background-color: #FFF;
.mtStandard;
//more of this stuff
}

This looks a bit silly in this simple example, but maybe something like this:

 #bggenerator (@color) {
background-color: @color;
}
#bggenerator (@color, dark) {
@blend : @color + #842210;
background-color: darken(@blend, 30%);
}
#bggenerator (@color, @url, @rest) {
background: "@{color} url('@{url}') @{rest}";
}

.mtStandard {
#genMarginTop(40px);
}

.someClass {
.mtStandard;
#bggenerator(#FFF, "bgimage.png", left top no-repeat);
//more of this stuff
}

Or something that does even more exciting stuff with the arguments

Less @import (reference) not working

This happens because of :extend() which is widely used in Bootstrap. As noted in http://lesscss.org/features/#import-options-reference:

reference styles will not show up in your generated CSS unless the reference styles are used as mixins or extended.

To get rid of unnecessary styles be more specific:

@import "../bootstrap/variables.less";
@import "../bootstrap/mixins.less";
@import (reference) "../bootstrap/forms.less";

#content {
> form {
.form-horizontal;
}
}

Importing Bootstrap LESS files

Now Available in LESS 1.5

As of LESS 1.5 you can do an import as just a reference (so you can use the mixins without getting all the code compiled). Like this:

@import (reference) "mixins.less";
@import (reference) "variables.less";
@import (reference) "buttons.less";

.my_custom_button {
.btn();
.btn-danger();
.btn-small();
}


Related Topics



Leave a reply



Submit