One day, a big man in the headline asked me, I heard that you had made theme switching in the project before, how did you achieve it at that time? Can you elaborate on it?
If you already know less like the palm of your hand, Start right here..
From less
Use
Less is used in Node.js environment:
npm install -g less > lessc styles.less styles.css
Use Less in the browser environment:
<link rel="stylesheet/less" type="text/css" href="styles.less" /> <script src="//cdnjs.cloudflare.com/ajax/libs/less.js/3.8.1/less.min.js" ></script>
However, it is recommended that less be compiled into css through tools such as webpack or gulp, and then introduced into use.
variable
@nice-blue: #5B83AD; @light-blue: @nice-blue + #111; #header { color: @light-blue; }
blend
-
Commonly used
.bordered { border-top: dotted 1px black; &:hover { border: 1px solid red; } // It can also include selector mixing } .post a { color: red; .bordered !important; // You can add important after all the attributes! ___________ }
-
Do not export to css file after compilation
.my-other-mixin() { background: white; }
-
Scope mixing
#outer { .inner() { color: red; } } #outer1 { .inner() { color: blue; } } .c { #outer > .inner; }
output
.c { color: red; }
-
Scope mixing with preconditions,more details
@mode: little; #outer when (@mode=huge) { .inner { color: red; } } #outer when (@mode=little) { .inner { color: blue; } } .c { #outer > .inner; }
Output (you can see that styles that do not pass the preconditions are filtered)
#outer .inner { color: blue; } .c { color: blue; }
-
Mixed with parameters, you can specify default values, you can take multiple parameters, you can assign values by name when using
.mixin(@color: black; @margin: 10px; @padding: 20px) { color: @color; margin: @margin; padding: @padding; } .class1 { .mixin(@margin: 20px; @color: #33acfe); } .class2 { .mixin(#efca44; @padding: 40px); }
-
Use @arguments
.mixin(@a; @b) { margin: @arguments; right:extract(@arguments,2); top:@b; } p {.mixin(1px; 2px);}
output
p { margin: 1px 2px; right: 2px; top: 2px; }
-
Use the @rest parameter
// Mode 1 .mixin(@listofvariables...) { border: @listofvariables; } p { .mixin(1px; solid; red); } // Mode 2 .mixin(@a; ...) { color: @a;} .mixin(@a) { background-color: contrast(@a); width:100%;} .mixin(@a; @b;) { background-color: contrast(@a); width:@b;} p { .mixin(red); } p.small { .mixin(red,50%); }
output
/*Mode 1*/ p { border: 1px solid red; } /*Mode 2*/ p { color: red; background-color: #ffffff; width: 100%; } p.small { color: red; background-color: #ffffff; width: 50%; }
-
Pattern Matching Hybridization
.mixin(dark; @color) { color: darken(@color, 10%); } .mixin(light; @color) { color: lighten(@color, 10%); } .mixin(@_; @color) { display: block; } @switch: light; .class { .mixin(@switch; #888); }
output
.class { color: #a2a2a2; display: block; }
-
Rule Set Mixing
// declare detached ruleset @detached-ruleset: { background: red; }; // use detached ruleset .top { @detached-ruleset(); }
function
Similar to calculating the value of a variable by function operation, then setting the attribute by the value of the variable.
.mixin() { @width: 100%; @height: 200px; } .caller { .mixin(); width: @width; height: @height; }
output
.caller { width: 100%; height: 200px; }
inherit
Inheriting the properties of another selector,more details
nav ul { &:extend(.inline); background: blue; } // & Is the parent type selector, referring to nav ul .inline { color: red; }
output
nav ul { background: blue; } .inline, nav ul { color: red; }
nesting
#header { color: black; .navigation { font-size: 12px; } .logo { width: 300px; } }
Introduce
@import "foo"; // foo.less is imported @import "foo.less"; // foo.less is imported @import "foo.php"; // foo.php imported as a less file @import "foo.css"; // statement left in place, as-is
parameter
@import (keyword) "filename";
- reference: use a Less file but do not output it
- inline: include the source file in the output but do not process it
- less: treat the file as a Less file, no matter what the file extension
- css: treat the file as a CSS file, no matter what the file extension
- once: only include the file once (this is default behavior)
- multiple: include the file multiple times
- optional: continue compiling when file is not found
loop
.generate-columns(4); .generate-columns(@n, @i: 1) when (@i =< @n) { .column-@{i} { width: (@i * 100% / @n); } .generate-columns(@n, (@i + 1)); }
output
.column-1 { width: 25%; } .column-2 { width: 50%; } .column-3 { width: 75%; } .column-4 { width: 100%; }
merge
-
Comma merge
.mixin() { box-shadow+: inset 0 0 10px #555; } .myclass { .mixin(); box-shadow+: 0 0 20px black; }
output
.myclass { box-shadow: inset 0 0 10px #555, 0 0 20px black; }
-
Space merging
.mixin() { transform+_: scale(2); } .myclass { .mixin(); transform+_: rotate(15deg); }
output
.myclass { transform: scale(2) rotate(15deg); }
Switching Theme Styles
Option 1
This can be used when several themes have similar layouts, almost just different colors.
Through the understanding of less (many additional Sao operations can be carried out), we here most simply write the following less file.
- The basic style template style.less, which sets each style mainly through variables
- patriotic-red.less, set the value of the variable
- Sky Blue Style sky-blue.less, set different variable values
- ...
style.less
The inside style is similar to this.a, .link { color: @link-color; } a:hover { color: @link-color-hover; } .widget { color: #fff; background: @link-color; }
patriotic-red.less has a similar style
@import "style"; @link-color: #f03818; @link-color-hover: darken(@link-color, 10%);
The sky-blue.less style is similar to this
@import "test"; @link-color: #428bca; @link-color-hover: darken(@link-color, 10%);
Compiled to patriotic-red.css and sky-blue.css files in advance by using related tools (or manual lessc of the original person).
Here's a simple assumption that only the default patriotic red is introduced in the page header——
<link rel="stylesheet" href="./patriotic-red.css" />
At the same time, there is a button to switch the theme when the user clicks. First, we bind the click event to the button, delete the current imported style when the user clicks, and then introduce another style. The specific operation is as follows:
function toggleThemeClick() { let a = document.getElementsByTagName("link"); let aHref = a[0].getAttribute("href").slice(2, -4); a[0].parentElement.removeChild(a[0]); let b = document.createElement("link"); b.setAttribute("rel", "stylesheet"); if ("patriotic-red" === aHref) { b.setAttribute("href", "./sky-blue.css"); } else { b.setAttribute("href", "./patriotic-red.css"); } document.getElementsByTagName("head")[0].appendChild(b); }
So we can switch themes freely.
Option 2
We can also switch topics by adding class labels to the body.
Create a new style-mixin.less, which reads as follows——
.patriotic-red { @import "patriotic-red"; } .sky-blue { @import "sky-blue"; }
It should be noted here that when style.less is introduced into sky-blue.less or patriotic-red.less, you need to use the (multiple) parameter, otherwise only one style will be compiled. The compiled style is automatically prefixed with. patriotic-red and sky-blue.
At this point, you just need to introduce a style-mixin.css, and modify the class label of the body when you want to switch styles.
document,getElementsByTagName('body')[0].className='xxx'
Digression
The headliner doesn't seem to agree with Plan 1 very much. He thinks that Plan 1 will lead to a conflict between the previously introduced pattern and the later one. I did not understand the specific meaning, because of the time relationship, he did not explain very clearly, hope to know where the problem is, let me know.
ps, is there a better way to switch the theme?