某一天,一個頭條的大佬問我,據說你以前在項目裏面弄過主題切換,你當時是怎麼實現的能夠詳說一下嗎?
若是已經對less瞭如指掌,直接從這裏開始。php
Node.js 環境中使用 Less :css
npm install -g less > lessc styles.less styles.css
在瀏覽器環境中使用 Less :html
<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,而後再引入使用。webpack
@nice-blue: #5B83AD; @light-blue: @nice-blue + #111; #header { color: @light-blue; }
經常使用web
.bordered { border-top: dotted 1px black; &:hover { border: 1px solid red; } // 一樣能夠包含選擇器混用 } .post a { color: red; .bordered !important; // 能夠在屬性後面都加上!important }
編譯後不輸出至css文件ajax
.my-other-mixin() { background: white; }
做用域混合npm
#outer { .inner() { color: red; } } #outer1 { .inner() { color: blue; } } .c { #outer > .inner; }
輸出gulp
.c { color: red; }
擁有前置條件的做用域混合,更多詳情瀏覽器
@mode: little; #outer when (@mode=huge) { .inner { color: red; } } #outer when (@mode=little) { .inner { color: blue; } } .c { #outer > .inner; }
輸出(能夠看到沒有經過前置條件的樣式被過濾了)app
#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); }
當幾種主題佈局相似,幾乎只是顏色不一樣時,可使用這種。
經過對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); }
這樣咱們就能夠自由的切換主題啦。
咱們還能夠經過給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,有沒有更好的切換主題的方案呢,求大佬指點~