有一天,今日头条的大佬问我,听说你之前在项目中做过主题切换,能详细说一下你是怎么实现的吗?如果您已经不太了解,请从这里开始。让我们从less开始,在Node.js环境下使用Less:npminstall-gless>lesscstyles.lessstyles.css在浏览器环境下使用Less:但是建议编译less通过webpack或者gulp等工具导入到css中,然后导入使用。变量@nice-blue:#5B83AD;@light-blue:@nice-blue+#111;#header{color:@light-blue;}mixcommon.bordered{border-top:dotted1pxblack;&:hover{border:1px纯红色;}//也可以包含选择器mix}.posta{color:red;.bordered!important;//你可以在属性的末尾添加!important}并编译而不输出到css文件。my-other-mixin(){background:white;}范围混合#outer{.inner(){颜色:红色;}}#outer1{.inner(){颜色:蓝色;}}.c{#outer>.inner;}output.c{color:red;}Scopemixinwithpreconditions,更多细节@mode:little;#outerwhen(@mode=huge){.inner{color:red;}}#outerwhen(@mode=little){.inner{颜色:蓝色;}}.c{#outer>.inner;}输出(可以看到不通过前置条件的样式被过滤)#outer.inner{color:blue;}.c{color:blue;}与参数混合,可以指定默认值,可以带多个参数,使用的时候可以按名称赋值。mixin(@color:black;@margin:10px;@padding:20px){color:@color;保证金:@保证金;填充:@padding;}.class1{.mixin(@margin:20px;@color:#33acfe);}.class2{.mixin(#efca44;@padding:40px);}使用@arguments.mixin(@a;@b){保证金:@参数;对:提取物(@arguments,2);top:@b;}p{.mixin(1px;2px);}输出p{margin:1px2px;右:2px;top:2px;}using@restparameter//Mode1.mixin(@listofvariables...){border:@listofvariables;}p{.mixin(1px;solid;red);}//模式2.mixin(@a;...){颜色:@a;}.mixin(@a){背景颜色:对比(@a);宽度:100%;}.mixin(@a;@b;){背景颜色:对比度(@a);width:@b;}p{.mixin(red);}p.small{.mixin(red,50%);}output/*method1*/p{border:1pxsolidred;}/*method2*/p{颜色:红色;背景色:#ffffff;宽度:100%;}p.small{颜色:红色;背景色:#ffffff;width:50%;}模式匹配mixin.mixin(dark;@color){color:darken(@color,10%);}.mixin(light;@color){color:lighten(@color,10%);}.mixin(@_;@color){显示:块;}@switch:light;.class{.mixin(@switch;#888);}output.class{color:#a2a2a2;display:block;}rulesetmixin//声明分离规则集@detached-ruleset:{background:red;};//使用分离规则集.top{@detached-ruleset();}函数类类似于先通过函数运算计算出变量的值,然后通过变量的值来设置属性.mixin(){@width:100%;@height:200px;}.caller{.mixin();宽度:@宽度;高度:@height;}output.caller{宽度:100%;height:200px;}Inherit继承另一个选择器的属性,更多细节navul{&:extend(.inline);background:blue;}//&是父类型选择器,指的是navul.inline{color:red;}outputnavul{background:blue;}.inline,navul{color:red;}nested#header{color:black;.navigation{字体大小:12px;}.logo{宽度:300px;}}导入@import"foo";//foo.less是imported@import"foo.less";//foo.less是imported@import"foo.php";//foo.php作为less文件导入@import"foo.css";//语句保留原样,原样参数@import(keyword)"filename";reference:使用Less文件但不输出itinline:在输出中包含源文件但不处理itless:将文件视为Lessfile,无论文件扩展名是什么css:将文件视为CSS文件,无论文件扩展名是什么once:只包含文件一次(这是默认行为)multiple:多次包含文件可选:找不到文件时继续编译loop.generate-columns(4);.generate-columns(@n,@i:1)when(@i=<@n){.column-@{i}{宽度:(@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%;}合并逗号合并。mixin(){box-shadow+:inset0010px#555;}.myclass{.mixin();box-shadow+:0020pxblack;}output.myclass{box-shadow:inset0010px#555,0020pxblack;}spacemerge.mixin(){transform+_:scale(2);}.myclass{.mixin();transform+_:rotate(15deg);}Output.myclass{transform:scale(2)rotate(15deg);}切换主题样式方案1当几个主题布局相似,几乎只有颜色不同,可以用这个对less的理解(可以进行很多额外的操作),这里我们用最简单的方式编写如下的less文件。基础样式模板style.less,主要通过变量设置各种样式patriotic-redstylepatriotic-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";@链接颜色:#f03818;@link-color-hover:变暗(@link-color,10%);sky-blue.less中的样式是这样的@import"test";@link-color:#428bca;@link-color-hover:变暗(@link-color,10%);使用相关工具(或原始手册lessc)预先编译patriotic-red.css和sky-blue.css文件。这里简单假设页面头部只引入默认的爱国红——还有一个切换主题的按钮用户点击。首先我们给按钮绑定点击事件,当用户点击时删除当前引入的样式,然后再引入另一种样式。具体操作如下:functiontoggleThemeClick(){leta=document.getElementsByTagName("link");让aHref=a[0].getAttribute("href").slice(2,-4);a[0].parentElement.removeChild(a[0]);让b=document.createElement("链接");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我们也可以通过在正文中添加类标签来切换主题。新建一个style-mixin.less,内容如下——.patriotic-red{@import"patriotic-red";}.sky-blue{@import"sky-blue";}这里要注意的是在sky-中将style.less引入blue.less或patriotic-red.less时,需要使用(multiple)参数,否则只会编译一个style。编译的样式将自动以.patriotic-red和sky-blue为前缀。这时只需要导入一份style-mixin.css,在切换样式时修改body的class标签即可。document,getElementsByTagName('body')[0].className='xxx'题外话今日头条似乎不太赞同方案一,他认为方案一会导致之前引入的样式和后面的冲突?具体是什么意思我没看懂,他也因为时间关系没有解释的很清楚。希望知道问题出在哪里的同学能告诉我。ps,切换主题有没有更好的解决办法?请大家多多指教~参考lesscss.cn