less / less.js

Less. The dynamic stylesheet language.
http://lesscss.org
Apache License 2.0
17.02k stars 3.41k forks source link

"If" statement or more operations needed #201

Closed matthew-dean closed 13 years ago

matthew-dean commented 13 years ago

I'd like to set up a less template that could have variables substituted in order to create resulting style sheets. The immediate questions in my mind are 1) how to easily turn on/off certain sections based on single variable values, and 2) how to "flip" color values based on lightness / darkness. In other words, if I change my background color variable to a dark color, I want the text color to be lighter, and obviously, if I change my background color to a dark color, the reverse should happen.

As far as I can tell, this can't happen with the current set of operations. Is there any chance that LESS might get some more sophisticated expressions? If statements would solve that, along with some other types of expressions / functions.

Thanks.

matthew-dean commented 13 years ago

In other words, something like:

@lightness: lightness(@color) > 50% ? 10% : 90%;

...or some other similar syntax if the colon is an issue.

alexandertrefz commented 13 years ago

Why was this issue closed, i often run in situation where at least if-statements would be extremely useful.

kevsmt commented 12 years ago

+1

example:

.rounded(@radius: 5px, @topleft: true, @topright: true, @bottomleft: true, @bottomright: true)
{
  -moz-border-radius: @radius;
  -webkit-border-radius: @radius;
  border-radius: @radius;

  @if(@topleft == false){
    -moz-border-radius-topleft: 0px;
    -webkit-border-top-left-radius: 0px;
    border-radius-topleft: 0px;
  }

  @if(@topright == false){
    -moz-border-radius-topright: 0px;
    -webkit-border-top-right-radius: 0px;
    border-radius-topright: 0px;
  }

  @if(@topright == false){
    -moz-border-radius-bottomright: 0px;
    -webkit-border-bottom-right-radius: 0px;
    border-radius-bottomright: 0px;
  }

  @if(@topright == false){
    -moz-border-radius-bottomleft: 0px;
    -webkit-border-bottom-left-radius: 0px;
    border-radius-bottomleft: 0px;
  }
}
matthew-dean commented 12 years ago

Yeah, don't know why it was closed either without comment.

"If" statements seem like such a basic necessity.

Another "nice to have" would be more integrated media query support, but that's a separate issue.

matthew-dean commented 12 years ago

Even Dreamweaver templates have If/Else If support, and it's a very simple (simpler than LESS) linear parsing syntax. The most basic of program parsers almost always start with "IF". Conditional statements are more valuable than darken, lighten, hue, etc, because those still have programmatic workarounds.

+1,000 to get this implemented?

matthew-dean commented 12 years ago

Here's how Sass does it:

@mixin link-colors($normal, $hover: false, $active: false, $visited: false, $focus: false) {
  color: $normal;
  @if $visited {
    &:visited {
      color: $visited; } }
  @if $focus {
    &:focus {
      color: $focus; } }
  @if $hover {
    &:hover {
      color: $hover; } }
  @if $active {
    &:active {
      color: $active; } } }
matthew-dean commented 12 years ago

Ah, just heard from Alexis on Twitter that this wasn't going to happen because he'd like to keep LESS a declarative language. Rats.

ESchuderer commented 11 years ago

Pity! As this is a while ago now and there are still many many practical uses for if statements, maybe it could be reconsidered?

Using a modular system, there is a lot of extra markup if you need if statements:

@responsive: true;

table {
  font-size: 1em;
    .tableResponsive() when (@responsive) {
    @media (max-width: 400px) {
      font-size: 0.9em;
    }
  }
  .tableResponsive;
}

button {
  padding: 2px 4px;
  .buttonResponsive() when (@responsive) {
    @media (max-width: 400px) {
      padding: 0;
    }
  }
  .buttonResponsive;
}

I know that I could use a single mixin, which is called once, but then the code would be merged to one and the same position.

matthew-dean commented 11 years ago

A lot has changed in the two years. After working more closely with LESS syntax, I understand and appreciate this approach a lot more. There's a lot that's evolving now with the extend syntax, for selectors and mixins, and perhaps eventually media queries.

Your code example is interesting. Why is it you think the code would be merged to the same position if it was a single mixin? The default behavior of mixins is that it's added to where they're called.

ESchuderer commented 11 years ago

I've looked at my code again, the problem occured while testing "non-practical":

@responsive: true;

.responsive() when (@responsive) {
    @media (max-width: 400px) {
    font-size: 0.9em;
    }
}
.responsive;

.responsive() when (@responsive) {
    @media (max-width: 400px) {
        padding: 0;
    }
}

.responsive;

This just merges all .responsives causing doubled code, but after all it's just logical to use:

@responsive: true;

table {
  font-size: 1em;
    .responsive() when (@responsive) {
    @media (max-width: 400px) {
      font-size: 0.9em;
    }
  }
  .responsive;
}

button {
  padding: 2px 4px;
  .responsive() when (@responsive) {
    @media (max-width: 400px) {
      padding: 0;
    }
  }
  .responsive;
}

Which works fine.