less.css if variable is true guard - if-statement

I wonder if there is a better solution (or if my solution is even right), to create if statement like behavior with variables and guards.
Goal:
If variable is set to true, compile the code (works)
If variable is set to anything else, ignore the code (default, works)
Keep initial code position (dosnt work, is merged wherever .responsive (#responsive); is called)
My Code:
#responsive: true;
.responsive(true){
a {
color: red;
}
}
.responsive(true) {
b {
color: blue;
}
}
.responsive (#responsive);

I am not completely sure I understand what you say doesn't work.
But if I do ... there are two things connected to this that you have to bare in mind in LESS:
scope matters - not order (you can define a variable/mixin after you call it, as long as you deine it in the same scope or a scope that is accessible)
the mixin gets rendered where you call it not where you define it
that said - if you really want to use the same guard in multiple places to do different things, you would need to define multiple mixins (each place would get another mixin), and if you want to render it in the place you define it, you would just need to call it immediately after (or before) you define it. Something like this:
#responsive: true;
test1 {
color:green;
}
.a() when (#responsive){
a {
color: red;
}
}
.a;
test2 {
color:green;
}
.b() when (#responsive) {
b {
color: blue;
}
}
.b;
the output will be:
test1 {
color: green;
}
a {
color: red;
}
test2 {
color: green;
}
b {
color: blue;
}
So the mixins .a() and .b() are returned if #responsive is set to true, if not you get:
test1 {
color: green;
}
test2 {
color: green;
}
I hope this is kinda what you wanted.

I ended up using this:
#responsive: true;
section.content {
.responsive () when (#responsive) {
#media (min-width: 768px) {
float: right;
width: 80%;
}
#media (min-width: 980px) {
width: 60%;
}
}
.responsive;
}
aside.left {
.responsive () when (#responsive) {
#media (min-width: 768px) {
float: left;
width: 20%;
}
}
.responsive;
}

Related

Can I use LESS mixins with `when` statement plus pseudo element

Can I use LESS mixins with when statement plus pseudo element?
I want to create a Mixins. The logical is if the primary color is white, then I need to give .userBadge:after secondary-color.
Here is my LESS mixins, but it seems like does not work.
.property-style(#primary-bgcolor, #primary-color, #secondary-bgcolor, #secondary-color) {
.wrapper {
background-color: #primary-bgcolor;
}
.userBadge:after(#primary-color, #secondary-color) when (#primary-color = "#fff") {
background: #secondary-color;
}
}
Can you please help? Thank you so much.
You have a few errors:
You're missing the # in front of secondary-color
Mixins are class-like .x, not arbitrary selectors. x::after(...) is invalid - you'd need x(...) {&::after {...} }
Your .property-style mixin defines a mixin, but you never called that mixin
Your .userBadge mixin defines a mixin, but you never called that mixin
In this case "#fff" needs to be #fff without quotes - otherwise your color would have to be "#fff" instead of #fff! :D
Here's a working version of what you have (I'm leaving out #secondary-bgcolor since you didn't use it for anything) [working demo]
.property-style(#primary-bgcolor, #primary-color, #secondary-color) {
// `.wrapper` styles
.wrapper {
background-color: #primary-bgcolor;
}
// define the other mixin. note that we _could_ use the same variable names
// but they are _new_ variables - I've given them new names to
// help us remember that they won't automatically inherit the values of the parent mixin
.myOtherMixin(#primary, #secondary) when (#primary = #fff) {
background: #secondary
}
.userBadge::after {
.myOtherMixin(#primary-color, #secondary-color)
}
}
.property-style(#ccc,#fff,#eee); // result:
// .wrapper {background: #ccc;}
// .userBadge::after {background-color: #eee;}
However, nesting mixins can get pretty messy. This would be a little cleaner [working demo]
.variableColor(#color, #otherColor) when (#color = #fff) {
background: #otherColor
}
.property-style(#primary-bgcolor, #primary-color, #secondary-color) {
.wrapper {
background-color: #primary-bgcolor
}
.userBadge::after {
.variableColor(#primary-color, #secondary-color)
}
}
.property-style(#ccc,#fff,#eee); // result:
// .wrapper {background: #ccc;}
// .userBadge::after {background-color: #eee;}
Or if that variable color mixin doesn't actually need to be reusable [working demo]
.property-style(#primary-bgcolor, #primary-color, #secondary-color) {
.wrapper {
background-color: #primary-bgcolor;
}
}
.property-style(#primary-bgcolor, #primary-color, #secondary-color) when (#primary-color = #fff) {
.userBadge::after {
background: #secondary-color
}
}
.property-style(#ccc,#fff,#eee); // result:
// .wrapper {background: #ccc;}
// .userBadge::after {background-color: #eee;}
But wait let's back up. The fact that you didn't call your mixin, at least in the code you've provided, makes me wonder if the whole thing really needs to be in one. If you don't really need to be able to do something like
.property-style(#ccc, #ddd, #eee);
alternate {.property-style(#aaa, #fff, #bbb)}
this much simpler solution (which relies on default values) would do the trick [working demo]
#primary-bgcolor: #ccc;
#primary-color: #fff;
#secondary-color: #eee;
.badgeBg(#check: #primary-color, #ifPasses: #secondary-color) when (#primary-color = #fff) {
background: #secondary-color
}
.wrapper {
background-color: #primary-bgcolor
}
.userBadge::after {
.badgeBg
}
/*
result:
.wrapper {background: #ccc;}
.userBadge::after {background-color: #eee;}
*/
Bonus: just for kicks, here's a different approach you could take. It's definitely overkill for what you've shown here, but you might find it an interesting thing to study. It uses default values and property interpolation, and it makes the color in the "if" a dynamic part of the theme. [working demo]
.propertyValueCondition(#property, #value, #check: pass, #guard: pass) when (#check = #guard) {
#{property}: #value
}
.theme(#color1, #color2, #color3, #color4:#fff) {
.wrapper {
.propertyValueCondition(background-color, #color1)
}
.userBadge::after {
.propertyValueCondition(background, #color3, #color2, #color4)
}
}
.theme(#ccc, #ddd, #eee);
alternate {
.theme(#bbb, #aaa, #eee, #aaa)
}
/*
result:
.wrapper {background-color: #ccc;}
alternate .wrapper {background-color: #bbb;}
alternate .userBadge::after {background: #eee;}
*/

SCSS / Sass - Statement referencing to parent not work

.a, .b
{
color: red;
$x: &;
#if $x == '.b'
{
color: $x;
}
}
http://sassmeister.com/gist/ad7fa7f3a431f3e2d4e0
Not work, why? Could you help me someone with some fix?
Because $x is equal to the full selector (.a, .b), never to .a or .b.
What you're trying to achieve would be:
.a, .b {
color: red;
&.b {
color: blue;
}
}
But it will generate this code (working, but not optimized):
.a, .b {
color: red;
}
.a.b, .b.b {
color: blue;
}

Conditional hover state in LESS

I would like to add a conditional hover state to my LESS mixin.
I've tried the following but it returns an error:
.foo(#hoverstate:false){
color:red;
&:hover when (#hoverstate = true){
color:blue;
}
}
What is the correct syntax for this?
dotless does not support "CSS guard" construction so you'll need a mixin to put the guard there, e.g.:
.foo(#hoverstate: false) {
color: red;
.-(); .-() when (#hoverstate = true) {
&:hover {
color: blue;
}
}
}
that can be simplified to:
.foo(...) {
color: red;
}
.foo(true) {
&:hover {
color: blue;
}
}
(Note I did not test this code with dotless so it's possible you would need to correct other minor incompatibilities)

Changing color of specific chartjs point

Is it possible to change specific point color with dx chartjs?
I know how to change point colors for the whole series, but I can't find anything on changing specific points.
You can use
customizePoint
callback.
$("#container").dxChart({
dataSource: dataSource,
...
customizePoint: function() {
if(this.value > highAverage) {
return { color: '#ff4500', hoverStyle: { color: '#ff4500' } };
} else if(this.value < lowAverage) {
return { color: '#00ced1', hoverStyle: { color: '#00ced1' } };
}
},
....
}
});
You can find find documentation and demo

CSS Transitions when display:none is set

How do you transition using CSS the properties of elements with display none?
My current solution is to set display to block with JavaScript, wait 10 milliseconds for repaint, then apply the class that changes the properties I want to animate.
Note: I'm using jQuery for code brevity.
CSS - animating opacity as an example. Don't care about $.show().
.element
{
display:none;
opacity:0;
-webkit-transition:all 0.5s;
-moz-transition:all 0.5s;
-ms-transition:all 0.5s;
-o-transition:all 0.5s;
transition:all 0.5s;
}
.element.shown
{
opacity:1;
}
JavaScript
function show()
{
var $element=$('.element');
$element.css({display:'block'});
//Add class a few moments later than chaning display to block, otherwise animations CSS Transitions won't fire
setTimeout(function(){
$element.addClass('shown');
},10);
}
function hide()
{
var $element=$('.element');
$element.removeClass('shown');
//Remove element from display after transition ends
$element.on('webkitTransitionEnd otransitionend oTransitionEnd MSTransitionEnd transitionend',function()
{
$element.css({display:'none'});
});
}
I feel there should be a better way though, a CSS-only way. Is there?
I just found workaround. All you need is use animation and start it little bit after you apply display:block. Like this:
#keyframes submenu_animation {
from {
opacity: 0;
}
1% {
opacity: 0;
}
99% {
opacity: 1;
}
to {
opacity: 1;
}
}
li ul {
opacity: 0;
display: none;
animation-name: submenu_animation;
animation-duration: 300ms;
animation-direction: reverse;
li ul.open {
display: block;
}
li:hover ul {
animation-direction: normal;
opacity: 1;
}
Javascript is pretty the same, It will apply class "open" once you hover on required element. When you hover-out it will remove "open" class little bit later, when animation is finished.