CSS揭秘系列一之"背景和邊框"

工具函數

//獲取和遍歷所有匹配特定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. 減少代碼重復:代碼可維護性的最大要素是盡量減少改動時要編輯的部分,當某些值相互依賴時,應該把他們的相互關系用代碼表達出來

    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. 每個媒體查詢都會增加成本, 盡最大努力實現彈性可伸縮的布局,并在媒體查詢的各個斷點區間內指定相應的尺寸

    
    避免不必要的媒體查詢的小建議:
    
    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(列數)
      這樣它就可以在較小的屏幕上自動顯示為單列布局
    
    
  2. 合理使用簡寫

    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;
    
  3. 預處理語言,如果使用得當,它們在大型項目中可以讓代碼更加靈活

    
    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);
}
image.png

多重邊框

box-shadow 方案 : 只能模擬實線邊框

  1. 接受第四個參數(稱作“擴張半徑”),通過指定正值或負值,可以讓投影面積加大或者減小
  2. 你完全可以用 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);
}
image.png

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;
}
image.png

靈活的背景定位

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;
}
image.png

兼容性的回退方案:在不支持 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 的左上角,這樣邊框才不會遮住背景圖片

盒模型如下圖
image.png

將 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不在影響它
}
image.png

background-origin.gif
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;
}
image.png

這個方法很好,但要求我們使用兩個元素,如果我們只需要一個元素呢?

.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;
}
GIF.gif

條紋背景

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%;
斜向條紋
更好的斜向條紋
靈活的同色系條紋

復雜的背景圖案

偽隨機背景

連續的圖像邊框

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 選擇qi:是表達式 標簽選擇器 類選擇器 屬性選擇器 繼承屬性: color,font,text-align,li...
    love2013閱讀 2,327評論 0 11
  • 一、CSS入門 1、css選擇器 選擇器的作用是“用于確定(選定)要進行樣式設定的標簽(元素)”。 有若干種形式的...
    寵辱不驚丶歲月靜好閱讀 1,616評論 0 6
  • 第一章 F12: element.style 內聯樣式(可以直接在上面寫代碼進行簡單調試) user agent...
    fastwe閱讀 1,527評論 0 0
  • 各種純css圖標 CSS3可以實現很多漂亮的圖形,我收集了32種圖形,在下面列出。直接用CSS3畫出這些圖形,要比...
    劍殘閱讀 9,634評論 0 8
  • 《“四何”詳詢例外》劉友龍,持續原創分享第1267天。 例外指的是當事人做的相對比較好的時候,問題沒有發...
    像花兒一樣綻放_fb06閱讀 177評論 0 0