Less guard not working with multiple arguments from mixin - css

I have searched the internet and try multiple codes but can't figure this one out. Hopefully you can be the helping hand.
The problem: Guard is not triggered when mixin have multiple values.
Button.less
/* CTA Box */
&ctabox {
.inline-box(#lightergrey);
&__header {
display: inline-block;
margin: 5px 0;
.font(#size: 18px, #weight: 700);
}
&__button {
.button(#style: #orange);
.button-icon-right();
}
}
As you can see I use button() mixin, #style: #orange works and triggers this guard:
.button(#style) when (#style = #orange) {
/* Rendered mixin: Button #style when #orange */
color: #FFF;
&:hover, &:focus {
background: #lightorange;
color: #FFF;
}
}
But when I use this:
&__button {
.button(#style: #orange, #width: 100%);
.button-icon-right();
}
The guard isn't triggered anymore, although the button #style is still #orange.
Could anyone explain this behavior?

Ok, after some digging, it seems that mentioning all arguments of a mixin function is the way to go. Instead of just .button(#style) I changed it to .button(#style, #width) and the guard is functioning correctly for now.
.button(#style, #width) when (#style = #orange) {
/* Rendered mixin: Button #style when #orange */
color: #FFF;
&:hover, &:focus {
background: #lightorange;
color: #FFF;
}
}

Related

SCSS Nesting and extend

When I do a yarn build of the scss below I can only see the .select-list__item:hover in the compiled css, I am not seeing anything else from the class such as .select-list__item--selected I am not sure what the issue here is.
%select-list__item {
&:hover {
background: red;
}
&--selected,
&--selected:nth-child(2n),
&--selected:hover {
background: #00FF00;
}}
.select-list__item {
#extend %select-list__item;}
I believe it is to do with how placeholders (ie: %chosen-name) are meant to be used.
Although this is not explicitly pointed out in the documentation they are meant to be small bits that are reusable.
At my company, we use one for our generic button styles (margin, padding, font) and we extend that into all of our buttons (primary, secondary, tertiary).
A potential solution for your use case:
%select-list__item {
&:hover {
background: red;
}
&:focus{
background: blue;
}
}
.select-list__item {
#extend %select-list__item;
&--selected,
&--selected:nth-child(2n),
&--selected:hover {
background: #00FF00;
}
}
Or here's another - bit of an OTT solution for the example but you get the idea:
%select-list__item {
&:hover {
background: red;
}
&:focus{
background: blue;
}
}
%selected-list__item {
background: #00FF00;
&:nth-child(2n),
&:hover {
background: #00FF00;
}
}
.select-list__item {
#extend %select-list__item;
&--selected {
#extend %selected-list__item
}
}

How to nest this scss so that it still functions as expected

I have a scss file that I need to orgnanize by nesting some of these properties, I've tried to nest them but the properties do not seem to work when I nest them. I was just wondering if there is a proper way to do it, thanks in advance!
This is how it is working at the moment:
input~.checked-icon {
color: $primary-color;
background-color: transparent;
&:hover {
background-color: transparent;
}
}
input:disabled~.checked-icon {
color: $disabled-color;
}
This is what i've tried:
input~.checked-icon {
color: $primary-color;
background-color: transparent;
&:hover {
background-color: transparent;
}
&:disabled {
color: $disabled-color;
}
}
Your current solution is creating a selector that looks like this:
input ~ .checked-icon:disabled {
color: $disabled-color;
}
where the :disabled is applied to the .checked-icon.
The additional :disabled rule needs to be applied to the input, so you would want to use:
input {
&~.checked-icon {
color: $primary-color;
background-color: transparent;
&:hover {
background-color: transparent;
}
}
&:disabled~.checked-icon {
color: $disabled-color;
}
}
Keep in mind there are lots of useful online tools for playing with Sass and viewing the compiled code. Like Sassmeister.

Does SCSS (SASS) selector order matter for nested classes

Here I have SCSS to style list items. What I'm wondering is if the order of selection for classes and pseudo-selectors. So basically, does &:before.active equal &.active:before?
Here is the full example of the latter:
.sidebar-list {
list-style-type: none;
padding: 0;
& li {
padding: 4px 0;
&:before { // Here,
color: darken($font-color, 60%);
font-family: "FontAwesome";
content: "\f101\00a0";
}
&.selected:before { // And here.
color: darken($font-color, 30%);
}
}
}
And the former of the part that matters (inside the li):
&:before { // Here,
color: darken($font-color, 60%);
font-family: "FontAwesome";
content: "\f101\00a0";
&.selected { // And here. This would evaluate to "li:before.selected"
color: darken($font-color, 30%);
}
}
Which one would be correct for styling the :before psuedo-selector for a list item?
Thanks!
Yes, the order does matter. li:before.selected will basically be ignored because it is invalid.
Here's a snippet for example:
span::before {
content:'span::before (Normal)';
background-color: #ddd;
}
/* Valid */
span.ribbon::before {
content: "span.ribbon::before (Valid)";
background-color: #0f0;
}
/* Invalid. Will be ignored */
span::before.ribbon {
content: "span::before.ribbon (Invalid)";
background-color: #f00;
}
<span></span>
<span class="ribbon"></span>
Also, you'll want to use double-colons for the ::before pseudo-element (updated in CSS3).
Reference: Pseudo Element Docs

Using LESS, is it possible to extend parametric mixins?

I'm new to LESS and I'm just experimenting with it, using version 1.5. I discovered the useful extend command, but I was wondering if that could be applied to parametric mixins as well as static ones. Apparently, this doesn't seem possible, based on my experiments:
This works
.some-mixin {
}
.child {
&:extend(.some-mixin);
}
This doesn't work and throws an "unexpected token" error:
.some-mixin(#color, #bgcolor) {
color: #color;
background-color: #bgcolor;
}
.child1 {
&:extend(.some-mixin(red, blue));
border: 1px solid blue;
}
.child2 {
&:extend(.some-mixin(red, blue));
border: 1px solid green;
}
.child3 {
&:extend(.some-mixin(red, blue));
border: 1px solid red;
}
Is this a current limitation of LESS, or am I using it incorrectly? Thanks in advance for the answers.
Edit - Added expected output, as per request
What I would expect makes more sense when there are more children extending the parametric mixin:
.child1,
.child2,
.child3 {
color: red;
background-color: blue;
}
.child1 {
border: 1px solid blue;
}
.child2 {
border: 1px solid green;
}
.child3 {
border: 1px solid red;
}
I'm not sure what you are trying to achieve (that is, I am not sure what you expect the :extend() code to actually do if it were extending the parameteric mixin). If your desire is to define the colors of .child, then using it as a straight mixin works:
LESS
.some-mixin(#color, #bgcolor) {
color: #color;
background-color: #bgcolor;
}
.child {
.some-mixin(red, blue);
}
CSS Output
.child {
color: #ff0000;
background-color: #0000ff;
}
This also makes .child itself a mixin for the red and blue color combination, which I think would have been a net result of the extension working if it had worked. That is, I would expect your second set of code to have produced something like this (theoretically; this does not actually work nor is it actually produced in LESS):
.some-mixin(#color, #bgcolor),
.child(#color: red, #bgcolor: blue) {
color: #color;
background-color: #bgcolor;
}
But these two are nearly equivalent as mixins (one has the added parameters):
/* theoretical mixin if extension worked */
.child(#color: red, #bgcolor: blue) {
color: #color;
background-color: #bgcolor;
}
/* code from straight use of .some-mixin in .child */
.child {
color: #ff0000;
background-color: #0000ff;
}
So that either of the above used like so will get the result of mixing in the child values to the new selector:
LESS
.test {
.child; /* or using .child(); */
}
CSS Output
.test {
color: #ff0000;
background-color: #0000ff;
}
No, currently this is not supported. But it's planned to be implemented in future versions.

Comments in CSS make it wrong

Situation
I recently decided to put comments in my CSS files. And once I did so, one of them stopped working.
Both ways of making comments make my entire CSS file not to work. I know this is lacking informations, I just don't know where it could even possibly come from.
In case it does matter, this is how I write my CSS:
// Background
body { background-color: #666666; }
#content { background-color: #cccccc; }
#menu { background-color: #cccccc; }
#menu-footer { background-color: #33cccc; }
#menu-items a.active { background-color: #33cccc; }
#menu-items a:hover { background-color: #99cccc; }
// The white spaces are actually tabs (Alt+i on Emacs)
Update 1
I am looking for ways to debug this situation. I see my CSS files in the developer tool from Google Chrome, but properties are not applied.
foobar {
// color: cyan;
}
Does this simply make the CSS wrong but only on the one line ? So the rest of the file keep getting parsed ?
Update 2
I always used // to comment my CSS but with the later notation I used in this post. Now that I changed my mind and am using inline CSS, // being an invalid token make the whole file not readable.
css does not recognize the double slash as a comment. You have to use the
/* */ one.
I might be wrong, but since the double slash is not a valid css token the behaviour might be browser dependent. I would expect browsers to simply ignore the property or the statement that follows the //, but I never checked/tested.
There are rules on what browsers should do in various situations, however I did not see any for unknown token (maybe a I didn't look well enough).
Use */ Text */ , instead of // (// is comment in javascript)
/* Comment */
For Example
/**** Background ****/
body { background-color: #666666; }
#content { background-color: #cccccc; }
#menu { background-color: #cccccc; }
#menu-footer { background-color: #33cccc; }
#menu-items a.active { background-color: #33cccc; }
#menu-items a:hover { background-color: #99cccc; }
/* The white spaces are actually tabs (Alt+i on Emacs) */
Try the comments this way
/* Background */
body { background-color: #666666; }
#content { background-color: #cccccc; }
#menu { background-color: #cccccc; }
#menu-footer { background-color: #33cccc; }
#menu-items a.active { background-color: #33cccc; }
#menu-items a:hover { background-color: #99cccc; }
/* The white spaces are actually tabs (Alt+i on Emacs) */
The only way to comment in CSS is by /* this is a comnent */
/*This is a comment*/
p
{
text-align:center;
/*This is another comment*/
color:black;
font-family:arial;
}

Resources