CSS - LESS class inheritance - css

I'm using the styles from twitter bootstrap and have a question about inheritance.
I'd like to make two label classes that'd inherit the label styles from bootstrap.
.label-new {
.label; .label-important;
}
.label-updated {
.label; .label-warning;
}
However, the above would result in LESS parse error "NameError: .label-important is undefined" because .label-important and .label-warning are defined using the following in bootstrap:
.label,
.badge {
// Important (red)
&-important { background-color: #errorText; }
&-important[href] { background-color: darken(#errorText, 10%); }
// Warnings (orange)
&-warning { background-color: #orange; }
&-warning[href] { background-color: darken(#orange, 10%); }
}
Is there any special syntax to inherit the .label-important/warning?
Thanks in advance.

I think you can only inherit the .label which should give .label-new-important and .label-new-warning (and equivalent for updated). If that is not desireable, and you want new added extensions, you probably need to define the colors again directly for the .label to isolate and define what you want. Like so:
.label {
// New (red)
&-new { background-color: #errorText; }
&-new[href] { background-color: darken(#errorText, 10%); }
// Updated (orange)
&-updated { background-color: #orange; }
&-updated[href] { background-color: darken(#orange, 10%); }
}
EDIT (If you don't want to redefine the colors but use a mixin)
To avoid a redefining of the colors, then you need to change the original definition, and do this:
First, delete the original .label and .badge definitions, and then second, define them more explicitly like so:
.label-important,
.badge-important {
// Important (red)
{ background-color: #errorText; }
{ background-color: darken(#errorText, 10%); }
}
.label-warning,
.badge-warning {
// Warnings (orange)
{ background-color: #orange; }
{ background-color: darken(#orange, 10%); }
}
.label-new {
.label-important;
}
.label-updated {
.label-warning;
}

Related

Classbuilding with scss (double ampersand)

I want to get the following selector B__E.B__E--M so that B__E--M only applies if the element also has the B__E class;
I have the following:
.B {
&__E {
// default color
&--M {
// Color i want
}
}
}
The problem is, that the --M modifier should apply another color, but doesn't overwrite the default color from the __E element.
This is not allowed:
.B {
&__E {
// default color
}
}
.B__E.B__E--M {
// color i want
}
If nothing is possible, this would be my guess:
.B {
&__E {
// default color
&.B__E--M {
// Color i want
}
}
}
You are looking for the double ampersand selector.
.B {
&__E {
color:black;
&#{&}--M{
color:white;
}
}
}
/* // Outputs:
.B__E {
color: black;
}
.B__E.B__E--M {
color: white;
}
*/

The Sass ampersand and attribute selectors

I want to create a sass file that the selectors will be attribute selectors.
When I work with class selectors, in most of the cases I will do
.parent {
&-child {
}
}
which gives me the following css: .parent-child {}.
I want to achieve the same thing with attribute selectors:
[data-parent] {
&-child {
}
}
which I want to become: [data-parent-child] {}
someone knows how to achieve this? thanks.
You can use this mixin as a workaround to get the desired result.
#mixin child-attribute($child) {
$string: inspect(&);
$original: str-slice($string, 3, -4);
#at-root #{ selector-replace(&, &, "[#{$original}#{$child}]" ) } {
#content;
}
}
The code simply does the following
$string variable is responsible for turning the parent selector to a string using the inspect function
$original variable is responsible for getting the text content of the $string variable i.e the value 'data-parent' from '([data-parent])'
selector-replace function then replaces the parent selector with the concatenation of the $original variable and child variable
When used in the following ways
[data-parent] {
#include child-attribute('-child') {
color: green;
}
}
The css output
[data-parent-child] {
color: green;
}
Depending on what you want to achieve, it can also be used like this
[grandparent] {
#include child-attribute('-parent') {
color: white;
#include child-attribute('-child') {
color: blue;
}
}
}
Which generates the following css
[grandparent-parent] {
color: white;
}
[grandparent-parent-child] {
color: blue;
}
Hope this helps you
You can create mixin that will set styles for elements with data attribytes.
Scss:
#mixin data($name) {
[data-#{$name}] {
#content;
}
}
* {
#include data('lol') {
color: red;
};
}
Css output:
* [data-lol] {
color: red;
}
DEMO
I would go down a slightly different route of having a class on your elements that contain the data attributes.
<div class="data-obj" data-parent="true"></div>
<div class="data-obj" data-parent-child="true"></div>
then in your SASS do
.data-obj {
...
&[data-parent] { ... }
&[data-parent-child] { ... }
}

Use mixin argument to create class name in LESS

I'm trying to create a simple mixin in LESS for different colors I'll use for a website.
What i want is use mixin argument as a part of class name as well.
#green: #5FBEAA; // my color variable
.text-color(#color) {
.text-{#color} {
color: #color;
}
}
.text-color(#green);
The output i'm getting is:
.text-#5FBEAA {
color:#5FBEAA
}
What I want is:
.text-green {
color:#5FBEAA
}
I think I have the solution using Variable Names.
Less
#green: #5FBEAA;
.text-color(#colorname) {
#color: ~"#{colorname}";
.text-#{color}{
color: ##color;
}
}
.text-color(green);
Output
.text-green {
color: #5FBEAA;
}
I don't think its possible. The closest solution for this will be using an additional variable.
#green: #5FBEAA;
.text-color(#name,#color) {
.text-#{name} {
color: #color;
}
}
.text-color(green,#green);
This will compile to
.text-green {
color: #5FBEAA;
}

how do add a dot to a variable to be used as selector in less

I'm currently getting this output:
.'teal-dark' { color: #xxx; }
What I want is this: {
.teal-dark { color; #xxx; }
Here is what I'm trying to do:
#teal-dark: #xxx;
.#{currentMember} div { background: ~"#{#{currentMember}}" };
See: http://lesscss.org/features/#variables-feature-variable-interpolation http://lesscss.org/features/#variables-feature-variable-names and
#current-member: teal-dark;
#teal-dark: red;
.#{current-member} {
color: ##current-member;
}
compiles into:
.teal-dark {
color: red;
}
Possible relevant questions:
Defining Variable Variables using LESS CSS
Dynamic class names in LESS
Here's the fix from another post:
#selector: ~'.#{currentMember}';
#{selector} div { background: ~"#{#{currentMember}}" };

How to change a class format based on body's class with SCSS?

I am making a web app that is used in three (or more) different contexts, and I want each context to have a different color scheme. However, I don't want to have to maintain three different stylesheets when all that changes is colors, typically.
For instance, suppose the themes are red, blue, and orange. One of my stylesheets describes the link colors:
a {
color: $some_color;
}
I want to split this based on the class applied to the body:
body.style1 {
a {
color: $red;
}
}
body.style2 {
a {
color: $blue;
}
}
body.style3 {
a {
color: $orange;
}
}
You can see how this gets unwieldy pretty quickly if you're changing the style for lots of elements. Is there a way to do this more like this?
a {
&closest:body.style1 {
color: $red
}
&closest:body.style2 {
color: $blue;
}
&closest:body.style3 {
color: $orange;
}
}
This way I can code my scss in a clearer, more maintainable way.
It appers you don't have to have the & first, so this works (at least in 3.2.10):
a {
body.style1 & {
color: $red
}
body.style2 & {
color: $blue;
}
body.style3 &{
color: $orange;
}
}
This is what I prefer. Define a mixin like body-style :
#mixin body-style($style, $map) {
body.#{$style} & {
#each $property, $value in $map {
#{$property}: $value;
}
}
}
Then use this for every tag by passing $style as style class of body and $map as map of css keys and values.
a {
#include body-style(style1, (
color: red,
background: white
)
);
}
It will return :
body.style1 a {
color: red;
background: white;
}

Resources