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;}
*/
Related
I have following stylesheet for table.
QHeaderView::section, *[role="mockheader"]
{
min-width:80px;
background-color:#3949ab;
color:#FFFFFF;
border:0px;
outline:none;
height:40px;
}
QHeaderView::section:checked, QHeaderView::section:hover
{
background-color: #3949ab;
color:white;
}
QTableView
{
show-decoration-selected: 1;
border:0px;
background-color: rgba(0, 0, 0, 0);
gridline-color:#454545;
color: #FFFFF8;
}
QTableView::item
{
border: 0px;
min-height:35px;
padding:5px;
color:#FFFFFF;
}
QTableView::item:hover
{
background-color: rgba(255,255,255, 50);
}
QTableView::item:selected
{
background-color: #3949ab;
}
Ideally it should paint header in blue color. it is seems unaffected. see attached snap.
*Left blue space is label, which i added for filling left space. Its not a part of table. Just leave it.
I am not able to figure out any problem in my stylehseet. Please let me know what I am doing wrong here.
How to create a print stylesheet which can override the dynamic styles created by css modules ?
Using CSS modules, classnames render with unique names like so :
<button class="buttons_style_primary-button__3T" type="submit"> Submit</button>
In my print stylesheet I have the following, which has no effect :
#media print {
button {
display: none;
}
}
I can get it to work by adding !important to the button style, but I will have many print styles and I don't want to do this for each style attribute. Is there an alternative ?
I'm also using React if there happens to be a React specific approach here.
Wound up doing the following :
Use !important for globals that need to override local values:
/* app.css */
#media print {
#page {
margin: 1cm;
}
* {
color: #000 !important;
}
}
Put component specific overrides into a style.css for each component:
/* style.css */
.my-class {
composes: rounded-corners from 'shared/ui.css';
margin: 0 0 60px 0;
background-color: white;
}
#media print {
.my-class {
page-break-inside: avoid;
font-size: 10px;
}
}
/* my-component.jsx */
import style from './style.css';
const MyComponent = () => {
return (
<div className={style.myClass}>
....
</Link>
);
};
There's also a third option which I haven't really tried.
You should be able to apply both the top-level override classname with your local classname using the classNames library:
import app from 'app.css';
import styles from './style.ss'
const MyComponent = () => {
return (
<div className={classNames(style.local, app.global)}>
....
</Link>
);
};
( this third option is just off the top of my head, I don't know if it will work )
Instead of this:
#media print {
.button {
display: none;
}
}
Try this:
.button{
#media print {
display: none;
}
}
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)
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.
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;
}