Generic `vendors` mixin
Asked Answered
S

3

2

Defining vendors' mixins is common task under LESS, ie:

.box-shadow() {
    -moz-box-shadow:@arguments;
    -webkit-box-shadow:@arguments;
    -o-box-shadow:@arguments;
    -ms-box-shadow:@arguments;
    box-shadow:@arguments;
}

.border-radius() {
    -moz-border-radius:@arguments;
    -webkit-border-radius:@arguments;
    -o-border-radius:@arguments;
    -ms-border-radius:@arguments;
    border-radius:@arguments;
}

...

But it seems a bit repeating...


What I would like is a generic vendor mixin which do this for me, ie:

.vendors(@prop, @val) {
    -moz-@prop:@val;
    -webkit-@prop:@val;
    -o-@prop:@val;
    -ms-@prop:@val;
    @prop:@val;
}

Then defining box-shadow mixin would as simple as:

.box-shadow() {
    .vendors(box-shadow, @arguments);
}

The problem is my .vendors mixin does not compile...

I tried:

.vendors(@prop, @val) {
    -moz-@prop: @val;        /* Error */
    ~"-moz-@{prop}": @val;   /* Error */
    ~`"-moz-@{prop}": @val;  /* Error */
}

Do you have an idea on how to do this?

Cheers

Shawanda answered 16/8, 2011 at 19:53 Comment(4)
Its a good idea, but currently there is no way to make this work. The problem, as I see it is that the paramaters passed can only be used as an argument for a predefined property in the mixin. I imagine the less parser simply is not looking for parameters on the property-side of the : ... maybe you should open a ticket on @cloudhead's git repository for lessUnpaid
Ok, issue just opened: github.com/cloudhead/less.js/issues/345Shawanda
I recently found a hackerish workaround for this, by trying to inject dynamically produced vendor prefixed properties into another property (it seems a bit messy but it produced working css): #14868542Millinery
I played around with it a little more and updated the answer that I linked to above with a solution that doesn't produce unnecessary additional properties.Millinery
S
4

Stylus has this, which is called Interpolation, eg:

vendor(prop, args)
  -webkit-{prop} args
  -moz-{prop} args
  {prop} args

border-radius()
  vendor('border-radius', arguments)

box-shadow()
  vendor('box-shadow', arguments)

— Then,

button
  border-radius 1px 2px / 3px 4px

yields to:

button {
  -webkit-border-radius: 1px 2px / 3px 4px;
  -moz-border-radius: 1px 2px / 3px 4px;
  border-radius: 1px 2px / 3px 4px;
}

\o/

Shawanda answered 5/10, 2011 at 19:43 Comment(1)
what about Less or Sass implementations of Interpolation ?Swarth
S
0

Another option, that I think is a little cleaner, would be do create a list of vendors and then iterate over that list to create the particular styles you want. Here's an example:

ALLVENDORS = webkit moz o ms w3c

vendors(prop, args)
  for vendor in ALLVENDORS
    if vendor == w3c
      {prop}: args
    else
      -{vendor}-{prop}: args

This creates a list of vendors that you want to support and then allows you to reuse them. if later, you decide you want to support another prefix or want to remove one, all you have to do is remove it from the list.

And then you would use the list just as shown above:

border-radius()
  vendors(border-radius, arguments)

box-shadow()
  vendor(box-shadow, arguments)
Sixfooter answered 6/11, 2013 at 2:21 Comment(0)
W
0

I'm pretty sure less now has it. I've used this code in a Meteor.js project:

.vendor(@property, @value) {
  -webkit-@{property}: @value;
  -khtml-@{property}: @value;
  -moz-@{property}: @value;
  -ms-@{property}: @value;
  -o-@{property}: @value;
  @{property}: @value;
}

.vertical-align {
  position: relative;
  top: 50%;
  .vendor(transformY, -25%);
}
Whale answered 19/5, 2015 at 12:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.