Ineffectiveness of Less Guard feature

I have a mixin with a guard clause that I've implemented following the provided guidelines.

According to the syntax below, @palette should be selected from a list of custom colors and @color should be assigned a value from a specific set.

The current setup works perfectly as it compiles correctly and generates the expected output.

However, whenever I deliberately introduce an error in the @palette variable, Less fails to compile - is this the intended behavior?

.AccentPalette(@palette; @color:500) when
    (@palette = amber), (@palette = blue), (@palette = blueGrey), (@palette = cyan), (@palette = deepOrange),
    (@palette = deepPurple), (@palette = green), (@palette = grey), (@palette = indigo), (@palette = lightBlue),
    (@palette = lightGreen), (@palette = lime), (@palette = orange), (@palette = pink), (@palette = purple),
    (@palette = red), (@palette = teal), (@palette = yellow) and
    (@color = 50), (@color = 100), (@color = 200), (@color = 300), (@color = 400),
    (@color = 500), (@color = 600), (@color = 700), (@color = 800), (@color = 900) {
    .Swatch(@palette); 

    @accentColor:"@{@{color}}";

    @accent50:  @50; 
    @accent100: @100; 
    @accent200: @200; 
    @accent300: @300; 
    @accent400: @400; 
    @accent500: @500; 
    @accent600: @600; 
    @accent700: @700; 
    @accent800: @800; 
    @accent900: @900;
}

This mixin can be invoked in the following manner:

.AccentPalette(indigo);

An example of a swatch implementation which includes various color values for each shade.

.Swatch(amber)
{
    @50: #fff8e1;
    @100:#ffecb3;
    @200:#ffe082;
    @300:#ffd54f;
    @400:#ffca28;
    @500:#ffc107;
    @600:#ffb300;
    @700:#ffa000;
    @800:#ff8f00;
    @900:#ff6f00;
}

Answer №1

My previous statement was incorrect, as the issue lies with the .AccentPalette mixin guard structure. The Less compiler seems to prioritize the evaluation of and before , (or). This results in the guard always being true when no value is provided for the @color variable, due to the constant matching of @color = 500.

Here is a simplified example to illustrate:

@500: dummy;
.AccentPalette(@palette; @color:500) when
(@palette = amber), (@palette = blue) and
(@color = 50), (@color = 500), (@color = 900) {
  .Swatch(@palette); 
  accentColor:"@{@{color}}";
}

.Swatch(amber){}
.Swatch(blue){}

#demo {
  .AccentPalette(amber;1000);
}

The compiler interprets this as: (note the additional braces)

(@palette = amber), ((@palette = blue) and (@color = 50)), (@color = 500), (@color = 900)

This results in

(false, (false and false), true, false)
or (false, false, true, false), causing the mixin to always match due to at least one true condition.


To resolve this issue, the correct approach would have been:

((@palette = amber),(@palette = blue)) and ((@color = 50),(@color = 500),(@color = 900))

However, using the multiple braces syntax causes a compilation error in the Less compiler. Thus, the workaround is to split the guards into two levels, as shown below:

@500: dummy;

.AccentPalette(@palette; @color:500) when (@palette = amber), (@palette = blue) {
  & when (@color = 50), (@color = 500), (@color = 900) {
    .Swatch(@palette); 
    accentColor:"@{@{color}}";
  }
}

.Swatch(amber){}
.Swatch(blue){}

#demo {
  .AccentPalette(red);
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I use querySelector in JavaScript to target all div elements that have the same class?

I'm having an issue with the document.querySelector in my JavaScript code. It currently only selects the first div that contains the class "test", but I need it to select all such divs. Is there a way to achieve this using my existing JavaScript? ...

Continuous scroll notification within the fixed menu until reaching the bottom

I'm looking to achieve a scrolling notification message that stays fixed at the bottom of a top-fixed menu while the body content continues to scroll normally. Here's an example in this fiddle: HTML: <div class="menu-fixed">I am a fixed me ...

Animation effect in Jquery failing to execute properly within a Modal

I have developed a small jQuery script for displaying modals that is both simple and efficient. However, it seems to only work with the fadeIn and fadeOut animations, as the slideUp and slideDown animations are not functioning properly. I am unsure of the ...

Unique rephrased text: "Varied wrapping styles in both

Feeling frustrated with a seemingly commonplace issue. Despite the thousands of times it has been asked before, I can't seem to find an answer on Google. I wanted to neatly display my text within one of my cards, but so far I've only achieved th ...

Ways to create a smooth transition in element height without a known fixed target height

Is it possible to create a smooth height transition for an element when the target height is unknown? Replacing height: unset with height: 100px allows the animation to work, but this presents a problem as the height needs to be based on content and may v ...

minimize the size of the image within a popup window

I encountered an issue with the react-popup component I am using. When I add an image to the popup, it stretches to full width and length. How can I resize the image? export default () => ( <Popup trigger={<Button className="button" ...

Is there a way to enable Fancybox to change to the adjacent gallery by simply using the 'up' or 'down' arrow keys?

I am currently working on a layout that consists of a vertical column of thumbnail images, each linked to its own gallery with additional images. When the user clicks on a thumbnail image, Fancybox opens, allowing them to navigate through the images within ...

The Material UI button shifts to a different row

I need help adjusting the spacing between text and a button on my webpage. Currently, they are too close to each other with no space in between. How can I add some space without causing the button to move to the next line? const useStyles = makeStyles((the ...

Tips for creating a customized dropdown menu that opens upwards without relying on Bootstrap

Looking for some assistance with creating an animated dropdown menu that slides upwards. Any help is appreciated! $('.need-help').click(function() { $('.need_help_dropdown').slideToggle(); }); .need-help { background:url(../im ...

React and Material UI: troubleshooting problems with layout columns

I'm working on a project with three columns and I want to include a column for removing each row. Is it possible to add a "removing" column on the right? If so, how can I go about doing it? VIEW CODESANDBOX: HERE const CustomTableRow = ({ row, index ...

Getting the x-axis points on Google charts to start at the far left point

I have integrated the Google API for charts into my application and am using multiple charts on the same page. However, I am facing an issue with setting padding for the charts. When I include more data points, the chart area occupies more space in the div ...

Refresh a function following modifications to an array (such as exchanging values)

Looking to re-render a function after swapping array values, but the useEffect hook is not triggering it. I need assistance with this as I plan to integrate this code into my main project. Below are the JSX and CSS files attached. In App.js, I am creating ...

What is the method of adding a child to the outerHTML of the parent element instead of within it?

Is there a way to use the outerHTML method on a parent element to append a child element so that the icons appear outside of the targeted element rather than inside it? The current code snippet shows the icons inside the box, but I want them to be placed o ...

Guide to creating the onclick feature for a dynamic button in Meteor

<template name="actionTemplate"> {{#each action}} <button class="myButton" id={{_id}}>btn</button> {{> action}} {{/each}} </template> <template name="action"> <div class="sct" id={{_id}}> ...

"Enhance your website with a unique Bootstrap 5 carousel featuring multiple

As a beginner in Bootstrap, I am currently working on an ecommerce template to learn about Bootstrap 5. I am interested in creating a carousel that displays multiple slides at once, like a products slider with left and right arrows. Is this possible in Bo ...

How can we use JavaScript to retrieve an element with custom styling?

I've encountered a strange issue with my script where it seems to stack up borders and display a 2px border instead of the intended 1px border when switching elements on click. Here is the link code I am using: <li ><a href="plumbing.php"&g ...

Exploring cross-browser compatibility with the use of CSS3 and JavaScript

Starting a new project to create a fresh website. It seems like many people are leaning towards CSS3 and AJAX, neglecting browsers without JavaScript support. They resort to workarounds like enabling CSS3 through JavaScript in older browsers. Is this the ...

Dynamically modifying the styling of elements within an iframe

In my current project, I encountered a challenge with changing the background color to black and the body text color to white within an iframe. Additionally, all elements that are originally styled with black in an external stylesheet also need to be chang ...

Having trouble changing the Font Awesome icon on click?

I'm struggling to figure out why I can't change a font awesome icon using a toggle. I've tried various solutions but nothing seems to be working. Any insights on what might be causing this issue? (HTML) <span class="toggle-icon" ...

Make an element in jQuery draggable but always within the viewport

My issue is that when I resize the window, the element stays in its position until I start dragging it. Once I drag it and then resize the window again, it doesn't stay within its container. To better illustrate my problem, you can view a demo on Fid ...