CSS揭秘筆記(2):背景與邊框

第2章:背景與邊框

1.半透明邊框

  • 背景知識:RGBA/HSLA顏色
    -給一個容器設置白色背景和一道半透明白色邊框,body的背景會從他的半透明框上透上去
background:white;
border: 10px solid hsla(0,0,100%,0.5)
image.png

結果卻不是我們想要的。為什么呢
因為背景色滲透到邊框下的區域了。需要更改一下默認值(默認是border-box)

background:white;
border: 10px solid hsla(0,0,100%,0.5);
background-clip:padding-box;
image.png

2. 多重邊框

  • box-shadow的基本用法

box-shadow方案

box-shadow方案還能接受第四個參數(稱作擴張半徑),通過指定正值或者負值,可以讓投影面積加大或者減少。一個正確的擴展半徑加上倆個為0的偏移量以及0 的模糊值,得到的投影其實就像是一道實線邊框。

background:yellowgreen;
box-shadow:0 0 10px #655;
image.png

另外,他還支持逗號,我們可以創建任何數量的投影。

background:yellowgreen;
box-shadow:0 0 0 10px #655, 0 0 0 15px deeplink;
image.png

唯一需要注意的就是,box-shadow是層層疊加的,第一層投影位于頂層,以此類推。因此你需要按照這個規律來調整擴展半徑。

-注意事項:

  • 1:投影的行為跟邊框不一致,因為他不會影響布局,而且也不會收到box-sizing的影響
  • 2:上述方法創建的假的邊框出現在元素的外圈。他們并不會響應鼠標事件,比如懸停或者點擊。如果這一點非常重要,你可以給box-shadow屬性加上inset關鍵字,來使投影繪制在元素的內圈,請注意,此時你需要增加額外的內邊距來騰出足夠的空隙。

3:outline方案

在某些情況下,你可能只需要兩層邊框,那就可以先設置一層常規邊框,再加上outline(描邊)屬性來產生外層的邊框。這種方式一大優點就是在于邊框樣式十分靈活,不像box-shadow只能模擬實現邊距。(假如我們需要產生虛線邊距效果,box-shadow就沒轍了)如果想得到上圖2-6的效果,代碼可以這樣寫;

background:yellowgreen;
border: 10px solid #655;
outline: 5px solid deeppink;

描邊的另外一個好處就是你可以通過outline-offset屬性來控制他跟元素邊緣之間的間距,這個屬性甚至可以接受負值。


image.png

注意事項:

  • 他只適用于雙層邊框的場景,因為outline并不能接受逗號分割的多個值,如果我們需要獲取更多層的邊框,前一種方案是我們唯一的選擇。
  • 邊框不一定會貼合border-radius屬性產生的圓角,如果此元素是圓角的,他的描邊可能還是直角的(這種行為唄css工作組認為是一個bug,因此未來可能會改為貼合border-radius圓角)
image.png
  • 根據css基本ui特性規范所述,“描邊可以不是矩形”,但如果你想適應這個方法,請切記最好在不同瀏覽器中完整的測試最終效果。

3:靈活的背景定位

1: background-position的擴展語法方案

background-position已經得到擴展,它允許我們指定背景圖片距離任意角的偏移量,只要我們在偏移量前面指定關鍵字。舉個例子,如果想讓背景圖片跟右邊距保持20px的偏移量,同時跟底邊保持10px的偏移量,可以這樣做。

background:url(code-priate.svg) no-repeat #58a;
background-pistion: right 20px bottom 10px;
image.png

但是,在不支持background-position擴展語法的瀏覽器中,背景圖片會緊貼左上角,如圖所示。


image.png

提供一個會退方案,就是把老套的bottom right 定位值寫進background的簡寫屬性中。

background: url(code-private.svg) no-repeat bottom right #58a;
background-position: right 20px bottom 10px;

2:background-origin方案

在給背景圖片設置距離某個角的偏移量時候,有一種情況及其常見:偏移量與容器的內邊距一致,如果采用上面提到的background-position的擴展語法方案,代碼看起來是這樣的:

padding: 10px;
background:url(code-private.svg) no-repeat #58a;
background-position: right 10px bottom 10px;
image.png

這樣就可以看到,他雖然起作用了,但是代碼不夠DRY, 每次改動內邊距的值時,我們都需要在其他三個地方更新這個值。
所以還有一個更簡單的辦法實現這個需求:
題外話---默認情況下,background-position是以padding box 為準的,這樣邊距才不會遮住背景圖片,因此top left 默認指的就是padding box 的左上角。background-position屬性默認值也是padding-box,如果把他的屬性改為content-box,我們在background-postion屬性中使用的邊角關鍵字將會以內容區的邊緣作為基準(也就是說,此時背景圖片距離邊角的偏移量就跟內邊距保持一致了)

padding: 10px;
backgroung: url("code-private.svg") no-repeat #58a bottom right ; /*或100%100%*/
backgroung-origin: content-box;

他的效果同上。另外如果你想讓偏移量與內邊距稍微有些不同,那么可以使用background-origin: content-box的同時,再通過background-position的擴展語法來設置這些額外的偏移量

3: calc()方案

上述問題我們可以通過這個函數輕而易舉的解決:

background:url('code-private.svg') no-repeat;
background-position: calc(100% - 20px) calc(100% - 10px)

注意:兩邊各有一個空白符

4: 邊框內圓角

  • 背景知識: box-shadow, outline“多重邊框”
    要實現如下效果,我們通常用兩個元素來實現


    image.png
image.png

但是我們如果只使用一個元素可以達到嗎?

解決方案

background:tan;
border-radius: .8em;
padding: 1em;
box-shadow: 0 0 0 .6em #655;
outline: .6em solid #655;

5: 條紋背景

  • 背景知識:css線性漸變,background-size
width:100px;
height:100px;
background: linear-gradient(#fb3 40%, #58a 80%);

效果如圖:


image.png

如果兩個距離過近甚至相等,漸變就會越來越小。直至沒有。
例如

width:100px;
height:100px;
background: linear-gradient(#fb3 450%, #58a 50%);
image.png

i因為漸變是一種由代碼生成的圖像,所以我們可以像對待其他背景一樣的方式對待他們,而且還可以通過background-size來調整他的尺寸。

background: linear-gradient(#fb3 50%, #58a 50%);
width: 100px;
height: 100px;
background-size: 100% 20px;

效果如下:


image.png

由于背景方式默認是重復的,所以效果如上圖,如果要創建不等寬的條紋,只需要調整色標的位置值即可。

background: linear-gradient(#fb3 30%, #58a 30%);
width: 100px;
height: 100px;
background-size: 100% 30px;

效果圖如下


image.png

注意:如果某個色標的位置值比整個列表中他之前的色標的位置值都要小,則該色標的位置值將會被設置為它前面所有色標的位置值的最大值。這意味著,如果我們把第二個色標的位置值設置為0,那它的位置就總會被瀏覽器調整為前一個色標的位置值,這個結果正是我們想要的。

background: linear-gradient(#fb3 30%, #58a 0);
width: 100px;
height: 100px;
background-size: 100% 30px;

效果如圖:


image.png

如果要創建超過兩種的條紋也是很容易的舉例子

background: linear-gradient(#fb3 30%, #58a 0, #58a 66.6%, yellow 0);
width: 100px;
height: 100px;
background-size: 100% 30px;

如圖:


image.png

垂直條紋

和水平條紋代碼基本一致,差別在于我們需要在開頭添加一個額外參數來指定漸變的方向。

background: linear-gradient(to right, #fb3 30%, #58a 0, #58a 66.6%, yellow 0);
width: 100px;
height: 100px;
background-size: 30px 100%;

效果如下:


image.png

斜向條紋

 background: linear-gradient(45deg, #fb3 30%, #58a 0, #58a 66.6%, yellow 0);
 width: 100px;
 height: 100px;
 background-size: 30px 30px;

結果如圖,并不是我們想要的效果:


image.png

為什么,因為背景是重復的,相當于我們把每一個貼片的內部漸變旋轉了45度,而不是把整個重復的背景都旋轉了。
思考一下,一個小貼片中包含了四種顏色,如下圖


image.png

只有這樣才能做到無縫貼合。
因此代碼需要更改為如下代碼:
    background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
    width: 100px;
    height: 100px;
    background-size: 30px 30px;

如圖:


image.png

根據勾股定理,如果想要產生等寬的漸變效果,需要做如下計算


image.png

image.png
    background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
    width: 100px;
    height: 100px;
    background-size: 42.42px 42.42px;
image.png

更好的斜向條紋

image.png

做一個對比,上述斜條紋可以通過如下代碼進行實現

    width: 100px;
    height: 100px;
    background-size: 42.42px 42.42px;
    background: repeating-linear-gradient(45deg, #fb3 0, #fb3 14px, #58a 0, #58a 28px)

效果如下:


image.png

這種方式的好處就是修改顏色時候只需要修改兩處而不是原來的三處,最大的好處就是可以隨意指定角度了。需要注意的是,這里在創建雙條紋時候,仍然需要指定四個色標值,意味著我們最好用前面的方法實現水平或者垂直條紋,而用這種方式來實現斜條紋。

靈活的同色系條紋

日常應用中,我們想要的條紋圖案并不是由差異極大的幾種顏色組成的,這些顏色往往屬于同一個色系。只是在明度方面有著輕微的差異,這樣在實際應用中對于這樣的案例,可以通過代碼體現出主色調和副色調之間的關系還可以在修改時候只用修改一處。代碼如下

    width: 100px;
    height: 100px;
    background-size: 42.42px 42.42px;
    background: #58a;
    background-image: repeating-linear-gradient(30deg, hsla(0, 0%, 100%, 0.1), hsla(0, 0%, 100%, 0.1) 14px, transparent 0, transparent 28px)

效果如下圖:


image.png

6:復雜的背景圖案,

  • 漸變知識:css漸變,條紋背景

7:偽隨機背景

8:連續的圖像邊框

9:自適應的橢圓

border-radius是用空格分開多個值,四個值是從左上角開始以順時針順序應用到元素的各個拐角。另外他也提供了完全不同的水平和垂直半徑。通過斜扛 / 來區分的。

四分之一橢圓

  • 無非就是一個角的水平和垂直半徑都需要是100%,而其他三個角都不能設置為圓角。
border-radius: 100% 0 0 0 ;

10平行四邊形

-背景知識:基本的CSS變形

    margin: 0 auto;
    width: 200px;
    height: 200px;
    background: #58a;
    transform: skewX(45deg)

注意:這個屬性對屬性為行內的元素是不生效的,所以最好更改為其他的屬性


image.png

你會發現,文本內容也發生變化了,顯然這是我們不想要的,解決方法如下

1. 嵌套元素方案

  • 我們可以對容器在進行一次反向的skew變形,從而抵消容器的變形效果。

2. 偽元素方案

另一種思路就是把所有的樣式(背景,邊框等)應用到偽元素上面,然后在對偽元素進行變形

  .btn {
    position: relative;
    background: none;
    border: none;
  }
  .btn::before {
    content: '';
    position: absolute;
    background: #58a;
    transform: skewX(45deg);
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: -1;
  }

這個思路適用于其他任何樣式,當我們想變形一個元素而不變形他的內容的時候就可以用到他。

11 菱形圖片

基于變形的方案

<div class="outer">
   <div class="inner">菱形文本</div>
</div>
 .outer {
    margin: 100px auto;
    width: 100px;
    height: 100px;
    border: 1px solid green;
    transform: rotate(45deg);
    overflow: hidden;
  }

  .inner {
    max-width: 100%;
    height: 100%;
    background: gray;
    transform: rotate(-45deg);
    line-height: 100px;
    text-align: center;
  }

效果如圖:


image.png

但是我們想讓圖片的寬度于外框對角線的長度相等,而不是與邊長相等。這里又要用到勾股定理了。邊長 * 1.414。如果用sale放大1.414倍會更改合理,因為寬度變寬是以左上角為中心點,而scale等默認是以中心點進行縮放的,前者需要在變換位移,后者不用,所以代碼改為如此,

 .outer {
    margin: 100px auto;
    width: 100px;
    height: 100px;
    border: 1px solid green;
    transform: rotate(45deg);
    overflow: hidden;
  }

  .inner {
    max-width: 100%;
    height: 100%;
    background: gray;
    transform: rotate(-45deg) scale(1.42);
    line-height: 100px;
    text-align: center;
  }

效果如下:


image.png

裁切路徑方案

上述方法對圖片寬高有要求,假如圖片不符合要求,上述方案就會出現bug,可見這種方式是由一種hack處理方式------------不夠簡潔,不夠直觀,也不夠健壯。
clip-path: polygon(...) // 多邊形

<img class="img" src="https://upload.jianshu.io/admin_banners/web_images/4609/5c252cdb56c9924a035c052cf56753f096a1d6e8.jpg"
      alt="">
.img {
    width: 200px;
    height: 200px;
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%)
  }

效果如圖:


image.png

還可以參與動畫實現

  .img {
    width: 200px;
    height: 200px;
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
    transition: 1s clip-path;
  }
  .img:hover {
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%)
  }

12. 切角效果

解決方案

  1. css背景漸變
 .third {
    width: 100px;
    height: 100px;
    background: #58a;
    background: linear-gradient(-45deg, transparent 15px, #58a 0);
    margin: 0 auto;
  }

效果如圖:


image.png

如果想要兩個角被切掉的效果,最初的想法是這樣的

 .third {
    width: 100px;
    height: 100px;
    background: #58a;
    background: linear-gradient(-45deg, transparent 15px, #58a 0), linear-gradient(45deg transparent 15px, #655, 0);
    margin: 0 auto;
  }

發現行不通,原因:默認情況下,這兩層漸變都會調填滿整個元素,因此他們會相互覆蓋。需要讓他們都縮小一半,于時我們用background-size來讓每個漸變只占元素背景的一般

弧形切角

13 梯形標簽頁

生成梯形

.thirteen {
    transform: perspective(.5rem) rotateX(5deg);
    width: 100px;
    height: 100px;
    margin: 0 auto;
    background: #58a;
  }

效果如下


image.png

由于這里我們是對整個元素進行3d變形的,因此上面的文字也是變形的。并且對元素采用3d變形以后,元素的內部變形是“不可逆轉”的。所以我們可以采用利用偽類的方式來實現生成梯形。有些類似于上面的平行四邊形。

.thirteen {
    position: relative;
    color: white;
    padding: 0.5em 1em .35em;
    display: inline-block;
  }

  .thirteen::before {
    content: '';
    background: #58a;
    top: 0;
    right: 0;
    left: 0;
    bottom: 0;
    z-index: -1;
    position: absolute;
    transform: perspective(.5rem) rotateX(5deg);
  }

效果如圖


image.png

這樣可以實現,但是有一個問題,如果我們沒有設置transform-origin的屬性時候,應用變形效果會讓這個元素以自身的中心線為軸進行空間上的旋轉。因此,元素投射到2d屏幕上的尺寸會發生多種變化。
。。。。

14簡單的餅圖

1:基于transform的解決方案

  • 這個方案在結構上是最佳解決方法:它只需要一個元素作為選擇器,而其他部分由偽元素/變形元素/和css漸變來實現。




?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容

  • 所有圖都在body背景設置為green下的截圖,請不要把最外層的綠色當成邊框 半透明邊框 如果我們想給一個容器設置...
    hcxowe閱讀 3,980評論 0 6
  • 我還記得國外某位大牛在一篇文章中寫道,CSS is fine, it's just really hard。讀完他...
    garble閱讀 1,102評論 0 0
  • css3圖案庫:http://lea.verou.me/css3patterns/http://bennettfe...
    noyanse閱讀 361評論 0 0
  • 半透明邊框 RGBA/HSLA顏色H:Hue(色調)。0(或360)表示紅色,120表示綠色,240表示藍色,也可...
    牛牛_lz閱讀 403評論 0 1
  • 選擇qi:是表達式 標簽選擇器 類選擇器 屬性選擇器 繼承屬性: color,font,text-align,li...
    love2013閱讀 2,325評論 0 11