Variable Concatenation - using a mixin to dynamically create class name - css

H I, Working with Less and here is what I am hoping :
.createClass() {
#varone:one;
#vartwo:two;
#classname: #{varone}_#{vartwo};
.testClass_#{classname} {
padding:.5em;
}
}
.createClass();
Things I have tried from a few searches :
#classname: '#{varone}_#{vartwo}';
But this renders as:
.testClass_'one_two' {
padding:.5em;
}
And I read about the tilder ~ ( but might be just for the phpless I found off a search ? )
#classname: ~'#{varone}_#{vartwo}';
didn't run.
I am running on node , compiling via the grunt less contrib
How do I render a 'unquoted string' in this way / is it possible ?
Many Thanks,

#classname: ~'#{varone}_#{vartwo}'; (or same with double quotes) is the correct syntax and works in all conformant Less compilers. I.e.:
.createClass() {
#varone: one;
#vartwo: two;
#classname: ~'#{varone}_#{vartwo}';
.testClass_#{classname} {
padding: .5em;
}
}
.createClass();

Ahh I found it.
http://lesscss.org/functions/#string-functions
Can use:
#classname: e(#{varone}_#{vartwo});
The e(str) filter does it
Bit more RTFM was needed from me !

Related

extend from class name in another file sass

So I'm currently doing some styling, following the BEM standard.
An example of what I'm doing could be this:
.block{
&__element {
}
}
what i would like to do is this:
// file a
.block {
...
}
-
// file b
// add magic to reference the `block`class in file a
&__elelemnt {
...
}
What I'm currently doing:
// file a
.block {
...
}
-
// file b
.block__elelemnt {
...
}
(manually adding the block part to the name)
Is there any way to reference this in a smarter way?
Thanks in advance
You can have this file structure:
block-1/
--block-1.scss
--element-1.scss
--element-2.scss
block-2/
--block-1.scss
--element-1.scss
--element-2.scss
And import elements files info block files.
block.scss:
.block {
color: red;
#import "element-1.scss";
#import "element-2.scss";
}
element-1.scss:
&__element-1 {
color: green;
}
Compiles to:
.block {
color: red;
&__element-1 {
color: green;
}
}
This is perhaps the best you can do.
$namespace: "block";
.#{$namespace}-myClass {
...
}
OUTPUT
.block-myClass {
...
}
You can keep a variable $namespace at the top of your file or in a different file and import it. The advantage of using a variable is you can update it once and all your references will be updated.
SASS is all about DRY.
As in, if you want to modify anything, you should be able to modify it from one single place. If you need anything available across multiple files, consider defining its value in a _vars file and including it everywhere you need it. Also note this has nothing to do with code shortness, but with code maintainability and flexibility.
In fact, even if you do get to write more code (which, in practice, doesn't happen), the advantage of DRY far outweighs it.
Here's how it should be done:
/* _vars.scss: */
$block:block;
/* a.scss: */
#import _vars;
.#{$block} {
...
}
/* b.scss: */
#import _vars;
.#{$block}__element {
...
}
Now, whenever you need to change block value, you can do it from one place: _vars.scss.
But, in practice, most people use the initial technique (nesting):
.block {
...
&__element {
...
}
}
Chances are .block and .block__element are related and, overall, it makes more sense to put them in same file. As your app grows in complexity, you'll find it harder to keep track of your code if you over-complicate it.

Less syntax with ## meaning

I have downloaded a theme for bootstrap and In their less sources I have a mixin like:
.label-color(#color) {
#label-class:~"label-#{color}";
#badge-class:~"badge-#{color}";
#label-color:##label-class;
.#{label-class}, .#{badge-class} {
background-color:#label-color !important;
}
}
.label-arrow(#color) {
#label-class:~"label-#{color}";
#label-color:##label-class;
.#{label-class}{
&.arrowed:before {
border-right-color:#label-color;
}
&.arrowed-in:before {
border-color:#label-color;
}
&.arrowed-right:after {
border-left-color:#label-color;
}
&.arrowed-in-right:after {
border-color:#label-color;
}
}
}
.label-color(~"lime");
.label-color(~"red");
My problem is that #label-color:##label-class;
because my internal compiler less4j give me error at this double ## and I don't understand why. Local compiler Crunch is working and know to compile that so is not a wrong syntax.
Can someone give me a hint pls, ty.
As already mentioned by #deceze, you can read at http://lesscss.org/features/#variables-feature-variable-names that the double # will be use to create a variable variable name in Less:
For instance:
#red: darkred;
#color: "red";
p {
color: ##color;
}
Outputs:
p {
color: darkred;
}
Notice that the variable name (#color) should be a string.
The above should also work in less4j according the docs which can be found at: https://github.com/SomMeri/less4j/wiki/Less-Language-Variables:
If the variable contains a string, then it can act as a reference to
another variable.

Know if the class exists with scss

Short description:
I'm using scss with compass, I need to know that the class exists or not.
Long Description:
What I'm trying to do is create a mixin for margin. We can pass the margin we need for all the dimensions and if will check dose any class exists for that dimensions if yes than it will extent it else will apply the dimension. For example:
I already have .mr5 class which is
.mr5 { margin-right: 5px; }
Now if the value passed in the mixin for the right dimension is 5 than I want to check if first something like
if ( exist .mr5 ) { #extend .mr5; } else { right: $dimension; }
I don't think it's possible to check for the existence of a class. I found this issue on the Sass github page, which asks for something similar, but got closed with the following comment that you can use the !optional flag for this:
The !optional flag is provided for handling classes and placeholders that may not exist.
For example:
.<your_class> {
.mr5 { margin-right: 5px; }
}
<your_selector> {
#extend .mr5 !optional;
}
}
See also the SASS reference on this flag for more info.

Concatenate String for class name in LESS

I am converting LESS to CSS, there I want to run the LESS function below:
.myPL( #val ) {
.pL #val{
padding-left:#val;
}
}
Function Call:
.myPL( 20px );
Expected result:
.pL20px{padding-left:20px}
But actual result is Syntax Error.
Please help me to concatenate the strings in class name in LESS.
What you are looking for is called selector interpolation ... you can find it here: http://lesscss.org/#-selector-interpolation
Your mixin would need to look like this for it to work:
.myPL( #val ) {
.pL#{val} {
padding-left: #val;
}
}
What you are trying to achieve does not work in LESS:
You could do:
.myPL( #val ) {
padding-left: #val;
}
Why on earth would you manually define each possible variant of padding left with the classname itself? That's not what LESS was designed for, and doesn't really make much sense with the context you've given.
The idea of mixins is to make them reusable, but I can't understand why you'd call a classname in the middle of that mixin. Use LESS mixins properly, and do the following:
.pl(#val) {
padding-left: #val;
}

SASS compilation error with nth-child selector

So I did a bit of research around here and was unable to find an answer, so hopefully, somebody here can help me out...
I have the following SASS code
$column: 7;
table
{
th:nth-child($column)
{
// This does NOT compile
}
th:nth-child(7)
{
// This does compile
}
}
Why is it that using the nth-child selector in combination with a variable does not compile within SASS? Is there any alternative I can go about using a dynamic value with the nth-child selector?
A variable must be interpolated when used with a selector (e.g. as an argument to a functional pseudo-class). In your case, the syntax should look something like this:
$column: 7;
table
{
th:nth-child(#{$column})
{
// ...
}
}

Resources