Less
常見的預處理語言:Less Sass Stylus
Less學習
使用 Less 的方式
頁面引入js代碼文件解析
1、
我們可以直接在客戶端使用 .less(LESS 源文件),只需要從 http://lesscss.org下載 less.js 文件,然后在我們需要引入 LESS 源文件的 HTML 中加入如下代碼,也可以直接引入cdn. 首先引入less代碼
link rel="stylesheet/less" href="example.less"
script src="http://cdn.bootcss.com/less.js/2.7.0/less.js"
注意順序不能亂
2、
服務器端編譯less
安裝完node.js之后,打開Node.js command prompt,通過npm install -d less命令安裝LESS包,然后新建一個demo.less文件,輸入lessc demo.less > test.css之后以后即可編譯CSS文件。
3、
在Vscode中安裝easy less
插件可以實時的編譯less文件
變量(variables)
1、值變量
less
/* Less */
@color: #999;
@bgColor: skyblue;//不要添加引號
@width: 50%;
#wrap {
color: @color;
background: @bgColor;
width: @width;
}
/* 生成后的 CSS */
#wrap {
color: #999;
background: skyblue;
width: 50%;
}
以 @
開頭 定義變量,並且使用時 直接 鍵入 @
名稱
在平時工作中,我們就可以把常用的變量封裝到一個文件中,這樣利於代碼組織維護
@lightPrimaryColor: #c5cae9;
@textPrimaryColor: #fff;
@accentColor: rgb(99, 137, 185);
@primaryTextColor: #646464;
@secondaryTextColor: #000;
@dividerColor: #b6b6b6;
@borderColor: #dadada;
2、選擇器變量
讓 選擇器 變成 動態
/* Less */
@mySelector: #wrap;
@Wrap: wrap;
@{mySelector}{ //變量名 必須使用大括號包裹
color: #999;
width: 50%;
}
.@{Wrap}{
color:#ccc;
}
#@{Wrap}{
color:#666;
}
/* 生成的 CSS */
#wrap{
color: #999;
width: 50%;
}
.wrap{
color:#ccc;
}
#wrap{
color:#666;
}
3、屬性變量
可減少代碼書寫量
/* Less */
@borderStyle: border-style;
@Soild:solid;
#wrap{
@{borderStyle}: @Soild;//變量名 必須使用大括號包裹
}
/* 生成的 CSS */
#wrap{
border-style:solid;
}
4、url 變量
/* Less */
@images: "../img";//需要加引號
body {
background: url("@{images}/dog.png");//變量名 必須使用大括號包裹
}
/* 生成的 CSS */
body {
background: url("../img/dog.png");
}
5、聲明變量
有點類似於 下面的 混合方法
- 結構: @name: { 屬性: 值 ;};
- 使用:@name();
/* Less */
@background: {background:red;};
#main{
@background();
}
@Rules:{
width: 200px;
height: 200px;
border: solid 1px red;
};
#con{
@Rules();
}
/* 生成的 CSS */
#main{
background:red;
}
#con{
width: 200px;
height: 200px;
border: solid 1px red;
}
6、變量運算
- 加減法時 以第一個數據的單位為基准
- 乘除法時 注意單位一定要統一
/* Less */
@width:300px;
@color:#222;
#wrap{
width:@width-20;
height:@width-20*5;
margin:(@width-20)*5;
color:@color*2;
background-color:@color + #111;
}
/* 生成的 CSS */
#wrap{
width:280px;
height:200px;
margin:1400px;
color:#444;
background-color:#333;
}
7、變量作用域
/* Less */
@var: @a;
@a: 100%;
#wrap {
width: @var;
@a: 9%;
}
/* 生成的 CSS */
#wrap {
width: 9%;
}
8、用變量去定義變量
/* Less */
@fnord: "I am fnord.";
@var: "fnord";
#wrap::after{
content: @@var; //將@var替換為其值 content:@fnord;
}
/* 生成的 CSS */
#wrap::after{
content: "I am fnord.";
}
嵌套
1、& 的妙用
& :代表的上一層選擇器的名字,此例便是header
。
/* Less */
#header{
&:after{
content:"Less is more!";
}
.title{
font-weight:bold;
}
&_content{//理解方式:直接把 & 替換成 #header
margin:20px;
}
}
/* 生成的 CSS */
#header::after{
content:"Less is more!";
}
#header .title{ //嵌套了
font-weight:bold;
}
#header_content{//沒有嵌套!
margin:20px;
}
2、媒體查詢
/* Less */
#main{
//something...
@media screen{
@media (max-width:768px){
width:100px;
}
}
@media tv {
width:2000px;
}
}
/* 生成的 CSS */
@media screen and (maxwidth:768px){
#main{
width:100px;
}
}
@media tv{
#main{
width:2000px;
}
}
唯一的缺點就是 每一個元素都會編譯出自己 @media 聲明,並不會合並。
混合
1、無參數方法
方法猶如 聲明的集合,使用時 直接鍵入名稱即可。
/* Less */
.card { // 等價於 .card()
background: #f6f6f6;
-webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
}
#wrap{
.card;//等價於.card();
}
/* 生成的 CSS */
#wrap{
background: #f6f6f6;
-webkit-box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
box-shadow: 0 1px 2px rgba(151, 151, 151, .58);
}
其中 .card 與 .card() 是等價的。
.
與#
皆可作為 方法前綴。- 方法后寫不寫
()
看個人習慣。
2、默認參數方法
- Less 可以使用默認參數,如果沒有傳參數,那么將使用默認參數。
- @arguments 猶如 JS 中的 arguments 指代的是 全部參數。
- 傳的參數中 必須帶着單位。
/* Less */
.border(@a:10px,@b:50px,@c:30px,@color:#000){
border:solid 1px @color;
box-shadow: @arguments;//指代的是 全部參數
}
#main{
.border(0px,5px,30px,red);//必須帶着單位
}
#wrap{
.border(0px);
}
#content{
.border;//等價於 .border()
}
/* 生成的 CSS */
#main{
border:solid 1px red;
box-shadow:0px,5px,30px,red;
}
#wrap{
border:solid 1px #000;
box-shadow: 0px 50px 30px #000;
}
#content{
border:solid 1px #000;
box-shadow: 10px 50px 30px #000;
}
3、方法的匹配模式
與 面向對象中的多態 很相似
/* Less */
.triangle(top,@width:20px,@color:#000){
border-color:transparent transparent @color transparent ;
}
.triangle(right,@width:20px,@color:#000){
border-color:transparent @color transparent transparent ;
}
.triangle(bottom,@width:20px,@color:#000){
border-color:@color transparent transparent transparent ;
}
.triangle(left,@width:20px,@color:#000){
border-color:transparent transparent transparent @color;
}
.triangle(@_,@width:20px,@color:#000){
border-style: solid;
border-width: @width;
}
#main{
.triangle(left, 50px, #999)
}
/* 生成的 CSS */
#main{
border-color:transparent transparent transparent #999;
border-style: solid;
border-width: 50px;
}
- 第一個參數
left
要會找到方法中匹配程度最高的,如果匹配程度相同,將全部選擇,並存在着樣式覆蓋替換。 - 如果匹配的參數 是變量,則將會匹配,如
@_
。
4、方法的命名空間
/* Less */
#card(){
background: #723232;
.d(@w:300px){
width: @w;
#a(@h:300px){
height: @h;//可以使用上一層傳進來的方法
}
}
}
#wrap{
#card > .d > #a(100px); // 父元素不能加 括號
}
#main{
#card .d();
}
#con{
//不得單獨使用命名空間的方法
//.d() 如果前面沒有引入命名空間 #card ,將會報錯
#card; // 等價於 #card();
.d(20px); //必須先引入 #card
}
/* 生成的 CSS */
#wrap{
height:100px;
}
#main{
width:300px;
}
#con{
width:20px;
}
- 在 CSS 中
>
選擇器,選擇的是 兒子元素,就是 必須與父元素 有直接血源的元素。 - 在引入命令空間時,如使用
>
選擇器,父元素不能加 括號。 - 不得單獨使用命名空間的方法 必須先引入命名空間,才能使用 其中方法。
- 子方法 可以使用上一層傳進來的方法
5、方法的條件篩選
Less 沒有 if else,可是它有 when
/* Less */
#card{
// and 運算符 ,相當於 與運算 &&,必須條件全部符合才會執行
.border(@width,@color,@style) when (@width>100px) and(@color=#999){
border:@style @color @width;
}
// not 運算符,相當於 非運算 !,條件為 不符合才會執行
.background(@color) when not (@color>=#222){
background:@color;
}
// , 逗號分隔符:相當於 或運算 ||,只要有一個符合條件就會執行
.font(@size:20px) when (@size>50px) , (@size<100px){
font-size: @size;
}
}
#main{
#card>.border(200px,#999,solid);
#card .background(#111);
#card > .font(40px);
}
/* 生成后的 CSS */
#main{
border:solid #999 200px;
background:#111;
font-size:40px;
}
- 比較運算有: > >= = =< <。
- = 代表的是等於
- 除去關鍵字 true 以外的值都被視為 false:
6、數量不定的參數
如果你希望你的方法接受數量不定的參數,你可以使用... ,猶如 ES6 的擴展運算符。
/* Less */
.boxShadow(...){
box-shadow: @arguments;
}
.textShadow(@a,...){
text-shadow: @arguments;
}
#main{
.boxShadow(1px,4px,30px,red);
.textShadow(1px,4px,30px,red);
}
/* 生成后的 CSS */
#main{
box-shadow: 1px 4px 30px red;
text-shadow: 1px 4px 30px red;
}
7、方法使用important!
方法名后 加上關鍵字即可。
/* Less */
.border{
border: solid 1px red;
margin: 50px;
}
#main{
.border() !important;
}
/* 生成后的 CSS */
#main {
border: solid 1px red !important;
margin: 50px !important;
}
8、循環方法
Less 並沒有提供 for 循環功能,但這也難不倒 聰明的程序員,使用遞歸去實現。 下面是官網中的一個 Demo,模擬了生成柵格系統。
/* Less */
.generate-columns(4);
.generate-columns(@n, @i: 1) when (@i =< @n) {
.column-@{i} {
width: (@i * 100% / @n);
}
.generate-columns(@n, (@i + 1));
}
/* 生成后的 CSS */
.column-1 {
width: 25%;
}
.column-2 {
width: 50%;
}
.column-3 {
width: 75%;
}
.column-4 {
width: 100%;
}
9、屬性拼接方法
+_
代表的是 空格
;+
代表的是 逗號
。
- 逗號
/* Less */
.boxShadow() {
box-shadow+: inset 0 0 10px #555;
}
.main {
.boxShadow();
box-shadow+: 0 0 20px black;
}
/* 生成后的 CSS */
.main {
box-shadow: inset 0 0 10px #555, 0 0 20px black;
}
- 空格
/* Less */
.Animation() {
transform+_: scale(2);
}
.main {
.Animation();
transform+_: rotate(15deg);
}
/* 生成的 CSS */
.main {
transform: scale(2) rotate(15deg);
}
10、實戰技巧
下面是官網中的一個非常贊的 Demo
/* Less */
.average(@x, @y) {
@average: ((@x + @y) / 2);
}
div {
.average(16px, 50px); // 調用 方法
padding: @average; // 使用返回值
}
/* 生成的 CSS */
div {
padding: 33px;
}
可以說 Less 是一門優雅編程語言。
繼承
extend 是 Less 的一個偽類。它可繼承 所匹配聲明中的全部樣式。
1、extend 關鍵字的使用
/* Less */
.animation{
transition: all .3s ease-out;
.hide{
transform:scale(0);
}
}
#main{
&:extend(.animation);
}
#con{
&:extend(.animation .hide);
}
/* 生成后的 CSS */
.animation,#main{
transition: all .3s ease-out;
}
.animation .hide , #con{
transform:scale(0);
}
2、all 全局搜索替換
使用選擇器匹配到的 全部聲明。
/* Less */
#main{
width: 200px;
}
#main {
&:after {
content:"Less is good!";
}
}
#wrap:extend(#main all) {}
/* 生成的 CSS */
#main,#wrap{
width: 200px;
}
#main:after, #wrap:after {
content: "Less is good!";
}
3、減少代碼的重復性
從表面 看來,extend 與 方法 最大的差別,就是 extend 是同個選擇器共用同一個聲明,而 方法 是使用自己的聲明,這無疑 增加了代碼的重復性。
方法示例 與上面的 extend 進行對比:
/* Less */
.Method{
width: 200px;
&:after {
content:"Less is good!";
}
}
#main{
.Method;
}
#wrap{
.Method;
}
/* 生成的 CSS */
#main{
width: 200px;
&:after{
content:"Less is good!";
}
}
#wrap{
width: 200px;
&:after{
content:"Less is good!";
}
}
4、要點
- 選擇器和擴展之間 是允許有空格的:pre:hover :extend(div pre).
- 可以有多個擴展: pre:hover:extend(div pre):extend(.bucket tr) - 注意這與 pre:hover:extend(div pre, .bucket tr)一樣。
- 這是不可以的,擴展必須在最后 : pre:hover:extend(div pre).nth-child(odd)。
- 如果一個規則集包含多個選擇器,所有選擇器都可以使用extend關鍵字。
導入
1、導入 less 文件 可省略后綴
import "main";
//等價於
import "main.less";
2、@import
的位置可隨意放置
#main{
font-size:15px;
}
@import "style";
3、reference
Less 中 最強大的特性 使用 引入的 Less 文件,但不會 編譯它。
/* Less */
@import (reference) "bootstrap.less";
#wrap:extend(.navbar all){}
使用@import (reference)導入外部文件,但不會添加 把導入的文件 編譯到最終輸出中,只引用。
4、once
@import語句的默認行為。這表明相同的文件只會被導入一次,而隨后的導入文件的重復代碼都不會解析。
@import (once) "foo.less";
@import (once) "foo.less"; // this statement will be ignored
5、multiple
使用@import (multiple)允許導入多個同名文件。
/* Less */
// file: foo.less
.a {
color: green;
}
// file: main.less
@import (multiple) "foo.less";
@import (multiple) "foo.less";
/* 生成后的 CSS */
.a {
color: green;
}
.a {
color: green;
}
函數
1、判斷類型
- isnumber
判斷給定的值 是否 是一個數字。
isnumber(#ff0); // false
isnumber(blue); // false
isnumber("string"); // false
isnumber(1234); // true
isnumber(56px); // true
isnumber(7.8%); // true
isnumber(keyword); // false
isnumber(url(...)); // false
- iscolor
判斷給定的值 是否 是一個顏色。
- isurl
判斷給定的值 是否 是一個 url 。
2、顏色操作
saturate
增加一定數值的顏色飽和度。
lighten
增加一定數值的顏色亮度。
darken
降低一定數值的顏色亮度。
fade
給顏色設定一定數值的透明度。
mix
根據比例混合兩種顏色。
3、數學函數
ceil
向上取整。
floor
向下取整。
percentage
將浮點數轉換為百分比字符串。
round
四舍五入。
sqrt
計算一個數的平方根。
abs
計算數字的絕對值,原樣保持單位。
pow
計算一個數的乘方。
深度思考
如何做默認樣式重置?resetting 和 normalizing 之間有什么區別?
樣式重置出現的原因
在日常生活中常用的幾個主流瀏覽器中, 當我們沒有給html元素設置樣式時,這些瀏覽器會根據自己的默認樣式對html元素進行布局,但是由於每個瀏覽器的默認布局樣式不同, 會導致元素的展示方式出現差異,從而使同一頁面在不同瀏覽器中的展示出現差異。使用CSS樣式重置這一方式,就可以使網頁展示效果保持 一致。
什么是CSS RESET?
一開始就將瀏覽器的默認樣式全部去掉,更准確說就是通過重新定義標簽樣式。“覆蓋”瀏覽器的CSS默認屬性嗎,把瀏覽器提供的默認樣式覆蓋掉!這就是CSS reset。
如何做CSS RESET
寫css reset的時候,主要是要根據我們對網頁的需求而來的,我們需要用到哪些標簽,當我們所用到的那些標簽的默認樣式也我們期望的不符的時候,有或者是在不同瀏覽器下元素的默認樣式不同而讓我們的頁面在不同的瀏覽器下顯示不同的布局而不符合我們的預期,我們就在css reset為這些元素重置它的樣式來達到我們的要求。
什么是Normalize?
Normalize.css 只是一個很小的CSS文件,但它在默認的HTML元素樣式上提供了跨瀏覽器的高度一致性。相比於傳統的CSSreset,Normalize.css是一種現代的、為HTML5准備的優質替代方案。Normalize.css現在已經被用於Twitter``Bootstrap
、HTML5Boilerplate
、GOV.UK
、Rdio
、CSS Tricks
以及許許多多其他框架、工具和網站上。
Normalize.css和傳統Reset的區別
- Normalize.css 保護了有價值的默認值
- Normalize.css 修復了瀏覽器的bug
- Normalize.css 不會讓你的調試工具變的雜亂
- Normalize.css 是模塊化的
- Normalize.css 擁有詳細的文檔
如何使用 normalize.css
首先,安裝或從Github下載Normalize.css,接下來有兩種主要途徑去使用它。
- 策略一:將normalize.css作為你自己項目的基礎CSS,自定義樣式值以滿足設計師的需求。
- 策略二:引入normalize.css源碼並在此基礎上構建,在必要的時候用你自己寫的CSS覆蓋默認值。
前端組件化
前端為什么要組件化
在大型軟件系統中,web應用的前后端已經實現了分離,而隨着REST軟件架構的發展,后端服務逐步傾向於微服務,簡單來說就是將一個大型后端服務,拆分成多個小服務,它們分別部署,降低了開發的復雜性,而且提高了系統的可伸縮性。而前端方面,隨着技術的發展,開發的復雜度也越來越高,傳統開發模式總是存在着開發效率低,維護成本高等的弊端。
傳統開發方式效率低以及維護成本高的主要原因在於很多時候是將一個系統做成了整塊應用,而且往往隨着業務的增長或者變更,系統的復雜度會呈現指數級的增長,經常出現的情況就是一個小小的改動或者一個小功能的增加可能會引起整體邏輯的修改,造成牽一發而動全身。
隨着React,angular等以組件(指令等)為主的優秀前端框架的出現,前端組件化逐漸成為前端開發的迫切需求,當然這一迫切需求也逐漸成為一種主流,一種共識,它不僅提高了前端的開發效率,同時也降低了維護成本。開發者們不需要再面對一堆復雜且難閱讀的代碼,轉而只需要關注以組件方式存在的代碼片段。
從開發者角度來看:
在CSS上,保證代碼上的模塊化,具有獨立作用域;
內部的布局,字體的變化(不包括顏色這類是不可控的)只由其最外層容器影響。
概括的說就是,組件內部的布局只受容器變化影響。 在容器不受外部影響變化的前提下,內部容器的樣式不被外部所影響
從整個公司的發展來看:
業務划分更佳清晰,新人接手更佳容易,可以按組件分配開發任務。
項目可維護性更強,提高開發效率。
更好排查問題,某個組件出現問題,直接對組件進行處理。
開發測試過程中,可以只編譯自己那部分代碼,不需要編譯整個項目代碼。
前端組件化的4個原則
- 標准性
任何一個組件都應該遵守一套標准,可以使得不同區域的開發人員據此標准開發出一套標准統一的組件。
- 組合性
組件之前應該是可以組合的。我們知道前端頁面的展示都是一些HTML DOM的組合,而組件在最終形態上也可以理解為一個個的HTML片段。那么組成一個完整的界面展示,肯定是要依賴不同組件之間的組合,嵌套以及通信。
- 重用性
任何一個組件應該都是一個可以獨立的個體,可以使其應用在不同的場景中。
- 可維護性
任何一個組件應該都具有一套自己的完整的穩定的功能,僅包含自身的,與其它組件無關的邏輯,使其更加的容易理解,使其更加的容易理解,同時大大減少發生bug的幾率。