Generate Styles Using Less Recursive Function and Media Queries

Generate styles using LESS recursive function and media queries

Arithmetic operations inside @media queries should always be in parens regardless of --strict-math option. I.e. should be @media (min-height: (@baseHeight * @screenHeight)).

Getting styles outside a media query with Less extend?

As you have correctly found out, it is currently not possible to extend the properties of a block that is outside the media query in a selector block that is within media query. I suspect the reason for this is that in simple terms all that the :extend does is to group selectors which cannot be done here. If the .col-2 is grouped within the media query, it creates a wrong behavior (and) a media query can't be added as a comma separated value in a selector group.

You can just call the required classes within the media query like in the below snippet.

Less Code:

@md: ~"only screen and (min-width: 48.9375em)";
.col-2 { width: 50%; }
.pull-left { float: left; }
.block1, .block2 {
@media @md {
.col-2;
.pull-left;
}
}

Output CSS:

.col-2 {
width: 50%;
}
.pull-left {
float: left;
}
@media only screen and (min-width: 48.9375em) {
.block1,
.block2 {
width: 50%;
float: left;
}
}

LESS function that builds a media query

The main problem of your first snippet is that you can't use mixin call to set an identifier for a {...} block. In the snippet the following:

.media(100px, 400px) {
color: red;
}

is actually a new mixin definition and not really a previously defined .media mixin call (so it simply outputs nothing since this new mixin is never invoked).
And proper mixin call syntax:

.media(100px, 400px); {
color: red;
}

in such context would be an equivalent to:

@query: ~"@media (min-width: 100px) and (max-width: 400px)"; {
color: red;
}

which of course does not make any sense for Less at all and it would throw a error.

-------

Your second snippet is more correct, but yes, since both mixin calls share the same scope there's only one @query variable. It's possible to isolate them by putting each into unnamed namespace (which is simply a ruleset with & name so it creates a new scope but then is output as part of the outer ruleset):

.class {
& {.media(100px, 400px);
@media @query {
color: red;
}}

& {.media(401px, 800px);
@media @query {
color: green;
}}
}

This does the trick but obviously it does not look like something really useful (too verbose and unreadable) so for the sake of reference it would make sense to mention other approaches:

-------

Today, the most clean solution for the particular case would be to use ruleset as mixin parameter:

.media(@min, @max, @styles) {
@media (min-width: @min)
and (max-width: @max) {
@styles();
}
}

.class {
.media(100px, 400px, {
color: red;
});

.media(401px, 800px, {
color: green;
});
}

Though I doubt that in a practical project you'd want to explicitly repeat pixel values every time you need the corresponding media so most likely eventually you end with more semantic mixins, e.g.:

.media(@min, @max, @styles) {
@media (min-width: @min)
and (max-width: @max) {
@styles();
}
}

.tiny-screen(@styles) {.media(100px, 400px, @styles)}
.not-so-tiny-screen(@styles) {.media(401px, 800px, @styles)}

.class {
.tiny-screen({
color: red;
});

.not-so-tiny-screen({
color: green;
});
}

------

Passing rulesets to mixins is not the only method to achieve the goal, there're other methods with various pros and cons (some of those can look even more readable if you go the "semantic media blocks" way). See for example https://stackoverflow.com/a/15842048/2712740 (obviously search for [less] media here at SO will point to more inspirations).

My LESS math operations aren't working in my media query definitions

Just like the CSS logic for the calc() method, equations within media queries (which are already encapsulated by a set of parentheses) need to be encapsulated by an extra set of parentheses. This won't work:

(min-width: 500px + 1) {CSS goes here}

But this will:

(min-width: (500px + 1px)) {CSS goes here}

LESS addition operator (+) is appending instead of adding

Look at strict math option which default value is OFF. Are you sure that for some reason you don't have it set to ON?

lessc -sm=on
lessc --strict-math=on

LESS addition operator (+) is appending instead of adding

Look at strict math option which default value is OFF. Are you sure that for some reason you don't have it set to ON?

lessc -sm=on
lessc --strict-math=on

Auto-generate LESS styles for sprite icons

Pure LESS (assuming you're using Web Essentials 2013 which uses LESS 1.5.x):

@icons: upvote, downvote, comment, new, notify, search, popup, eye, cross;

.iconize();
.iconize(@i: length(@icons)) when (@i > 0) {
.iconize((@i - 1));

@value: extract(@icons, @i); // LESS arrays are 1-based
.@{value} {background-position: (-20px * (@i - 1)) 0}
.color.@{value} {background-position: (-20px * (@i - 1)) -20px}
.white.@{value} {background-position: (-20px * (@i - 1)) -40px}
}

I removed & from selector names since it has no effect when you generate these classes in the global scope (but put it back if you actually need .iconize to be nested in another ruleset). It is also possible to calculate array length in earlier LESS versions (that have no length function) w/o any javascript, but I don't list this method here since it's quite scary (and you don't need it anyway).


Your javascript based loop is in fact less or more correct but the problem is all values returned by LESS inline javascript are of so-called "anonymous value" type and not a numbers so that when (@c < @count) condition is always true and the loop becomes infinite. (basically the condition is expanded exactly as when (0 < ~'9') ... when (9 < ~'9') = true etc.)



Related Topics



Leave a reply



Submit