某一天,一个头条的大佬问我,听说你之前在项目里面弄过主题切换,你当时是怎么实现的可以详说一下吗?如果已经对less了如指掌,直接从这里开始。从less说起使用Node.js 环境中使用 Less :npm install -g less> lessc styles.less styles.css在浏览器环境中使用 Less :<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>不过比较推荐的还是通过webpack或者gulp等工具先将less编译成css,然后再引入使用。变量@nice-blue: #5B83AD;@light-blue: @nice-blue + #111;#header { color: @light-blue;}混合常用.bordered { border-top: dotted 1px black; &:hover { border: 1px solid red; } // 同样可以包含选择器混用}.post a { color: red; .bordered !important; // 可以在属性后面都加上!important}编译后不输出至css文件.my-other-mixin() { background: white;}作用域混合#outer { .inner() { color: red; }}#outer1 { .inner() { color: blue; }}.c { #outer > .inner;}输出.c { color: red;}拥有前置条件的作用域混合,更多详情@mode: little;#outer when (@mode=huge) { .inner { color: red; }}#outer when (@mode=little) { .inner { color: blue; }}.c { #outer > .inner;}输出(可以看到没有通过前置条件的样式被过滤了)#outer .inner { color: blue;}.c { color: blue;}带参数混合,可以指定默认值,可以带多个参数,使用时可以通过名称赋值.mixin(@color: black; @margin: 10px; @padding: 20px) { color: @color; margin: @margin; padding: @padding;}.class1 { .mixin(@margin: 20px; @color: #33acfe);}.class2 { .mixin(#efca44; @padding: 40px);}使用@arguments.mixin(@a; @b) { margin: @arguments; right:extract(@arguments,2); top:@b;}p {.mixin(1px; 2px);}输出p { margin: 1px 2px; right: 2px; top: 2px;}使用@rest参数// 方式1.mixin(@listofvariables…) { border: @listofvariables;}p { .mixin(1px; solid; red);}// 方式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%);}输出/方式1/p { border: 1px solid red;}/方式2/p { color: red; background-color: #ffffff; width: 100%;}p.small { color: red; background-color: #ffffff; width: 50%;}模式匹配混合.mixin(dark; @color) { color: darken(@color, 10%);}.mixin(light; @color) { color: lighten(@color, 10%);}.mixin(@; @color) { display: block;}@switch: light;.class { .mixin(@switch; #888);}输出.class { color: #a2a2a2; display: block;}规则集混合// declare detached ruleset@detached-ruleset: { background: red; };// use detached ruleset.top { @detached-ruleset(); }函数类似于先函数运算计算出变量的值,再通过变量的值设置属性。.mixin() { @width: 100%; @height: 200px;}.caller { .mixin(); width: @width; height: @height;}输出.caller { width: 100%; height: 200px;}继承继承另外一个选择器的属性,更多详情nav ul { &:extend(.inline); background: blue;} // &是父类型选择器,指代的是nav ul.inline { color: red;}输出nav ul { background: blue;}.inline,nav ul { color: red;}嵌套#header { color: black; .navigation { font-size: 12px; } .logo { width: 300px; }}引入@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参数@import (keyword) “filename”;reference: use a Less file but do not output itinline: include the source file in the output but do not process itless: treat the file as a Less file, no matter what the file extensioncss: treat the file as a CSS file, no matter what the file extensiononce: only include the file once (this is default behavior)multiple: include the file multiple timesoptional: continue compiling when file is not found循环.generate-columns(4);.generate-columns(@n, @i: 1) when (@i =< @n) { .column-@{i} { width: (@i * 100% / @n); } .generate-columns(@n, (@i + 1));}输出.column-1 { width: 25%;}.column-2 { width: 50%;}.column-3 { width: 75%;}.column-4 { width: 100%;}合并逗号合并.mixin() { box-shadow+: inset 0 0 10px #555;}.myclass { .mixin(); box-shadow+: 0 0 20px black;}输出.myclass { box-shadow: inset 0 0 10px #555, 0 0 20px black;}空格合并.mixin() { transform+: scale(2);}.myclass { .mixin(); transform+_: rotate(15deg);}输出.myclass { transform: scale(2) rotate(15deg);}切换主题样式方案1当几种主题布局类似,几乎只是颜色不同时,可以使用这种。通过对less的了解(可以进行许多额外的骚操作哦),我们这里最简单地编写出如下less文件。基础样式模版style.less,里面主要通过变量设置各个样式爱国红样式patriotic-red.less,设置变量的值天空蓝样式sky-blue.less,设置不同的变量值…style.less里样式类似这样a,.link { color: @link-color;}a:hover { color: @link-color-hover;}.widget { color: #fff; background: @link-color;}patriotic-red.less里样式类似这样@import “style”;@link-color: #f03818; @link-color-hover: darken(@link-color, 10%);sky-blue.less里样式类似这样@import “test”;@link-color: #428bca;@link-color-hover: darken(@link-color, 10%);利用相关工具(或原始人手动lessc)提前编译成patriotic-red.css和sky-blue.css文件。这里简单的假设页面header中只引入了默认爱国红——<link rel=“stylesheet” href="./patriotic-red.css" />同时存在一个按钮,用户点击时切换主题。首先我们给按钮绑定点击事件,当用户点击时删除当前导入的样式,然后再引入另外一个样式。具体操作如下: 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); }这样我们就可以自由的切换主题啦。方案2我们还可以通过给body添加类标签来进行主题的切换。新建一个style-mixin.less,里面内容如下——.patriotic-red { @import “patriotic-red”;}.sky-blue { @import “sky-blue”;}这里需要注意的是,在sky-blue.less或者patriotic-red.less中引入style.less时,需要使用(multiple)参数,否则会只编译出一份样式。编译出来的样式会自动加上.patriotic-red和sky-blue前缀。这个时候只需要引入一份style-mixin.css就行了,要切换样式的时候修改body的类标签。document,getElementsByTagName(‘body’)[0].className=‘xxx’题外话头条大佬似乎并不是很认可方案1,他认为方案1会导致之前引入的样式和后来的冲突?我没有明白具体是什么意思,由于时间关系他也没有解释得很清楚,希望知道问题出在哪里的同学告诉我一下哦。ps,有没有更好的切换主题的方案呢,求大佬指点~参考lesscss.cn