LESS problems with implicit declared css class

238 Views Asked by At

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?

1

There are 1 best solutions below

2
On

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.