How to make loop in QSS? - qt5

I use file *.qss to apply style sheet on my program. I want apply color on several QLabel, which have text "%number% channel".
I can write this:
Mnemonics--Base QLabel[text="1 channel"] {
color: white;
};
Mnemonics--Base QLabel[text="2 channel"] {
color: white;
};
Mnemonics--Base QLabel[text="3 channel"] {
color: white;
};
Mnemonics--Base QLabel[text="4 channel"] {
color: white;
};
But I'm wondering if I can write something like this?
#for $i from 1 through 4 {
num: #{$i};
ch: num+ " channel";
Mnemonics--Base QLabel[text=$ch] {
color: white;
};
}
But this code doesn't work.
Can it work? And if so, how to write it correctly for qss?

Related

Generate rules via LESS plugin

I'd like to write a plugin that can generate a LESS function named alt that can do the following transformation:
.button {
background-color: alt(red, blue);
color: alt(black, white);
}
And output the following:
.button {
background-color: red;
color: black;
body.alt & {
background-color: blue;
color: white;
}
}
There doesn't seem to be much documentation about writing LESS plugins on the site, so hoping someone can provide an example of how this might be written :) Thanks!
I think a mixin would be best for this. Something like the following LESS:
.alt(#property, #primary-color, #alternate-color) {
#{property}: #primary-color;
body.alt & {
#{property}: #alternate-color;
}
}
.button {
.alt(background-color, red, blue);
.alt(color, black, white);
}
Which will compile to the following CSS:
.button {
background-color: red;
color: black;
}
body.alt .button {
background-color: blue;
}
body.alt .button {
color: white;
}

Output nested selectors as individual lines with LESS

I'm just curious, if I have code written like this:
.newsletter-form input {
&::-webkit-input-placeholder,
&::-moz-placeholder,
&:-ms-input-placeholder {
color: red !important;
}
}
It will output as:
.newsletter-form input::-webkit-input-placeholder,
.newsletter-form input::-moz-placeholder,
.newsletter-form input:-ms-input-placeholder {
color: red !important;
}
But, I actually want it to be output as individual lines like this:
.newsletter-form input::-webkit-input-placeholder {
color: red !important;
}
.newsletter-form input::-moz-placeholder {
color: red !important;
}
.newsletter-form input:-ms-input-placeholder {
color: red !important;
}
How am I able to do this with LESS?
I understand I could just write it as separate lines using regular CSS, but that would be no fun.
See Passing Rulesets to Mixins. E.g.:
.newsletter-form input {
.placeholder({
color: red !important;
});
}
.placeholder(#rules) {
&::-webkit-input-placeholder {#rules();}
&::-moz-placeholder {#rules();}
&:-ms-input-placeholder {#rules();}
}
Unlike the solutions of the prev. answers, this way won't require your placeholder mixin to be hardcoded to a particular value or property like color: ... or so.
I found that if I just structured it like this, without the commas, I get the desired outcome.
.newsletter-form input {
&::-webkit-input-placeholder {
color: red !important;
}
&::-moz-placeholder {
color: red !important;
}
&:-ms-input-placeholder {
color: red !important;
}
}
Or using a mixin for flexibility.
.placeholder(#color) {
&::-webkit-input-placeholder {color: #color !important;}
&::-moz-placeholder {color: #color !important;}
&:-ms-input-placeholder {color: #color !important;}
}
.newsletter-form input {
.placeholder(red)
}
You can create mixin that will set a color to specific selector.
Less:
.set-color(#selector, #color) {
&#{selector} {
color: #color !important;
}
}
.newsletter-form input {
.set-color(~"::-webkit-input-placeholder", red);
.set-color(~"::-moz-placeholder", red);
.set-color(~":-ms-input-placeholder", red);
}
Css output:
.newsletter-form input::-webkit-input-placeholder {
color: red !important;
}
.newsletter-form input::-moz-placeholder {
color: red !important;
}
.newsletter-form input:-ms-input-placeholder {
color: red !important;
}

Alter CSS applied by LESS Mixin when body class is present?

I have a LESS mixin. When I apply this to an element I want it be styled slightly differently if a body class is present.
This:
.mixin() {
font-weight: bold;
color: red;
}
.element {
.mixin()
}
Outputs to this:
.element {
font-weight: bold;
color: red;
}
But I also want this to be outputted:
.body-class .element {
color: blue;
}
You can define your mixin this way:
.mixin() {
font-weight: bold;
color: red;
.body-class & {
color: blue;
}
}

Inherit from a Class Which Name Is Composed Using the `&` character in Less

How can I inherit from a class which name is composed using the & character (e.g. &-rule), please?
Desired Output
.prefix-rule-extended,
.prefix-rule {
color: white;
}
.prefix-rule-extended {
background-color: black;
}
or
.prefix-rule {
color: white;
}
.prefix-rule-extended {
color: white;
background-color: black;
}
Non-working Approaches
.prefix {
&-rule {
color: white;
}
}
plus
.prefix-rule-extended:extend(.prefix-rule) {
background-color: black;
}
or
.prefix-rule-extended {
.prefix-rule();
background-color: black;
}
Ideal Approach
.prefix {
&-rule {
color: white;
}
&-rule-extended:extend(&-rule) {
background-color: black;
}
}
Note 1: I know :extend(&-rule) is currently not supported.
Note 2: .prefix-rule is not so simple, i.a. there are nested rules inside so the following will not work:
.prefix {
&-rule {
color: white;
&-extended {
background-color: black;
}
}
}
Thank you.
(Ok, so as always to not leave this one w/o an answer - a summary of comments above):
Currently it's impossible to extend that kind of things. For the moment extend can't match selector identifiers generated via "concatenation" so .prefix {&.rule { ... would be a valid extend target (as it's "two elements" -> "two identifiers") but .prefix {&-rule { ... won't (since it's "two elements" -> "one identifier").
So if you plan to use extend don't be keen on such kind of nesting, keep it more simple.
Here are three valid Less snippets (each having its pros and cons) to get the desired CSS output.
1:
.prefix-rule {
color: white;
&-extended:extend(.prefix-rule) {
background-color: black;
}
}
2:
.prefix-rule {
&, &-extended {
color: white;
}
&-extended {
background-color: black;
}
}
3:
.rule-base {
color: white;
}
.prefix-rule {
&:extend(.rule-base);
&-extended:extend(.rule-base) {
background-color: black;
}
}

Lighten color from parent in Less

I am starting out with Less and one of the reasons I wanted to is because of the ligthen() function. So my first attempt was to do something with that.
This is my HTML
<div class="box blue">
<div class="boxbar">Foo</div>
blue
</div>
I finally got it working, but I doubt it's supposed be like this:
#blue: #468ACE;
#green: #41A53D;
#red: #9C2525;
#purple: #8938BF;
div
{
padding: 10px;
}
.blue {
background-color: #blue;
.boxbar { background-color: lighten(#blue, 10%); }
}
.green {
background-color: #green;
.boxbar { background-color: lighten(#green, 10%); }
}
.red {
background-color: #red;
.boxbar { background-color: lighten(#red, 10%); }
}
.purple {
background-color: #purple;
.boxbar { background-color: lighten(#purple, 10%); }
}
.boxbar
{
height: 10px;
}
How can I refactor this? Surely it must be easier to say "get your parent color, and lighten it a bit". I tried a couple of things: inherit (was worth a shot!), have the lightened versions inside .boxcar. But this obviously compiled to .boxcar .blue.. which is not what I want and I ended with what you can see here.. it works.. but it doesn't feel right. Then I would need to write code for every new color I introduce..
I am not completely sure what your desired solution would be ... but maybe something like making a mixin would help you from having to write so much stuff out.
LESS:
.bgmixin(#color) {
(~".#{color}") {
background-color: ##color;
.boxbar {
background-color: lighten(##color, 10%);
}
}
}
#blue: #468ACE;
#green: #41A53D;
#red: #9C2525;
.bgmixin("blue");
.bgmixin("green");
.bgmixin("red");
CSS:
.blue{
background-color: #468ace;
}
.blue .boxbar {
background-color: #6ea3d9;
}
.green{
background-color: #41a53d;
}
.green .boxbar {
background-color: #59c055;
}
.red{
background-color: #9c2525;
}
.red .boxbar{
background-color: #c52f2f;
}
Update:
In LESS>=1.4 you would want to use something like this to interpolate the class name from the color name:
.bgmixin(#color) {
#classname: ~"#{color}";
.#{classname} {
background-color: ##color;
.boxbar {
background-color: lighten(##color, 10%);
}
}
}