10

Because of bootstrap3, lots of my html will end up like this:

<div class="form-group">
    <label class="control-label col-xs-4 col-sm-6">Name on card</label>
    <div class="col-xs-8 col-sm-6">
        <input class="form-control" type="text" placeholder="Name on Card" required />
    </div>
</div>
<div class="form-group">
    <label class="control-label col-xs-4 col-sm-6">Card Number</label>
    <div class="col-xs-8 col-sm-6">
        <input class="form-control" type="text" placeholder="Card Number" name="EWAY_CARDNUMBER" required value="4444333322221111" />
    </div>
</div>

See the above code, the label node has multiple classes for different media screens. And I want to simply them using my own class to shorten them.

I am trying to less to create a class which extends from multiple classes like

my-control-label:extend(.control-label, .col-xs-4, col-sm-6){}

But that doesn't work, because less uses exact match for the above example. Yes I could try to extend "all" like the following:

my-control-label:extend(.control-label all, .col-xs-4 all, col-sm-6 all){}

But it is annoying, and it will blow the generated css.

So is there any easy way to avoid such duplication?

Thanks, Ron

Update #1:

Even extend all doesn't work for my case

Html

<div id='finalise'>
  <form class='form-horizontal'>
    <div class='form-group' >
      <label class='my-label' />
      <div class='my-controls'>
        <input class="form-control" type="text" placeholder="Name on Card" required />
      </div>

      ...
    </div>
  </form>
</div>

Less:

#finalise {
    .my-label:extend(.control-label all, .col-xs-4 all, .col-sm-3 all, .col-lg-2 all){}
    .my-controls:extend(.control-label all, .col-xs-8 all, .col-sm-5 all, .col-lg-4 all){}
}

Generated css:

@media (min-width: 768px) {
  .form-horizontal .control-label,
  .form-horizontal #finalise .label,
  .form-horizontal #finalise .controls {
    text-align: right;
  }
}

See the 3rd line will not apply the the html node, that's why it doesn't work.

Any suggestions?

Update #2: Though it is not a generic way to combine several classes into a custom one, but it solved this problem. It uses bootstrap grid mixins solved this problem. Thanks NiloVelez

Html

<div id='finalise'>
  <form class='form-horizontal'>
    <div class='form-group' >
      <label class='control-label' />
      <div class='controls'>
        <input class="form-control" type="text" placeholder="Name on Card" required />
      </div>

      ...
    </div>
  </form>
</div>

Less:

#finalise {
    .form-group {
    .make-row();
}
.control-label {
    .make-xs-column(4);
    .make-sm-column(5);
    .make-lg-column(6);
}
.controls {
    .make-xs-column(8);
    .make-sm-column(5);
    .make-lg-column(6);
}
}
6
  • 2
    Even if you consolidate your selectors to keep your markup tidy, you'll still have all of those extra selectors junking up your CSS. Commented Mar 11, 2014 at 14:37
  • Agree with @cimmanon. You are cleaning up your HTML but will be bloating up your CSS quite considerably. I looked into this briefly a while ago but now I just live with the col selectors in the HTML class attribute. Commented Mar 11, 2014 at 18:10
  • @Lowkase I don't mean to imply that this shouldn't be done. Small HTML + big CSS is better than big HTML and small CSS due to caching. My personal recommendation is to stop using libraries that make all of these junk selectors, but I realize that's not an option for some folks. Commented Mar 11, 2014 at 18:15
  • @cimmanon, I agree small HTML and big css is better, because we can modify css later if needed without changing the html part. And we probably can minify css, or even use other tools to remove unused css automatically. By the way, is there any css optimizing tool do the job like unused-css.com ? Commented Mar 11, 2014 at 22:47
  • github.com/addyosmani/grunt-uncss may be the one I am looking for, I will give a try soon. If it works, my answer will be use less to extend all, minify css, and uncss. Commented Mar 11, 2014 at 23:03

1 Answer 1

4

You'll have to work out your own case, but Bootstrap's comes with LESS mixins intented to reduce the selector bloat caused by responsible grid columns

http://getbootstrap.com/css/#grid-less

You can make things like this (from the docs)

.wrapper {
  .make-row();
}
.content-main {
  .make-lg-column(8);
}
.content-secondary {
  .make-lg-column(3);
  .make-lg-column-offset(1);
}

...

<div class="wrapper">
  <div class="content-main">...</div>
  <div class="content-secondary">...</div>
</div>

Update: Bootstrap offers some more documentation on it's LESS mixins now:

http://getbootstrap.com/css/#less-mixins-vendor

http://getbootstrap.com/css/#less-mixins-utility

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks NiloVelez, thought it is not 100% what I expect, but at least 95%. It solve my problem. But actually I expected a generic way which can combine multiple classes(not just grid selectors) into be one custom class.
Althought only grid mixins are documented, Bootstrap comes with LOTS of mixins. github.com/twbs/bootstrap/blob/master/less/mixins.less
looks like by these we can define own classes which can adapter all bootstrap classes.

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.