21

The .lib-css() mixin is used heavily in Magento 2 LESS files. However its purpose is not apparent, and the mixin definitions don't provide any helpful documentation:

//
//  Add any css property
//  ---------------------------------------------

.lib-css(
    @_property,
    @_value,
    @_prefix: 0
) when (@_prefix = 1)
  and not (@_value = '')
  and not (@_value = false)
  and not (extract(@_value, 1) = false)
  and not (extract(@_value, 2) = false)
  and not (extract(@_value, 3) = false)
  and not (extract(@_value, 4) = false)
  and not (extract(@_value, 5) = false) {
  -webkit-@{_property}: @_value;
       -moz-@{_property}: @_value;
        -ms-@{_property}: @_value;
}

.lib-css(
    @_property,
    @_value,
    @_prefix: 0
) when not (@_value = '')
  and not (@_value = false)
  and not (extract(@_value, 1) = false)
  and not (extract(@_value, 2) = false)
  and not (extract(@_value, 3) = false)
  and not (extract(@_value, 4) = false)
  and not (extract(@_value, 5) = false) {
    @{_property}: @_value;
}

I could see why you would want to use the mixin to add vendor prefixes to bleeding edge CSS properties (although there are few properties where that is necessary any more), but the reason for outputting normal CSS properties using this mixin is not clear. Can anyone shed light on this?

5
  • 1
    I am wondering the same thing, within Magento's code it seems to be inconsistent. For example where background is declared with a variable sometimes they use .lib-css and sometimes they don't, even within the same file.
    – Ben Crook
    Commented May 12, 2016 at 9:13
  • My conspiracy theory on this one is that some of the developers at Magento wanted to have a utility less function that could be used in place of default less. This was more of a 'way of coding less' then a needed too for a specific purpose. But i would love to hear what other people might think about this.
    – circlesix
    Commented Jun 13, 2016 at 20:18
  • 1
    autoprefixer wasn't cool enought?
    – Lorenzo
    Commented Sep 14, 2016 at 9:30
  • 1
    Magento 2 style framework really is absolutely terrible🤮. An annoying effect of this mixin is when inspecting styles using browser devtools, often instead of pointing to where the style was actually declared it points to the '.lib-css' mixin in _utilities.less. Cheers Magento 😑 Does anyone know a way around this other than searching the codebase manually? M2 theme development is extremely frustrating.
    – 00-BBB
    Commented Feb 3, 2021 at 12:41
  • 1
    @00-BBB agree with your final thought! Everything about M2 is an order of magnitude more overengineered that it was for M1 - and that was bad enough. LESS just adds another level of complication that detracts from what we should be doing - building a commerce site. Commented May 26, 2022 at 16:01

2 Answers 2

14

The only uses I can see are the prefixes and removing previously declared rules:

Prefixes

body {
    .lib-css(transition, color .5s ease, @_prefix: 1);
}

Will output:

body {
    webkit-transition: color 0.5s ease;
    -moz-transition: color 0.5s ease;
    -ms-transition: color 0.5s ease;
    transition: color 0.5s ease;
}

Removing previously declared rules instead of unsetting them

.lib-css() gives the ability to remove every rule that uses a certain variable instead of unsetting them or setting them to 0 or none. For example lets say we want to remove every rule that uses @button__shadow. Such as:

.product-list button {
    .lib-css(box-shadow, @button__shadow);
}

If it was only for one element it would be easier to write box-shadow: none;. But if this is on say 20 elements, it will be quicker to remove them all like so:

@button__shadow: false;

This has the added benefit of using @variable: none as it reduces lines of code, instead of adding more.

So compare these two methods:

LESS

Method 1:

.product-list button {
    .lib-css(box-shadow, @button__shadow);
}

Method 2:

.product-list button {
    box-shadow: none;
}

Or alternatively

@button__shadow: 0;

Output

Magento 2 Less

LESS

@button__shadow: false;

.product-list button {
    .lib-css(box-shadow, @button__shadow);
}

Output

There is no output, the rules aren't processed

This does seem like a good idea but the use cases seem pretty small. I'll more likely just use it for the prefixes. It would be much more useful if @variable: false could be set locally, for example only within one div, unfortunately I couldn't get this working.

Core usage

I've noticed some variables are set to false by default, such as ones in lib/web/css/source/lib/variables/_buttons.less, I presume this is so they aren't outputted until required. Also a good idea.

//  Default = secondary button
@button__color: @primary__color;
@button__background: @color-gray95;
@button__border: 1px solid @color-gray-darken2;
@button__gradient-color-start: false;
@button__gradient-color-end: false;
3
  • And how do I know when I need to use @_prefix: 1 ? I guess only on very new features? How do I know
    – Black
    Commented Mar 11, 2020 at 13:33
  • 1
    This site comes in useful for that - shouldiprefix.com
    – Ben Crook
    Commented Mar 11, 2020 at 15:01
  • This feels like one of the best things I've read in a long time... the ability to remove a declaration with .lib-css and setting the property to false is invaluable! I'm sick of CSS files growing via extending. But this allows for an extend to modify the original - genius!!! Thanks!
    – PromInc
    Commented Mar 15 at 18:30
4

The .lib-css() mixin is used to set any css property if there is a value passed to it by a variable. (e.g.)

[![.class {
    .lib-css(border-radius, @button__border-radius);
    .lib-css(border, @button-primary__border);
    .lib-css(color, @button-primary__color);
    .lib-css(background, @color-gray94);
    .lib-css(padding, @indent__s);
}

enter image description here

Also .lib-css() can add -ms-, -webkit- and -moz- prefixes if needed.

If the variable is set to false, the .lib-css() mixin will add nothing to the code.

please review .lib-css variables

enter image description here

also you can find all less help under

<magento install directory>\lib\web\css\docs\utilities.html
4
  • 2
    Thanks for your answer, but it's still not clear why this: .lib-css(border-radius, @button__border-radius); would be any better than: border-radius: @button__border-radius; Commented Dec 19, 2015 at 15:56
  • also you can directly write CSS Property and value like this .lib-css(border-radius, 5px); Commented Jan 5, 2016 at 13:44
  • 2
    This is literally the dumbest mixin of all time. Only the third parameter offers some value: "If set to "1" adds -ms-, -webkit- and -moz- prefixes to the property " Commented Aug 11, 2020 at 18:31
  • Helpful answer. +1 Commented Aug 11, 2021 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.