Can I add a variable to a mixin function name in Less? - css

Is this possible to do in some way I don't know? I'm trying to add a variable in the mixin function name.
#mybar: Test;
.mymixin() {
padding: 10px;
}
.mymixin#{mybar}() {
padding: 10px;
}
.test {
.mymixinTest();
}

I think it should work if you do:
.myMixin(#myvar) {
.myMixin#{myvar} {
//your css
}
}

Related

sass prepend root class to current selector

I am having trouble prepending the root class to my current selector in sass. I have the following code:
.cta-two-columns {
&__text-holder {
#at-root&#{__inner} {
// also tried #at-root __inner&{#}
// and many others like #at-root__inner
padding: rem(25px);
}
}
}
but this gives me the following:
.cta-two-columns__text-holder__inner {
padding: rem(25px);
}
I don't understand the above - what's the point of at-root as you may as well just do &__inneras it gave me the same as the two things I have shown I tried
how do I get
.cta-two-columns__text-holder .cta-two-columns__inner {
}
without having to resort to
.cta-two-columns {
&__text-holder {
.cta-two-columns__inner {
padding: rem(25px);
}
}
}
Or is this the only way to do it in sass?
#at-root doesn't really work like you may think in this case. #at-root will simply make the declaration outside the nest. To better understand, add another CSS declaration like below:
.cta-two-columns {
&__text-holder {
margin: 10px;
#at-root&#{__inner} {
padding: rem(25px);
}
}
}
This will produce the following CSS code:
.cta-two-columns__text-holder {
margin: 10px;
}
.cta-two-columns__text-holder__inner {
padding: rem(25px);
}
Simply imagine how the selector will be created without #at-root then make it outside.
Without it will produce this:
.cta-two-columns__text-holder {
margin: 10px;
}
.cta-two-columns__text-holder .cta-two-columns__text-holder__inner {
padding: rem(25px);
}
Then we simply omit .cta-two-columns__text-holder.
One idea to obtain what you want is to consider a variable where you can declare the main class then you will be able to nest as many element as you want:
$sel: '.cta-two-columns';
#{$sel}__text-holder {
#{$sel}__inner {
padding: rem(25px);
}
}
Will produce:
.cta-two-columns__text-holder .cta-two-columns__inner {
padding: rem(25px);
}
with more nested elements:
$sel: '.cta-two-columns';
#{$sel}__text-holder {
#{$sel}__outer {
#{$sel}__inner{
#{$sel}__wrap{
padding: rem(25px);
}
}
}
}
Will produce
.cta-two-columns__text-holder .cta-two-columns__outer .cta-two-columns__inner .cta-two-columns__wrap {
padding: rem(25px);
}

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;
}

Simplifying sass attribute selectors

I'm trying to come up with a way to simplify some SCSS attribute selectors. What I end up with is:
[data-attr="opt1"] { ... }
[data-attr="opt2"] { ... }
[data-attr="opt3"] { ... }
What I'm hoping for is to be able to write something closer to:
[data-attr]
&="opt1" { ... }
&="opt2" { ... }
&="opt3" { ... }
via a mixin, or whatever. Can't come up with a solution though. Any clever ideas?
I've come to this idea:
#mixin attrVal($value) {
$attr: str-slice(#{&}, 2, -2); // $attr = "data-attr"
#at-root {
[#{$attr}="#{$value}"] {
#content;
}
}
}
[data-attr] {
#include attrVal('opt1') { width: 10px; }
#include attrVal('opt2') { width: 20px; }
#include attrVal('opt3') { width: 30px; }
}
Output (tested on sassmeister.com)
[data-attr="opt1"] { width: 10px; }
[data-attr="opt2"] { width: 20px; }
[data-attr="opt3"] { width: 30px; }
For this specific example there's no that huge simplification, but with this approach you're actually decoupling the attribute name from its value (in the aim of code reuse).

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}}" };

Extending a Nested Placeholder in SCSS

Is it possible to #extend a SCSS placeholder with nesting, and have that nesting reflected in the resulting class?
Given a nested placeholder:
%my-form-field {
...
&__label {
...
}
&__feedback {
...
}
}
I currently have to do the following:
.one-of-many-targets {
#extend %my-form-field;
&__label {
#extend %my-form-field__label;
}
&__feedback {
#extend %my-form-field__feedback;
}
}
But I'd like to be able to simplify this to:
.one-of-many-targets {
#extend %my-form-field;
}
... and have it resolve to:
.one-of-many-targets { ... }
.one-of-many-targets__label { ... }
.one-of-many-targets__feedback { ... }
Is there a different way to write my placeholder and #extends to make the SCSS cleaner, as in the 2nd example?
You can use a mixin instead:
#mixin my-form-field() {
width: 10px;
&__label {
width: 20px;
}
&__feedback {
width: 30px;
}
}
.one-of-many-targets {
#include my-form-field();
}
will generate:
.one-of-many-targets {
width: 10px;
}
.one-of-many-targets__label {
width: 20px;
}
.one-of-many-targets__feedback {
width: 30px;
}
You could try use selector.append()
See: https://github.com/sass/sass/issues/2808#issuecomment-574413393
Also see more info why parent selector didn't work as you expect in extend-only selectors: https://github.com/sass/sass/issues/2262#issuecomment-291645428

Resources