LESS: Better to use inheritance or multiple classes
Various Options, No Set Answer
It's going to depend a lot upon your code, your goals, etc., how you get styles to the various elements. Here are some possibilities, each with strengths and weaknesses.
1. Mixin (what you currently do)
LESS
.inputbase() {
/* your base code */
}
.someInput {
.inputbase;
/*some input special code */
}
.someOtherInput {
.inputbase;
/*some other input special code */
}
.andAnotherInput {
.inputbase;
/*and another input special code */
}
CSS Output
.someInput {
/* your base code */
/*some input special code */
}
.someOtherInput {
/* your base code */
/*some other input special code */
}
.andAnotherInput {
/* your base code */
/*and another input special code */
}
If there is more than a line or two of code in .inputbase()
, and if it is mixed in more than just a couple of instances, this will be generating a lot of extra code. This is the issue you find yourself facing.
2. Extend a Class
It appears LESS is just about ready to allow for extending mixins, but at present (LESS 1.5) this requires just a class definition, so this:
LESS
.inputbase {
/* your base code */
}
.someInput {
&:extend(.inputbase);
/*some input special code */
}
.someOtherInput {
&:extend(.inputbase);
/*some other input special code */
}
.andAnotherInput {
&:extend(.inputbase);
/*and another input special code */
}
CSS Output
.inputbase, /* this is gone once mixin extending allows .inputbase() extension */
.someInput,
.someOtherInput,
.andAnotherInput {
/* your base code */
}
.someInput {
/*some input special code */
}
.someOtherInput {
/*some other input special code */
}
.andAnotherInput {
/*and another input special code */
}
The advantage is all the base code is not repeated, but what is repeated is the selectors, as they are first grouped together with the base code, then again are output for the individual code. If one likes to keep their code grouped in one selector definition, then this would not be the way to go. Otherwise, this offers a nice way to reduce CSS output.
3. Two Classes (extra html markup you propose)
This one solution you proposed, having two classes (this is because you stated that you do not always want .inputbase
applied to an input element).
LESS and CSS Output*
.inputbase {
/* your base code */
}
.someInput {
/*some input special code */
}
.someOtherInput {
/*some other input special code */
}
.andAnotherInput {
/*and another input special code */
}
This does have the least amount of CSS, but it has the disadvantage that it also requires the extra HTML markup of the two classes, <input class="inputbase someInput" />
etc.
4. One Class with Override of Base
This may be better than the above.
LESS and CSS Output
input {
/* your base code */
}
.someInput {
/*some input special code */
/*override input base code if needed */
}
.someOtherInput {
/*some other input special code */
/*no override if not needed */
}
.andAnotherInput {
/*and another input special code */
/*no override if not needed */
}
If most inputs will have the baseinput code, you can simply define your base input code within the input
element definition, then just override the properties you don't want in your special css code. This allows for less html with just the single class applied <input class="someInput" />
. This will keep both the CSS and the HTML less cluttered, but has the disadvantage of remembering what the base code is and being able to override it if needed.
Summary
What will be best depends too much on the particular circumstances you face. But perhaps the two additional options will help you think through your case. I personally would in most cases opt for #2 or #4, but again, there are applications for #1 and #3 as well.
Less inheritance fails with undefined class
Since .dropdown-toggle
is defined there inside .panel-heading
class as part of the .dropdown .dropdown-toggle
selector, it is not available as a standalone global scope mixin (like you try to invoke it). The .panel-heading
and .dropdown
classes work like namespaces in this case so to access .dropdown-toggle
there you need to specify "complete path" to it, e.g.:
.my-toggle {
.panel-heading > .dropdown > .dropdown-toggle;
// or just:
.panel-heading.dropdown.dropdown-toggle;
// if you prefer shorter things
}
However this won't work the way you probably expect it to. Note that the .dropdown-toggle
class is defined not only once inside .panel-heading
but also several (~10) times inside other classes (e.g. .btn-group
, .input-group-btn
etc.). So if you need to get other .dropdown-toggle
styles you also need to invoke these other .dropdown-toggle
definitions.
Most likely extend
will serve in this particular case better but it also has its limitations. Usually I imply that an approach to try to use Bootstrap as a CSS construction kit for your own semantic classes is a dead end. Some things are possible (using mixins, extend, referencing "bootstrap.css" and all of this all together) but many are just not (or at least are super-bloating both in coding (time) and in final CSS result). See my comments here, here and here for more details on this.
Adding less file
With Less
files you need to compile them to css
. There are various ways to do this depending on your chosen build tool.
The Less website shows you how to install and compile Less
files with node.js
From less.org
Install Less with Node.js
$ npm install -g less
Compiling Less from the command line
$ lessc styles.less > styles.css
This will then give you a css file you can link to from your html page.
css mixins using an external framework
If you can add LESS compilation into your workflow, you can achieve this easily with its @import (reference)
and :extend(x all)
. Without needing to learn anything more about LESS, you'd do
@import (reference) "bootstrap.less"; // this file is included with bootstrap. `(reference)` means it will only pull in the styles you ask it for, so you could continue using this even if you switch to another framework and don't want to include all of bootstrap
.disabled-button:extend(.button all, .button-success all, .disabled all) {} // pulls in the `.button` styles, `.button-success` styles, and `.disabled` styles
.disabled-button {color:red} // adds on your styles
Explanation of LESS's :extend(all)
and relevant documentation links are in this answer
Since CSS is valid LESS, you wouldn't have to make any other changes to your stylesheet. Okay, so how do you add LESS compilation to your workflow? The simplest solution is described in LESS's "Command Line Useage" documentation, which boils down to installing less
(once)
$ npm install less -g
and then running lessc
, the less compiler
$ lessc my-styles.less my-compiled-styles.css
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>
Related Topics
Extracting Only the CSS Used in a Specific Page
How to Target All <H> Tags with a Single Selector
How to Horizontally Center a Floating Element of a Variable Width
Which HTML5 Reset CSS Do You Use and Why
Webkit CSS to Control the Box Around the Color in an Input[Type=Color]
How to Rotate Text Left 90 Degree and Cell Size Is Adjusted According to Text in HTML
How to Override Global CSS in a CSS Module File
The Behaviour of Top: Auto; Bamboozles Me
:Nth-Letter Pseudo-Element Is Not Working
Pass Function or Mixin by Reference in SASS
How to Use/Emulate Regex-Like Backreferences in Attribute Selectors
Shorten Verbose CSS That Repeats Combinations of Elements and Pseudo-Classes