Can I override global variables from the calling scope - less

I need to override some global variables used within a mixin. However I'm reluctant to just change the variables in global space (wouldn't be overriding then)
Consider this given mixin with the required variable defined.
// Mixin and adjust the regular image class
.thumbnail {
display: block;
padding: #thumbnail-padding;
margin-bottom: #line-height-computed;
line-height: #line-height-base;
background-color: #thumbnail-bg;
border: 1px solid #thumbnail-border;
border-radius: #thumbnail-border-radius;
.transition(all .2s ease-in-out);
> img,
a > img {
.img-responsive();
margin-left: auto;
margin-right: auto;
}
// Add a hover state for linked versions only
a&:hover,
a&:focus,
a&.active {
border-color: #link-color;
}
// Image captions
.caption {
padding: #thumbnail-caption-padding;
color: #thumbnail-caption-color;
}
}
Yep, from Bootstrap... Now I want that mixin to work with different variables, without changing the global scoped ones. Can this be done?
article.publications {
.news-thumb {
#thumbnail-padding: 10px;
#line-height-computed: 20px;
#line-height-base: 30px;
#thumbnail-bg : black;
.thumbnail();
}
}

Related

how to use deep selector in less imported externally to tsx/jsx

The deep selector in vue3 has been changed into :deep(xxx), but it doesn't work when I use it in .less imported externally to .tsx.
BTW, Although Vue3 is no longer use /deep/ or >>>, I still tried and didn't work too
.register_form {
&__base_info {
display: flex;
flex-direction: row;
justify-content: space-between;
background-color: palegoldenrod;
&__input_container {
padding: 1rem;
border: 1px solid green;
border-radius: 5px;
&__label {
font-weight: bolder;
}
:deep(input) {
border: none;
background-color: yellow;
}
}
}
}

passing from specific class to props function sccs and vuejs

I want to pass a class according to a props without having to duplicate the scss code
indeed if I duplicate the code by putting the class it works but I would only like to modify certain value by adding the appropriate class
components
``` :class="[
theme === 'darkModeTheme'
? 'darkModeTheme'
: theme === 'toggleLanguage'
? 'toggleLanguage'
: ''
]"
// props
theme: { type: String }
```
here is an example of the scss
```
&:checked {
background: color(menu);
background-repeat: no-repeat;
background-size: 80px 40px;
.darkModeTheme { //class to be taken into account if defined on the component to call
background: url("../../../assets/img/sky-stars.jpg");
}
&::before {
.toggleLanguage {
background-image: url("~#/assets/img/en.png");
}
// background-image: url("~#/assets/img/en.png");
left: 40px;
}
}
&:before {
content: "";
position: absolute;
width: 30px;
height: 30px;
border-radius: 50%;
left: 0;
background-size: 30px;
background-repeat: no-repeat;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.8);
#include easeOut;
cursor: pointer;
// background-image: url("~#/assets/img/fr.svg");
.darkModeTheme { //class to be taken into account if defined on the component to call
background-image: color(toggleTheme);
}
.toggleLanguage { //class to be taken into account if defined on the component to call
background-image: url("~#/assets/img/fr.svg");
}
}```
In your template, the dynamic class should be defined like
:class="{
'darkModeTheme': theme === 'darkModeTheme',
'toggleLanguage': theme === 'toggleLanguage'
}"

Use LESS to factor out a CSS rule (e.g. font-size: 20px; )

How would you define a CSS style (e.g. font-size: 20px), and reuse it in multiple places with LESS?
According to the LESS docs, I can use variables for keys (e.g. font-size), identifiers (e.g. .myClass), and values (e.g. 20px). However, I'm not seeing an ability to do general rules like this.
Example in SCSS:
Define a mixin
#mixin large-text {
font-size: 20px;
}
Use it elsewhere
.MyAwesomeTitle {
color: red;
#include large-text;
}
Result:
.MyAwesomeTitle {
color: red;
font-size: 20px;
}
Define the mixin. While the leading . makes it look like a class selector, it's just how naming mixins works in LESS.
.large-text() {
font-size: 20px;
}
You include a mixin by just writing the name of the mixin. In this case it's .large-text.
.MyAwesomeTitle {
color: red;
.large-text
}
The docs give an example under "parametric mixins"
Input:
.wrap() {
text-wrap: wrap;
white-space: -moz-pre-wrap;
white-space: pre-wrap;
word-wrap: break-word;
}
pre { .wrap }
Output:
pre {
text-wrap: wrap;
white-space: -moz-pre-wrap;
white-space: pre-wrap;
word-wrap: break-word;
}

Run LESS mixin only once

I am trying to make sure a mixin that may be called several times in different files, only outputs css once.
First try (less)
I first was thinking something like this:
mixin
#_mod: "false";
.mod(#_mod) when (#_mod = "false") {
#_mod: "true";
.mod {
border-radius: 6px;
border: 1px solid gray;
}
}
call 1
.mod(#_mod);
call 2
.mod(#_mod);
output
.mod {
border-radius: 6px;
border: 1px solid gray;
}
.mod {
border-radius: 6px;
border: 1px solid gray;
}
That doesn't work because the variables are namespaced and scoped to mixins.
Read more
CodePen
Second try (less)
I then though this:
mixin
#_mod: "false";
.mody() {
.mody {
border-radius: 6px;
border: 1px solid gray;
}
}
call 1
& when (#_mod = "false") {
.mody();
}
#_mod: "true";
call 2
& when (#_mod = "false") {
.mody();
}
#_mod: "true";
output
-nothing-
This doesn't work because of Less's lazy loading "feature" for all variables...
CodePen
Does anyone know a way to make sure a mixin, called multiple times, runs only once?
Solution: use default() and make the initial mixin to expose yet another empty mixin (which will suppress the default one).
// (using same name for a mixin and a ruleset is a bad idea)
._mod() when (default()) {
._mod() {}
.mod {
border-radius: 6px;
border: 1px solid gray;
}
}
._mod();
._mod();
._mod();
._mod();

LESS mixing duplicate properties

When using LESS, i found usefull to mix classes, in order to create a new class based on other class properties, but sometimes i need to override them.
like:
.btn {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn_warning {
.btn;
background-color: yellow;
font-size: 12px;
}
The output has duplicated properties:
.btn {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn_warning {
border-radius: 10px;
background-color: blue;
font-size:10px;
background-color: yellow;
font-size: 12px;
}
I know there are multiple aproaches for this, like multiple classes on dom, or even #extend to build multiple selectors, but navigator still overriding at runtime the properties.
Is there any reason to duplicate same properties when mixin? Seems a simple way for making "independent" groups of properties, but not nice if has duplicated values.
LESS does not account for removal of duplicate properties within a block, at least in part because of this reason stated here (quote slightly modified for grammar fix):
The trouble is that people frequently use multiple properties in order
to provide a fallback for older browsers. Removing the properties is
not something that it would be good to do generically.
It is left up to the programmer to not program it for duplication. You can set up a basic mixin like what Danny Kijkov noted in his answer, or...
Solution #1 (Complex, but Powerful to Fully Define)
You can get elaborate in building a master button maker mixin. Something like this:
LESS (Mixin)
.makeBtn(#ext: null; #rad: 10px; #color: blue; #size: 10px;) {
.set-extension() when (#ext = null) {
#class-extension: ~'';
}
.set-extension() when not (#ext = null) {
#class-extension: ~'_#{ext}';
}
.set-extension();
.btn#{class-extension} {
border-radius: #rad;
background-color: #color;
font-size: #size;
//define various addtions based on extensions here
.specialExtensionProps() when (#ext = danger) {
border: 3px solid red;
}
.specialExtensionProps() when (#ext = someExtName) {
my-special-prop: yep;
}
.specialExtensionProps();
}
}
LESS (Use the Mixin Various Ways)
.makeBtn(); //makes base button
.makeBtn(warning; #color: yellow; #size: 12px); //makes modified button
.makeBtn(danger; #color: red;); //makes modified button
.makeBtn(someExtName, 15px); //makes modified button
CSS Output
.btn {
border-radius: 10px;
background-color: #0000ff;
font-size: 10px;
}
.btn_warning {
border-radius: 10px;
background-color: #ffff00;
font-size: 12px;
}
.btn_danger {
border-radius: 10px;
background-color: #ff0000;
font-size: 10px;
border: 3px solid red;
}
.btn_someExtName {
border-radius: 15px;
background-color: #0000ff;
font-size: 10px;
my-special-prop: yep;
}
In case you did not know, note the above demonstrated LESS functionality of setting only some variables from the set of mixin variables. So for the first two specialized .makeBtn() calls, I only set a few variables, out of order from the mixin, by explicitly calling the variable name to set (e.g. #color: yellow). This allows me to "skip" over setting the #size. In the last example, I was only setting the first two values, so I did not need to put any variable names.
I don't know if the above helps you get what you want, but it does offer a different way of being able to reduce code size.
Solution #2
You mentioned :extend(), which could be well used here to avoid duplication:
LESS
.btn {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn_warning {
&:extend(.btn);
background-color: yellow;
font-size: 12px;
}
CSS Output
.btn,
.btn_warning {
border-radius: 10px;
background-color: blue;
font-size: 10px;
}
.btn_warning {
background-color: yellow;
font-size: 12px;
}
Solution #3
In your case, if all the buttons will be of either class .btn or a .btn_SOMETHING form, and you are not using .btn_ for anything else but buttons, then you might be able to just use the CSS cascade to apply styles and prevent duplication of CSS code like so (no special LESS required):
LESS and CSS Output
.btn, [class *= btn_] {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn_warning {
background-color: yellow;
font-size: 12px;
}
Any html with the class btn_warning will first get the base button styles from the attribute selector [class *= btn_] while the actual btn_warning class will override the things set to be overridden.
Solution #4
If you split the class names in the html (so class="btn warning" rather than class="btn_warning"), then this works to avoid duplication:
LESS and CSS Output
.btn {
border-radius: 10px;
background-color: blue;
font-size:10px;
}
.btn.warning {
background-color: yellow;
font-size: 12px;
}
What about this solution?
.btn(#size: 10px, #color:blue) {
border-radius: 10px;
background-color: #color;
font-size:#size;
}
.btn_warning {
.btn(12px, yellow);
}