LESS variable concatenation and interpolation - twitter-bootstrap-3

I'm attempting to override Bootstrap's hover effect on the buttons. I'd like to save some space and do it the slick way by simply passing into a mixin the name of a class and have that class' background variable be automatically deduced from just that. So my mixin is:
.btn-hover(#name){
.#{name}:hover{
background: lighten( #~"#{name}-bg", 10% );
}
}
.btn-hover(btn-primary);
But I can't seem to access the variable #btn-primary-bg by concatenating -bg to btn-primary, because #~"#{btn-name}-bg" results in a compiler error. Is what I'm trying to do even possible? It would be pretty slick if it were.
Edit -----------------------------------------------------------------
Just stumbled upon this question and it's definitely related, but I think my question really just boils down to:
In LESS, can you access a variable via interpolation after string concatenation?
#btn-success-bg: #00ff00;
#name: btn-success;
#background: #~"#{name}-bg"; // How do I access #btn-success-bg?

You can do:
#btn-primary-bg: red;
.btn-hover(#name){
.#{name}:hover{
#buttonname: ~"#{name}-bg";
background: lighten( ##buttonname, 10% );
}
}
.btn-hover(btn-primary);
Also see: http://lesscss.org/features/#variables-feature-variable-names

Related

LESS: create variables in a way similar to 'nested rules'

Actually I have several LESS variables defined in the following way:
#toolbar-first-level-item-color-background: #transparent-black-80;
#toolbar-first-level-item-color-background_hover: #black;
#toolbar-second-level-item-color-background: lighten(#toolbar-entry-color-background,30%);
#toolbar-second-level-item-color-background_hover: lighten(#toolbar-entry-color-background_hover,30%);
#toolbar-third-level-item-color-background: lighten(#toolbar-entry-color-background,40%);
#toolbar-third-level-item-color-background_hover: lighten(#toolbar-entry-color-background_hover,40%);
#toolbar-fourth-level-item-color-background: lighten(#toolbar-entry-color-background,45%);
#toolbar-fourth-level-item-color-background_hover: lighten(#toolbar-entry-color-background_hover,45%);
As you can see, there are several repetitions in it, so I wonder if could be possible to use something like namespaces or maps to create a more compact and less repetitive declaration.
The idea is starting by structure of nested rules, that create a very clear hierarchy with few repetitions.
I think, you can use a map. It is a new feature in Less lang that allows you to get values using keys.
You can write something like that:
#toolbar: {
#first-level-item: {
color-background: #fff;
};
}
text {
color: #toolbar[#first-level-item][color-background];
}

How to check if a riot tag exists?

How can I check if a riot tag has already been loaded and compiled (in-browser with script tag), in order to avoid doing it again, programmatically.
In other words, what should I use instead of doesTagExist function in my simplified code, below?
if (!doesTagExist('my-tag')) {
riot.compile('/path/to/my-tag', function() {
riot.mount('dom-node', 'my-tag');
});
} else {
riot.mount('dom-node', 'my-tag');
}
had same problem. After bit of research I think you can't get it directly. Implementation is stored inside __TAG_IMPL which is not accessible from outside. You can however access selector for all implemented tags via riot.util.tags.selectTags(), which returns comma separated list of selectors i.e. datepicker,[data-is="datepicker"].
Oneliner for convenience
riot.util.tags.selectTags().search(/(^|,)my-tag($|,)/g) >= 0
or depending on your purity inclination
riot.util.tags.selectTags().search('"my-tag"')
Note, that first version is future-proof, if riot decides to start using single commas in selector.

find and replace - with awk or sed

I'm writing a desktop application with Electron and ReactJS that edits CSS files.
I need to scan the CSS looking for a class selector, and then clear the following declaration block and add some new properties.
The tricky part is matching the class in the selector. I need the class to be the actual target (not a parent), but there might be multiple comma-separated selectors, and so I need to check all of them.
For example,
in this file I'm searching for the containerApp class:
.section-main .section-right , .menu .container-manu , .containerApp .container-nav {
background: black;
}
.section-main2 .section-left , .menu .container-manu , .section-group-d .containerApp {
background: red;
}
The first block doesn't match because .containerApp is only mentioned as the parent of the real target, .container-nav. The second block does match, and I would want to remove the background: red; and replace it with something else.
What's the best way to go about doing this CSS matching and rewriting?
If I understand your requirements correctly, .containerApp needs to be the last element of a selector. Since the selector ends with a comma, or at the curly braces, you need to use a suitable regular expression:
sed '/\.containerApp *[,{]/s/{[^}]*}/{ my new css rules }/' app.css

Custom CSS attributes while using LESS?

I have been using SASS for a while now, and one thing I really like is how I can use it for my FlashBuilder projects also, namely that is supports custom CSS attributes, like 'embedAsCFF' and 'unicodeRange'.
I'm trying out LESS for the first time, and it will not let me compile to CSS while using these two custom attributes:
embedAsCFF: true;
unicodeRange: U+0021, U+0023-U+0026, U+0028-U+002a, U+002c, U+002e-U+0039, U+0040-U+005d, U+0061-U+007d;
I receive a 'Less Compilation Error: Syntax Error...'
Any LESS users know how I need to add in support for these custom attributes? Thanks in advance.
Update: This issue will be resolved in the release of LESS 1.4.2
Not a Custom Name but a Format Issue
It appears on my experimenting that the issue is really the fact that you are using capital letters in the property names (not that they are custom attributes themselves). Capital letters are apparently not supported by LESS. In other words, these work:
embedascff: true;
embed-as-cff: true;
unicoderange: U+0021; //etc.
unicode-range: U+0021; //etc.
But this does not:
Color: red;
I have not for certain isolated where in the actual LESS code itself this might be fixed (if it can be fixed for the way LESS handles the property rules). I suspect the cause is in the parser.js file lines 1578-1584 (as of this writing), which are:
property: function () {
var name;
if (name = $(/^(\*?-?[_a-z0-9-]+)\s*:/)) {
return name[1];
}
}
This seems to be filtering out allowing for capital letters. I don't know what the consequences would be if that regular expression was changed to allow for them.

less.css - set css parameter dynamically

I learning how to use less.css for creating dynamic css files.
I'd like to create a dynamic property in my css file and load it, for example:
#marginProperty : margin-left;
.top
{
#marginProperty: 10px;
}
Is this possible? Doesn't seem to compile for me. Any ideas?
It doesn't work quite that way; you can't set a property from a variable, variables are only values of those properties. Instead of setting a variable for the property, you should use a mixin. It's tricky, not knowing exactly how you are structuring your LESS/CSS or what your goals are, but it seems like you need to think in reverse. CSS, like SQL, is declarative, so you have to describe the result from the code, instead of describing the process of getting to that result. Something like this might do it:
.margin(#size:10px) {
margin-left: #size;
}
.top {
.margin(10px);
}
That .margin mixin can be defined in one mixin file and you can #import it, and when you need to redefine it, substitute that mixin file for another similar one.