How to apply concatenated classes within another class using Less? - less

Let's say I have the following Less setup:
.box {
border: 1px solid #333;
&.error {
background-color: Red;
}
}
If I wanted to declare another class which applied the full style of .box.error, as .error-box for example, what's the correct syntax?
If I use:
.error-box {
.box.error;
}
All I get is the red background, with no border. I've tried many different combinations, but I always get a syntax error.

I plugged in your less as so:
.box {
border: 1px solid #333;
&.error {
background-color:red;
}
}
.error-box {
.box;
}
and the CSS output was this:
.box {
border: 1px solid #333;
}
.box.error {
background-color: red;
}
.error-box {
border: 1px solid #333;
}
.error-box.error {
background-color: red;
}
were you wanting the .error-box class to alone receive both styles? The only way I can think of doing that would be:
.error-bg {
background:red;
}
.box {
border:1px solid #333;
&.error {
.error-bg;
}
}
.error-box {
.box;
.error-bg;
}

Related

Generate rules via LESS plugin

I'd like to write a plugin that can generate a LESS function named alt that can do the following transformation:
.button {
background-color: alt(red, blue);
color: alt(black, white);
}
And output the following:
.button {
background-color: red;
color: black;
body.alt & {
background-color: blue;
color: white;
}
}
There doesn't seem to be much documentation about writing LESS plugins on the site, so hoping someone can provide an example of how this might be written :) Thanks!
I think a mixin would be best for this. Something like the following LESS:
.alt(#property, #primary-color, #alternate-color) {
#{property}: #primary-color;
body.alt & {
#{property}: #alternate-color;
}
}
.button {
.alt(background-color, red, blue);
.alt(color, black, white);
}
Which will compile to the following CSS:
.button {
background-color: red;
color: black;
}
body.alt .button {
background-color: blue;
}
body.alt .button {
color: white;
}

Inherit from a Class Which Name Is Composed Using the `&` character in Less

How can I inherit from a class which name is composed using the & character (e.g. &-rule), please?
Desired Output
.prefix-rule-extended,
.prefix-rule {
color: white;
}
.prefix-rule-extended {
background-color: black;
}
or
.prefix-rule {
color: white;
}
.prefix-rule-extended {
color: white;
background-color: black;
}
Non-working Approaches
.prefix {
&-rule {
color: white;
}
}
plus
.prefix-rule-extended:extend(.prefix-rule) {
background-color: black;
}
or
.prefix-rule-extended {
.prefix-rule();
background-color: black;
}
Ideal Approach
.prefix {
&-rule {
color: white;
}
&-rule-extended:extend(&-rule) {
background-color: black;
}
}
Note 1: I know :extend(&-rule) is currently not supported.
Note 2: .prefix-rule is not so simple, i.a. there are nested rules inside so the following will not work:
.prefix {
&-rule {
color: white;
&-extended {
background-color: black;
}
}
}
Thank you.
(Ok, so as always to not leave this one w/o an answer - a summary of comments above):
Currently it's impossible to extend that kind of things. For the moment extend can't match selector identifiers generated via "concatenation" so .prefix {&.rule { ... would be a valid extend target (as it's "two elements" -> "two identifiers") but .prefix {&-rule { ... won't (since it's "two elements" -> "one identifier").
So if you plan to use extend don't be keen on such kind of nesting, keep it more simple.
Here are three valid Less snippets (each having its pros and cons) to get the desired CSS output.
1:
.prefix-rule {
color: white;
&-extended:extend(.prefix-rule) {
background-color: black;
}
}
2:
.prefix-rule {
&, &-extended {
color: white;
}
&-extended {
background-color: black;
}
}
3:
.rule-base {
color: white;
}
.prefix-rule {
&:extend(.rule-base);
&-extended:extend(.rule-base) {
background-color: black;
}
}

Bootstrap collapse nav at 991px

Building a site using Bootstrap. Having an issue with the van. I want it to collapse at 991px. Searched online and found this code, however it has changed the function of the nav as the nav wont stay open. Any ideas? The code used to override default is in my custom.css
http://nurdit.com/styleengineered/
#media (max-width: 991px) {
.navbar-header {
float: none;
}
.navbar-toggle {
display: block;
}
.navbar-collapse {
border-top: 1px solid transparent;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}
.navbar-collapse.collapse {
display: none!important;
}
.navbar-nav {
float: none!important;
margin: 7.5px -15px;
}
.navbar-nav>li {
float: none;
}
.navbar-nav>li>a {
padding-top: 10px;
padding-bottom: 10px;
}
}
Try changing the CSS above to:
#media (max-width: 991px) {
.navbar-header {
float: none;
}
.navbar-toggle {
display: block;
}
.navbar-collapse {
border-top: 1px solid transparent;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.1);
}
.navbar-collapse.collapse {
display: none!important;
}
.navbar-nav {
float: none!important;
margin: 7.5px -15px;
}
.navbar-nav>li {
float: none;
}
.navbar-nav>li>a {
padding-top: 10px;
padding-bottom: 10px;
}
.navbar-collapse.collapse.in { /* NEW */
display: block!important;
}
}
As far as I can tell, this does the trick on your site. Credit for this suggestion goes to Dave Forber , see Bootstrap 3 Navbar Collapse

Less > Define variable on constant

I have the following button mixin:
.Button(#type) {
color: #White;
&:hover {color: #White;} // :hover
} // Button
.Button(#type) when (#type = 'Delete') {
background-color: lighten(#Red, 20%);
border: 1px solid lighten(#Red, 20%);
&:hover {
background-color: lighten(#Red, 12%);
border: 1px solid lighten(#Red, 12%);
} // :hover
} // Button
.Button(#type) when (#type = 'Search') {
background-color: lighten(#Blue, 20%);
border: 1px solid lighten(#Blue, 20%);
&:hover {
background-color: lighten(#Blue, 12%);
border: 1px solid lighten(#Blue, 12%);
} // :hover
} // Button
This is working fine and, as you can see, what changes in each button is the color.
If it possible to have only one Mixin and according to the type define a color variable.
This way I wouldn't need to use so many Button mixin versions ...
There is no other way to do that. Guarded mixins in LESS is fixed to you use that format instead of if/else statements. But in your case, I suggest to do this :
//create a mixin for global rules.
.rules(#color){
background-color: lighten(#color, 20%);
border: 1px solid lighten(#color, 20%);
&:hover {
background-color: lighten(#color, 12%);
border: 1px solid lighten(#color, 12%);
}
}
And you just only to call .rules mixin to every your css rules.
.Button(#type) when (#type = 'Delete') {
.rules(#Red);
}
.Button(#type) when (#type = 'Search') {
.rules(#Blue);
}
This is simpler and no need a lot of space to write the same code. Hope this helps.
Yes, It Can Be Done
It can be folded into a single mixin that uses the #type to switch color values with a creative use of variable variables.
LESS
#White: #fff;
#Red: #f00;
#Blue: #00f;
.Button(#type) {
//define the variables with the name
//of the button you want to pass: Delete, Search, etc.
//associated to the color variable you desire
#Delete: #Red;
#Search: #Blue;
//set up a generic variable name to use, and
//then call the color value through a variable variable call (##)
#ContrastColor: ##type;
color: #White;
background-color: lighten(#ContrastColor, 20%);
border: 1px solid lighten(#ContrastColor, 20%);
&:hover {
color: #White;
background-color: lighten(#ContrastColor, 12%);
border: 1px solid lighten(#ContrastColor, 12%);
} // :hover
} // Button
.deleteClass {
.Button(Delete);
}
.searchClass {
.Button(Search);
}
CSS Output
.deleteClass {
color: #ffffff;
background-color: #ff6666;
border: 1px solid #ff6666;
}
.deleteClass:hover {
color: #ffffff;
background-color: #ff3d3d;
border: 1px solid #ff3d3d;
}
.searchClass {
color: #ffffff;
background-color: #6666ff;
border: 1px solid #6666ff;
}
.searchClass:hover {
color: #ffffff;
background-color: #3d3dff;
border: 1px solid #3d3dff;
}

SCSS rule Inheritance compared to LESS

I'm used to using LESS but im currently working with SCSS.
In Less I could do the following:
.sidebar_styles { background: red; border: 1px solid blue; }
aside[role="complementary"] { .sidebar_styles; }
Would the SCSS equivalent be:
.sidebar_styles { background: red; border: 1px solid blue; }
aside[role="complementary"] { #extend .sidebar_styles; }
I ask as I am using the Foundation framework and I'm trying to not use presentation classes in the html. I noticed Chrome was running slowly and opened up the inspector. The matched css rules for some elements is huge.
Below is about 5% of what I could copy from one of the elements before Chrome hangs.
.row.collapse .column, body.full_width div[role="main"] form .row.collapse .column, body.two_columns div[role="main"] form .row.collapse .column, body.homepage div[role="main"] .hero_container form .row.collapse .column, .row form .collapse.top_bar .column, .top_bar form .collapse.top_bar .column, header[role="banner"] form .collapse.top_bar .column, footer[role="contentinfo"] form .collapse.top_bar .column, body.full_width div[role="main"] form .collapse.top_bar .column, body.two_columns div[role="main"]
#extend will group the css selectors together in comma separated list. If you add additional rules after the #extend, it will keep those rules as it's own selector.
scss
.sidebar_styles {
background: red;
border: 1px solid blue;
}
aside[role="complementary"] {
#extend .sidebar_styles;
color: black;
}
css output
.sidebar_styles, aside[role="complementary"] {
background: red;
border: 1px solid blue;
}
aside[role="complementary"] {
color: black;
}
If you want to keep the rules separated then you can use a mixin and include it in the rules.
scss
#mixin test {
background: red;
border: 1px solid blue;
}
.sidebar_styles {
#include test;
}
aside[role="complementary"] {
#include test;
}
css output
.sidebar_styles {
background: red;
border: 1px solid blue;
}
aside[role="complementary"] {
background: red;
border: 1px solid blue;
}