0

We have the following declarations in styles.less:

.table tbody > tr > td {
    &.colnum, &.colnumdec {
            > input[type=text], > input[type=number] {
                text-align: center;
            }
        }
    }

.inputquantity {
    .colnumdec;
    width: 50px;
}

.inputprize {
    .colnumdec;
    width: 70px;
}

The problem is that LESS complains at inputprize { .colnumdec; with undeclared mixin.

We tried to solving it by adding a explicit declarations of those clases:

.colnum, .colnumdec {
}

But having no properties makes the LESS compiler to omit them, if we instead put one irrelevant property it works fine:

.colnum, .colnumdec {
    border:inherit;
}

Whats the correct way of solving this?

VSP
  • 2,367
  • 8
  • 38
  • 59

1 Answers1

5

The problem is that LESS complains at .inputprize { .colnumdec; with undeclared mixin.

This is expected since .colnumdec is not in the global scope (and .inputprize has no access to the .table tbody > tr > td scope where the .colnumdec is defined).

The correct syntax to "call" .colnumdec within .inputprize would be something like .table tbody > tr > td.colnumdec; however LESS does not allow using non-class or non-id selectors (i.e. non-. and non-# like body) as mixins or namespaces.

Solution #1:

The usual way to handle this kind of stuff is to move the shared code into a dedicated mixin, e.g.:

.colnum() {
    > input[type=text], > input[type=number] {
        text-align: center;
    }
}

.table tbody > tr > td {
    &.colnum, &.colnumdec {
        .colnum();
    }
}

.inputquantity {
    .colnum(); // parens are optional here
    width: 50px;
}

.inputprize {
    .colnum();
    width: 70px;
}

Solution #2:

#1 produces quite bloated CSS output, so more optimised way recently getting more popular is to use the "Extend" feature, e.g.:

.table tbody > tr > td {
    &.colnum, &.colnumdec {
        > input[type=text], > input[type=number] {
            text-align: center;
        }
    }
}

.colnum() {
    &:extend(.table tbody > tr > td.colnumdec all);
}

.inputquantity {
    .colnum(); // parens are optional here
    width: 50px;
}

.inputprize {
    .colnum();
    width: 70px;
}

The other important benefit of this extend-based solution is that it's not intrusive, i.e. you don't need to modify .table tbody > tr > td content.

seven-phases-max
  • 11,765
  • 1
  • 45
  • 57
  • It seems factible, but could be possible to make .colnum and .colnumdec usable directly instead of .colnum() (we use this definitions for subtemplates too and prefer make it easy for the other developers) – VSP Dec 10 '13 at 16:49
  • 1
    Parens on calling a mixin with 0 parameters are optional so for other developers both #1 and #2 may look exactly like it was intended to be with your initial example (Though personally I would prefer to distinguish between "real selector" and "sub-template" (aka mixin) expansions by seeing those parens). – seven-phases-max Dec 10 '13 at 17:57