Pattern matching with mixins is where mixin is defined several times, with slightly different values, and the mixin that is finally used when the file is compiled is decided by the arguments being used. It looks confusing a bit let’s try to make it understandable. A good example of usefulness of pattern matching with mixins is box shadow and text shadow styles as both take very similar values and very similar format, only difference comes when property name is written.
So, we can create a single mixin to use with both properties. It still looks confusing, it’ll be better to understand it by looking at our code snippet, so have a look below:
// creating a mixin and providing parameters and pattern .shadow: (text: @a, @b, @blur, @color) { .text-shadow: @a @b @blur @color; }
If you look at above code snippet, we are creating our mixin and providing parameters (@a variable, @b variable etc), point to note here is that the first argument named as “text” is not variable, it’s our patter. It’ll be clear just look at the given code below:
// creating a mixin and providing parameters and pattern .shadow: (box: @a, @b, @blur, @color) { .box-shadow: @a @b @blur @color; }
Nothing special change, only the name of pattern changed while all other code is same just copied. So, in this mixin, pattern is “box”. Now when ever we want to use above mixins, we’ll write the name of pattern as first argument and then values for variables. If we have to use mixin for text shadow we’ll provide pattern as text shadow and same is true for box shadow. It’s time to use our mixin for more understanding:
// using a mixin for box shadow, h1 { .shadow: (box, 1px, 1px, 2px, orange); }
That’s it, we just provided name of our mixin class and then provided first parameter named as “box” that means we are applying box shadow. How that box shadow value assumed there? Why not text shadow? Good question, as I already told that first parameter is pattern and not variable, hence pattern value is box, that’s why pattern told that it is box shadow. Same code will be used for text shadow with very minor pattern name change. Let’s see:
// using a mixin for box shadow, h1 { .shadow: (text, 1px, 1px, 2px, orange); }
Now we are applying text shadow instead of box shadow. Look at the code, only pattern name change and totally different results. That’s very simple usage of pattern matching with mixins in less. Now it’s time to explore further about pattern matching mixins.
Pattern matching with default values
If you have gone through from previous parametric mixins lesson, you’ll be familiar with default values in mixins. We can also provide default values for pattern matching as well to get more control. Let suppose we want to apply a font-weight bold to our h1, no matter we are applying text shadow or box shadow but that style must be applied. To get that result our code should look like that:
// creating a mixin and providing default parameter .shadow: (@_, @a, @b, @blur, @color) { font-weight: bold; }
Now our default value will be there no matter box shadow or text shadow is applied. Point to note here is our very first variable, “@_” (@ followed by underscore) any variable. That’s why default value will be there no matter which type of shadow is being applied.
As we matched on text, like “text” or “box” we can also match on arity (simply means rank). So rank here means rank of argument or I would say number of argument etc. Try to explain with example, when we have to apply very same style but with minor change we can use arguments differently too, so same styles would be applied to same arguments while different style can be applied to different argument.
Arity in this case helps us to apply styles properly and so we can provide different arguments. Let’s see with a example; if we have to apply box shadow to our selector we can apply differently. I mean that box shadow may be inner with inset property or outer box shadow. So, in such situations we can create our mixin and arguments can be different like shown below:
// creating a mixin and providing parameters .boxshadow: (@a, @b, @blur, @color) { .box-shadow: @a @b @blur @color; }
Above code snippet will provide box shadow only, so if we have to provide inset as well, we can add five parameters to our second mixin as shown below :
// creating a mixin and providing parameters .boxshadow: (@inset, @a, @b, @blur, @color) { .box-shadow: @inset @a @b @blur @color; }
Now when ever we’ll provide four arguments our first mixin (simply box shadow) will be applied. While if we provide five arguments our second mixin (mixin with inset) will be applied. Which mixin to apply is decided by arity (number of parameters). So, it’s time to close our discussion but let’s see our final code snippet for usage of box shadow:
// using a mixin for box shadow only .outer { .boxshadow: (1px, 1px, 2px, orange); } .inner { .boxshadow: (inset, 1px, 1px, 2px, orange); }
In above code snippet we are having two classes named as outer and inner, so in first case we are applying four arguments in that case only box shadow will be applied while in inner class case we are applying five arguments so box shadow with inset will be applied.