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
    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
    Jun 13, 2016 at 20:18
  • 1
    autoprefixer wasn't cool enought?
    – Lorenzo
    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
    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. May 26, 2022 at 16:01

2 Answers 2

13

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;
2
  • And how do I know when I need to use @_prefix: 1 ? I guess only on very new features? How do I know
    – Black
    Mar 11, 2020 at 13:33
  • 1
    This site comes in useful for that - shouldiprefix.com
    – Ben Crook
    Mar 11, 2020 at 15:01
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; Dec 19, 2015 at 15:56
  • also you can directly write CSS Property and value like this .lib-css(border-radius, 5px); 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 " Aug 11, 2020 at 18:31
  • Helpful answer. +1 Aug 11, 2021 at 8:34

Your Answer

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

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