第2章:背景與邊框
1.半透明邊框
- 背景知識:RGBA/HSLA顏色
-給一個容器設置白色背景和一道半透明白色邊框,body的背景會從他的半透明框上透上去
background:white;
border: 10px solid hsla(0,0,100%,0.5)
結果卻不是我們想要的。為什么呢
因為背景色滲透到邊框下的區域了。需要更改一下默認值(默認是border-box)
background:white;
border: 10px solid hsla(0,0,100%,0.5);
background-clip:padding-box;
2. 多重邊框
- box-shadow的基本用法
box-shadow方案
box-shadow方案還能接受第四個參數(稱作擴張半徑),通過指定正值或者負值,可以讓投影面積加大或者減少。一個正確的擴展半徑加上倆個為0的偏移量以及0 的模糊值,得到的投影其實就像是一道實線邊框。
background:yellowgreen;
box-shadow:0 0 10px #655;
另外,他還支持逗號,我們可以創建任何數量的投影。
background:yellowgreen;
box-shadow:0 0 0 10px #655, 0 0 0 15px deeplink;
唯一需要注意的就是,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屬性來控制他跟元素邊緣之間的間距,這個屬性甚至可以接受負值。
注意事項:
- 他只適用于雙層邊框的場景,因為outline并不能接受逗號分割的多個值,如果我們需要獲取更多層的邊框,前一種方案是我們唯一的選擇。
- 邊框不一定會貼合border-radius屬性產生的圓角,如果此元素是圓角的,他的描邊可能還是直角的(這種行為唄css工作組認為是一個bug,因此未來可能會改為貼合border-radius圓角)
- 根據css基本ui特性規范所述,“描邊可以不是矩形”,但如果你想適應這個方法,請切記最好在不同瀏覽器中完整的測試最終效果。
3:靈活的背景定位
1: background-position的擴展語法方案
background-position已經得到擴展,它允許我們指定背景圖片距離任意角的偏移量,只要我們在偏移量前面指定關鍵字。舉個例子,如果想讓背景圖片跟右邊距保持20px的偏移量,同時跟底邊保持10px的偏移量,可以這樣做。
background:url(code-priate.svg) no-repeat #58a;
background-pistion: right 20px bottom 10px;
但是,在不支持background-position擴展語法的瀏覽器中,背景圖片會緊貼左上角,如圖所示。
提供一個會退方案,就是把老套的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;
這樣就可以看到,他雖然起作用了,但是代碼不夠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
但是我們如果只使用一個元素可以達到嗎?
解決方案
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%);
效果如圖:
如果兩個距離過近甚至相等,漸變就會越來越小。直至沒有。
例如
width:100px;
height:100px;
background: linear-gradient(#fb3 450%, #58a 50%);
i因為漸變是一種由代碼生成的圖像,所以我們可以像對待其他背景一樣的方式對待他們,而且還可以通過background-size來調整他的尺寸。
background: linear-gradient(#fb3 50%, #58a 50%);
width: 100px;
height: 100px;
background-size: 100% 20px;
效果如下:
由于背景方式默認是重復的,所以效果如上圖,如果要創建不等寬的條紋,只需要調整色標的位置值即可。
background: linear-gradient(#fb3 30%, #58a 30%);
width: 100px;
height: 100px;
background-size: 100% 30px;
效果圖如下
注意:如果某個色標的位置值比整個列表中他之前的色標的位置值都要小,則該色標的位置值將會被設置為它前面所有色標的位置值的最大值。這意味著,如果我們把第二個色標的位置值設置為0,那它的位置就總會被瀏覽器調整為前一個色標的位置值,這個結果正是我們想要的。
background: linear-gradient(#fb3 30%, #58a 0);
width: 100px;
height: 100px;
background-size: 100% 30px;
效果如圖:
如果要創建超過兩種的條紋也是很容易的舉例子
background: linear-gradient(#fb3 30%, #58a 0, #58a 66.6%, yellow 0);
width: 100px;
height: 100px;
background-size: 100% 30px;
如圖:
垂直條紋
和水平條紋代碼基本一致,差別在于我們需要在開頭添加一個額外參數來指定漸變的方向。
background: linear-gradient(to right, #fb3 30%, #58a 0, #58a 66.6%, yellow 0);
width: 100px;
height: 100px;
background-size: 30px 100%;
效果如下:
斜向條紋
background: linear-gradient(45deg, #fb3 30%, #58a 0, #58a 66.6%, yellow 0);
width: 100px;
height: 100px;
background-size: 30px 30px;
結果如圖,并不是我們想要的效果:
為什么,因為背景是重復的,相當于我們把每一個貼片的內部漸變旋轉了45度,而不是把整個重復的背景都旋轉了。
思考一下,一個小貼片中包含了四種顏色,如下圖
只有這樣才能做到無縫貼合。
因此代碼需要更改為如下代碼:
background: linear-gradient(45deg, #fb3 25%, #58a 0, #58a 50%, #fb3 0, #fb3 75%, #58a 0);
width: 100px;
height: 100px;
background-size: 30px 30px;
如圖:
根據勾股定理,如果想要產生等寬的漸變效果,需要做如下計算
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;
更好的斜向條紋
做一個對比,上述斜條紋可以通過如下代碼進行實現
width: 100px;
height: 100px;
background-size: 42.42px 42.42px;
background: repeating-linear-gradient(45deg, #fb3 0, #fb3 14px, #58a 0, #58a 28px)
效果如下:
這種方式的好處就是修改顏色時候只需要修改兩處而不是原來的三處,最大的好處就是可以隨意指定角度了。需要注意的是,這里在創建雙條紋時候,仍然需要指定四個色標值,意味著我們最好用前面的方法實現水平或者垂直條紋,而用這種方式來實現斜條紋。
靈活的同色系條紋
日常應用中,我們想要的條紋圖案并不是由差異極大的幾種顏色組成的,這些顏色往往屬于同一個色系。只是在明度方面有著輕微的差異,這樣在實際應用中對于這樣的案例,可以通過代碼體現出主色調和副色調之間的關系還可以在修改時候只用修改一處。代碼如下
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)
效果如下圖:
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)
注意:這個屬性對屬性為行內的元素是不生效的,所以最好更改為其他的屬性
你會發現,文本內容也發生變化了,顯然這是我們不想要的,解決方法如下
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;
}
效果如圖:
但是我們想讓圖片的寬度于外框對角線的長度相等,而不是與邊長相等。這里又要用到勾股定理了。邊長 * 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;
}
效果如下:
裁切路徑方案
上述方法對圖片寬高有要求,假如圖片不符合要求,上述方案就會出現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%)
}
效果如圖:
還可以參與動畫實現
.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. 切角效果
解決方案
- css背景漸變
.third {
width: 100px;
height: 100px;
background: #58a;
background: linear-gradient(-45deg, transparent 15px, #58a 0);
margin: 0 auto;
}
效果如圖:
如果想要兩個角被切掉的效果,最初的想法是這樣的
.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;
}
效果如下
由于這里我們是對整個元素進行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);
}
效果如圖
這樣可以實現,但是有一個問題,如果我們沒有設置transform-origin的屬性時候,應用變形效果會讓這個元素以自身的中心線為軸進行空間上的旋轉。因此,元素投射到2d屏幕上的尺寸會發生多種變化。
。。。。
14簡單的餅圖
1:基于transform的解決方案
- 這個方案在結構上是最佳解決方法:它只需要一個元素作為選擇器,而其他部分由偽元素/變形元素/和css漸變來實現。