工具函數
//獲取和遍歷所有匹配特定css選擇符的DOM元素
function $$(selector, context) {
context = context || document;
var elements = context.querySelectorAll(selector);
return Array.prototype.slice.call(elements);
}
//檢測css屬性支持情況
function testProperty(property) {
var root = document.getElement;
if (property in root.style) {
root.classList.add(property.toLowerCase());
return root;
}
root.classList.add("no-" + property.toLowerCase());
return false;
}
如果我們想要檢測某個具體的屬性值是否支持,那就需要把它賦給對應
的屬性,然后再檢查瀏覽器是不是還保存著這個值。很顯然,這個過程會改
變元素的樣式,因此我們需要一個隱藏元素
var dummy = document.createElement("p");
dummy.style.backgroundImage = "linear-gradient(red,tan)";
if (dummy.style.backgroundImage) {
root.classList.add("lineargradients");
} else {
root.classList.add("no-lineargradients");
}
//封裝
function testValue(id, value, property) {
var dummy = document.createElement("p");
dummy.style[property] = value;
if (dummy.style[property]) {
root.classList.add(id);
return true;
}
root.classList.add("no-" + id);
return false;
}
CSS 編碼技巧
-
減少代碼重復:代碼可維護性的最大要素是盡量減少改動時要編輯的部分,當某些值相互依賴時,應該把他們的相互關系用代碼表達出來
1.代碼易維護和代碼量少不可兼得border-width: 10px 10px 10px 0; border-width: 10px; border-left-width: 0; 2. 顏色關鍵字 currentColor 3. 繼承 inherit 可以用在任何 CSS 屬性中,而且它總是綁定到父元素的計算值 .callout { position: relative; } .callout::before { content: ""; position: absolute; top: -0.4em; left: 1em; padding: 0.35em; background: inherit; border: inherit; border-right: 0; border-bottom: 0; transform: rotate(45deg); } /* 行高是字號的1.5倍*/ font-size: 20px; line-height: 1.5;
-
每個媒體查詢都會增加成本, 盡最大努力實現彈性可伸縮的布局,并在媒體查詢的各個斷點區間內指定相應的尺寸
避免不必要的媒體查詢的小建議: 1.使用百分比長度來取代固定長度 2.當你需要在較大分辨率下得到固定寬度時,使用 max-width 而不是 width ,因為它可以適應較小的分辨率,而無需使用媒體查詢 3.不要忘記為替換元素(比如 img 、 object 、 video 、 iframe 等)設 置一個 max-width ,值為 100% 4.background-size: cover,但是帶寬并不是無限的,記住在移動網頁中這么做往往是不明智的 5.當圖片(或其他元素)以行列式進行布局時,讓視口的寬度來決定 列的數量。彈性盒布局(即 Flexbox)或者 display: inline-block 加上常規的文本折行行為,都可以實現這一點。 6.在使用多列文本時,指定column-width(列寬)而不是指定column-count(列數) 這樣它就可以在較小的屏幕上自動顯示為單列布局
-
合理使用簡寫
background: url(tr.png) no-repeat top right / 2em 2em, url(br.png) no-repeat bottom right / 2em 2em, url(bl.png) no-repeat bottom left / 2em 2em; 寫成一個展開式屬性background: url(tr.png) top right, url(br.png) bottom right, url(bl.png) bottom left; background-size: 2em 2em; background-repeat: no-repeat;
-
預處理語言,如果使用得當,它們在大型項目中可以讓代碼更加靈活
1. CSS 的文件體積和復雜度可能會失控。即使是簡潔明了的源代碼, 在經過編譯之后也可能會變成一頭從天而降的巨獸。 2. 調試難度會增加,因為你在開發工具中看到的 CSS 代碼并不是你寫 的源代碼。不過這個問題已經大大好轉了,因為已經有越來越多的 調試工具開始支持 SourceMap。SourceMap 是一種非??岬男录夹g, 正是為了解決這個痛點而生的,它會告訴瀏覽器哪些編譯生成的 CSS 代碼對應哪些預處理器 CSS 代碼,精確到行號。 3. 預處理器在開發過程中引入了一定程度的延時。盡管它們通常很快, 但仍然需要差不多一秒鐘的時間來把你的源代碼編譯成 CSS, 4. 抽象都必然會帶來更高的學習成本 5. “所有重大的抽象機制在某種程度上都存在泄漏的情況?!? 預處理器是由人類寫出來的,就像所有由人類寫出來的大型程序一樣,它們有它們自己的 bug。 這些 bug 可能會潛伏很久,因為我們很少會懷疑預處理器的某個 bug 才是我們CSS 出錯的幕后元兇。
背景和邊框
半透明邊框
CSS 中的半透明顏色 rgba() 和 hsla()
H:Hue(色調)。0(或 360)表示紅色,120 表示綠色,240 表示藍色,也可取其他數值來指定顏色。取值為:0 - 360
S:Saturation(飽和度)。取值為:0.0% - 100.0%
L:Lightness(亮度)。取值為:0.0% - 100.0%
A:Alpha 透明度。取值 0~1 之間。
如果不希望背景侵入邊框所在的范圍,我們要做的就是把它的值設為 padding-box ,這樣瀏覽器就會用內邊距的外沿來把背景裁切掉。
background-clip有三個屬性值,
即border-box、padding-box、content-box;
border-box 背景被裁剪到邊框盒。
padding-box 背景被裁剪到內邊距框。
content-box 背景被裁剪到內容框。
.one {
width: 100px;
height: 100px;
background: red;
border: 15px dashed hsla(214, 50%, 50%, 1);
background-clip: padding-box;
}
background-clip的初始值是 border-box,意味著背景會被元素的border-box(邊框的外沿框)裁切掉
.two {
width: 100px;
height: 100px;
background: red;
border: 15px dashed hsla(214, 50%, 50%, 1);
}
多重邊框
box-shadow 方案 : 只能模擬實線邊框
- 接受第四個參數(稱作“擴張半徑”),通過指定正值或負值,可以讓投影面積加大或者減小
- 你完全可以用 border 屬性來生成完全一樣的邊框效果。不過 box-shadow 的好處在于,它支持逗號分隔語法,我們可以創建任意數量的投影
.one {
width: 100px;
height: 100px;
background: red;
box-shadow: 0 0 0 10px hsla(214, 50%, 50%, 1);
}
.two {
width: 100px;
height: 100px;
background: yellowgreen;
box-shadow: 0 0 0 10px #655, 0 0 0 20px deeppink,
0 2px 5px 25px rgba(0, 0, 0, 0.6);
}
outline 方案 : 可以產生虛線邊框效果
outline 它只適用于雙層“邊框”的場景。在某些情況下,你可能只需要兩層邊框,那就可以先設置一層常規邊框,再加上 outline
(描邊)屬性來產生外層的邊框
.one {
width: 100px;
height: 100px;
background: yellowgreen;
border: 10px solid #655;
outline: 10px solid deeppink;
}
.two {
width: 140px;
height: 140px;
background: yellowgreen;
outline: 2px dashed deeppink;
outline-offset: -10px;
}
注意:通過outline
屬性實現的“邊框”不會貼合元素的圓角,不過這一行為在未來可能會發生變化
.three {
width: 140px;
height: 140px;
background: yellowgreen;
outline: 2px dashed deeppink;
border-radius: 20px;
}
靈活的背景定位
background-position
對于具有固定尺寸的容器來說,使用 CSS 2.1 來做到這一點是可能的,
但很麻煩:可以基于它自身的尺寸以及我們期望它距離右下角的偏移量,計
算出背景圖片距離左上角的偏移量,然后再把計算結果設置給 background-
position,,借助現代的 CSS 特性,我們已經擁有了更好的解決方案
.one {
width: 200px;
height: 200px;
background: url("../logo.jpg") no-repeat #58a;
background-size: 50px 50px;
background-position: right bottom;
}
.two {
width: 200px;
height: 200px;
background: url("../logo.jpg") no-repeat #58a;
background-size: 50px 50px;
background-position: right 50px bottom 50px;
}
兼容性的回退方案:在不支持 background-position 擴展語法的瀏覽器中,背景圖片會緊
貼在左上角(背景圖片的默認位置)
#app {
width: 200px;
height: 200px;
background: url("../img.jpg") no-repeat bottom right #58a; //回退方案
background-position: right 20px bottom 10px;
}
backgroung-origin
在給背景圖片設置距離某個角的偏移量時,有一種情況極其常見:偏移量與容器的內邊距一致。如果采用上面提到的 background-position 的擴展語法方案,代碼看起來會是這樣的
padding: 10px;
background: url(code-pirate.svg) no-repeat #58a;
background-position: right 10px bottom 10px;
上面定義方式的缺點:每次都要改動三個值,所以有一個更簡單的辦法可以實現這個需求:讓它自動地跟著我們設定的內邊距走,不用另外聲明偏移量的值
默認情況下,background-position 是以 padding box 為準的,這樣邊框才不會遮住背景圖片
background-position: top left;
top left 默認指的是 padding box 的左上角,這樣邊框才不會遮住背景圖片
盒模型如下圖
將 backgroung-origin 設置為content-box
,background-position 中使用的邊角關鍵字將會以內容區的邊緣作為基準(也就是說,此時背景圖片距離邊角的偏移量就跟內邊距保持一致了):如下代碼
padding: 10px;
background: url("code-pirate.svg") no-repeat #58a bottom right; /* 或 100% 100% */
background-origin: content-box;
案例展示:
.three {
width: 200px;
height: 200px;
padding: 20px;
background: url("../logo.jpg") no-repeat #58a;
background-size: 50px 50px;
background-position: right 20px bottom 20px;
//padding改動,background-position的偏移量也要改動
}
.four {
width: 200px;
height: 200px;
padding: 20px;
background: url("../logo.jpg") no-repeat #58a;
/* background: url('../logo.jpg') no-repeat #58a right bottom; */
background-size: 50px 50px;
background-position: right bottom;
background-origin: content-box; //設置為以內容區為基準,padding不在影響它
}
calc()方案
以左上角偏移的思路來考慮,其實就是希望它有一個 100% - 20px 的水平偏移量,以及 100% - 10px 的垂直偏移量
width: 200px;
height: 200px;
background: url("../logo.jpg") no-repeat #58a;
background-size: 50px 50px;
background-position: calc(100% - 20px) calc(100% - 10px); //左上角偏移
邊框內圓角
box-shadow, outline, "多重邊框"
一個容器,只在內側有圓角,而邊框或描邊的四個角在外部,仍然保持直角的形狀
.parent {
width: 200px;
height: 60px;
background: #655;
padding: 0.8em;
}
.child {
font-size: 10px;
background: tan;
border-radius: 10px;
padding: 2em;
text-align: center;
}
這個方法很好,但要求我們使用兩個元素,如果我們只需要一個元素呢?
.parent1 {
margin: 100px;
width: 200px;
background: tan;
border-radius: 10px;
padding: 10px;
box-shadow: 0 0 0 10px #655;
outline: 12px solid #655;
}
.parent2 {
margin: 100px;
width: 200px;
background: tan;
border-radius: 10px;
padding: 10px;
box-shadow: 0 0 0 10px #655;
outline: 12px solid red;
}
條紋背景
CSS 線性漸變,background-size
水平條紋
假設我們有一條基本的垂直線性漸變,顏色從 #fb3 過渡到 #58a
<style>
.app {
width: 300px;
height: 300px;
}
.one {
background: linear-gradient(#fb3, #58a);
}
.two {
background: linear-gradient(#fb3 30%, #58a 30%);
background-size: 100% 30px;
}
</style>
<div class="app one"></div>
<div class="app two"></div>
如果我們把第二個色標的位置值設置為 0,那它的位置就總是會被瀏覽器調整為前一個色標的位置值,如果要創建超過兩種顏色的條紋,也是很容易的
<style>
.app {
width: 300px;
height: 300px;
}
.three {
background: linear-gradient(
rgb(0, 183, 255) 33.3%,
yellow 0,
blue 66.6%,
green 0
);
background-size: 100% 60px;
}
</style>
<div class="app three"></div>
垂直條紋
background: linear-gradient(to right, /* 或 90deg */ #fb3 50%, #58a 0);
background-size: 30px 100%;