A Smarter Way for Integrating Bootstrap(Or Even from Another Less,CSS File) Classes into My Less File (Inheritance)

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



Leave a reply



Submit