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
there is a bug Reference import not importing media queries- 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
How to Combine Cursor: Not-Allowed and Pointer-Events: None;
How to Avoid "-Internal-Autofill-Selected" Style to Be Applied
What Is the Current State of Sub-Pixel Accuracy in the Major Browsers
Add Prefixes to CSS Class Names Using Less or SASS
Display:None Doesn't Work on Outlook 2007
Why Do /**/ Comments Work in Stylesheets But // Comments Don'T
Add Timestamps to Compiled SASS/Scss
CSS Changing Aspect Ratio of Fluid Images
What's a @Media Rule Without a Media Type Do
What Are the Differences Between Display:Box and Display:Flexbox
How to Capitalize the First Letter of Each Word in CSS
How to Remove Clear Button ( 'X' Button ) from Ie10 Textboxes in Compatibility Mode
Media Queries Not Working in Internet Explorer 11
Font-Variant: Small-Caps; Shows Different Font Sizes Using Chrome or Firefox