Leonel Galán
Leonel Galán

Reputation: 7167

Reference nested rule when mixin in LESS

I'm trying to keep my HTML clean, and use mixins instead of non-semantic bootstrap classes.

All my "index" tables, should have both .table and .table-hover.

table.index {
  .table;
  .table-hover;
}

This works fine, except for rules applied to elements under .table, e.g:

.table tbody tr

Is there away I can mixin .table tbody tr in .index tbody tr?

table.index {
  .table;
  .table-hover;

  tbody tr {
   .table tbody tr;
  }
}

Of course this last block of code is failing with a simple: syntax error in the sixth line.

Upvotes: 0

Views: 1521

Answers (2)

Leonel Galán
Leonel Galán

Reputation: 7167

The final solution based on ScottS answer is:

@import "twitter/bootstrap/bootstrap";
...
@import "corrections";

.index {
  .table;
  .table-hover;
}

I had to import the variables.less again in correction.less (it is originally imported in bootstrap.less, but it wasn't available in corrections.less). Note that the .less extensions is not needed when importing.

//corrections.less

@import "twitter/bootstrap/variables.less";

.table {
  tbody tr {
    &.success > td {
      background-color: @successBackground;
    }
    &.error > td {
      background-color: @errorBackground;
    }
    &.warning > td {
      background-color: @warningBackground;
    }
    &.info > td {
      background-color: @infoBackground;
    }
  }
}
.table-hover {
  tbody tr {
    &.success:hover > td {
      background-color: darken(@successBackground, 5%);
    }
    &.error:hover > td {
      background-color: darken(@errorBackground, 5%);
    }
    &.warning:hover > td {
      background-color: darken(@warningBackground, 5%);
    }
    &.info:hover > td {
      background-color: darken(@infoBackground, 5%);
    }
  }
}

Upvotes: 0

ScottS
ScottS

Reputation: 72271

The answer is "NO." At present, you cannot mixin a selector that has an element in the selector string. While that might be a limitation of LESS, it would be hard to make something distinguish if a tr is supposed to be a mixin or a selector.

The real issue is that bootstrap failed to use nesting for a portion of its code. For example, the following comes from tables.less (as of 2/18/2013):

.table tbody tr {
  &.success > td {
    background-color: @successBackground;
  }
  &.error > td {
    background-color: @errorBackground;
  }
  &.warning > td {
    background-color: @warningBackground;
  }
  &.info > td {
    background-color: @infoBackground;
  }
}

If it had been constructed like this (note the extra nesting brackets between .table and tbody)...

.table { 
   tbody tr {
      &.success > td {
        background-color: red;
      }
      &.error > td {
        background-color: blue;
      }
      &.warning > td {
        background-color: cyan;
      }
      &.info > td {
        background-color: yellow;
      }
   }
}

... then it would mixin to your .index just fine. So to get what you want, you would need to "correct" the bootstrap code to the above, making sure all elements are nested in a .table call; other selector calls that are not nested would need to be corrected as well. You could do something like a corrections.less file that loads after bootstrap.less, that way if bootstrap updates, you don't lose the corrections. Then, when it does update, you will need to go in and check to see if your corrections need updating (or eliminating, if bootstrap solves the issue themselves).

How much you need to copy over and correct will all depend on how many things are improperly nested that you want to use as mixins. If you don't need to mixin, don't bother correcting it.

Upvotes: 2

Related Questions