關於如下內容,咱們假設結構層的變動是不容許的。css
咱們也儘可能不去添加額外的HTML,以作到樣式層與結構層的分離,如若實在沒有其餘的可能性,才退而求其次來增長額外的HTML。html
衆所周知,製做與圓相關的圖形,用到的屬性就要 border-radius
了。咱們知道,border-radius
能夠單獨指定水平和垂直半徑,使用斜槓 (/) 來分開,兩個值相等能夠製做一個圓弧,若是不相等,即是一個橢圓弧了。git
.demo{
border-radius: 100px / 75px;
}
複製代碼
其實border-radius是一個簡寫屬性,咱們有兩種方式能夠爲元素的每一個角指定不一樣的值。github
第一種簡寫方式dom
.demo{
border-radius:10px 20px 30px 40px / 50px 60px 70px 80px;
/* 斜槓(/)前表明水平半徑,後表明垂直半徑,順序分別爲左上角開始,順時針走向,因此這段代碼表示左上角(10px/50px) 右上角(20px/60px)右下角(30px/70px)左下角(40px/80px) */
}
複製代碼
第二種是分開寫的方式svg
.demo{
border-top-left-radius:10px/50px;
border-top-right-radius:20px/60px;
border-bottom-right-radius:30px/70px;
border-bottom-left-radius:40px/80px;
}
複製代碼
若是生成一個自適應的橢圓就很簡單了,只要每一個角的水平半徑爲寬的50%,垂直半徑爲高的50%,就ok了。 代碼簡寫爲:函數
.ellipse{
border-radius:50%;
}
複製代碼
平行四邊形也是頁面中常出現的一種圖形,咱們可能很容易就想到,使用skew()將矩形傾斜必定角度便可。oop
.parallelograms{
transform: skew(-45deg);
/*...... */
}
複製代碼
惋惜效果不如人意,文字也跟着傾斜了,這時候很容易想到,藉助一層dom結構,再把內部文字傾斜回來。post
<div class="parallelograms">
<div>二十首情詩與絕望的歌</div>
</div>
複製代碼
.parallelograms{
margin: 50px auto;
max-width: 200px;
padding: 10px;
line-height: 30px;
text-align: center;
color:#fff;
background-color: #58a;
transform:skew(-45deg);
}
.parallelograms div{
transform: skew(45deg);
}
複製代碼
接下來咱們討論第二種方式,使用 僞元素來實現,這時候就體現了僞元素的好處。 關於僞元素的內容可參考個人另外一邊文章你所不知道的cssui
思路:咱們能夠把僞元素做爲第一種方法中的輔助結構層,把全部樣式(背景、邊框等)應用到僞元素上,而後再對僞元素進行變形,獲得咱們的平行四邊形形狀,而正式內容不受影響,而後把僞元素定位z-index
設爲-1,即可漏出正文的內容。
.parallelograms{
margin: 50px auto;
max-width: 200px;
padding: 10px;
line-height: 30px;
text-align: center;
color:#fff;
position: relative;
}
.parallelograms:before{
content:'';
position: absolute;
left:0;
top:0;
right:0;
bottom:0;
background-color: #58a;
transform:skew(-45deg);
z-index: -1;
}
複製代碼
提醒: 這個技巧不只對 skew()
變形來講頗有用,還適用於其餘任何變形樣式, 當咱們想變形一個元素而不想變形它的內容時就能夠用到它。
看到這個圖形狀,是否是立刻想起上一小節平行四邊形的製做,同樣的道理,須要把圖片用一個
rotate()
變形樣式:
<div class="diamond">
<img src="https://avatars1.githubusercontent.com/u/8121621?v=4" alt="..." />
</div>
複製代碼
.diamond {
margin:30px auto;
width: 100px;
height: 100px;
transform: rotate(45deg);
overflow: hidden;
border: 1px solid red; /*爲了更好的展現問題*/
}
.diamond img {
max-width: 100%;
transform: rotate(-45deg);
}
複製代碼
奈何,天不遂人願!問題在於 max-width:100%
中的100%是指width的100%,也就是400px,而正方形旋轉後最長邊爲對角線,是 根號2倍的width,天然圖片的寬度不夠了,咱們可使用 scale() 變形樣式來把這個圖片放大。找到問題後,咱們修復它,
.diamond {
margin:30px auto;
width: 100px;
height: 100px;
transform: rotate(45deg);
overflow: hidden;
border: 1px solid red; /*爲了更好的展現問題*/
}
.diamond img {
max-width: 100%;
transform: rotate(-45deg) scale(1.42);
}
複製代碼
這個方法須要一層額外的 HTML 標籤,這是咱們不作優先考慮的。同時有一個最大的問題就是,只能處理正方形圖片,不然就會失效。
在上節中咱們使用過僞元素的技巧,一樣能夠用在這裏,代碼以下:
.diamond{
margin:30px auto;
width: 100px;
height: 100px;
overflow: hidden;
position: relative;
transform: rotate(45deg);
}
.diamond:before{
content:'';
position: absolute;
left: 0;
right:0;
top:0;
bottom:0;
transform: rotate(-45deg) scale(1.42);
background: url(https://avatars1.githubusercontent.com/u/8121621?v=4);
background-size: cover;
}
複製代碼
原理與上面藉助結構層是同樣的,因此面臨一樣的問題,只能處理正方形圖片。
接下來咱們使用一種更爲好用的方法來解決不是正方形的圖片。(裁切路徑方案)
.diamond{
/*......*/
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
複製代碼
clip-path
屬性是從svg中借鑑過來的,裁切路徑容許咱們把元素裁剪爲咱們想要的任何形狀。polygon()函數容許咱們用一系列(以逗號分隔的)座標點來指定任意的多邊形。
該方法一樣能夠實現上個章節中的平行四邊形,如下章節中的切角、梯形等等任意形狀,只須要按順序排列座標點便可,如下章節再也不作過多展現,本身能夠多多嘗試。
切角效果,很容易想到的就是個人上篇文章 你該知道的《css揭祕》--背景與邊框篇 中的條紋背景製做中用到的線性漸變 linear-gradient()
咱們很輕易的能夠實現一個角被切掉的效果,代碼以下:
.bevel-corners{
background: #58a; /*linear-gradient不支持的狀況下,做爲代碼回退機制*/
background:linear-gradient(-45deg, transparent 15px, #58a 0);
}
複製代碼
接下來使用兩層漸變背景實現兩個角被切掉。
background-size
讓每層漸變分別只佔據整個元素一半的面積,而且
background-repeat
設爲
no-repeat
。
代碼以下:
.bevel-corners{
background: #58a;
background:
linear-gradient(-45deg, transparent 15px, #58a 0) right,
linear-gradient(45deg, transparent 15px, #58a 0) left;
background-size:50% 100%;
background-repeat:no-repeat;
}
複製代碼
一樣的原理,咱們把每層漸變改成整個元素的四分之一,則四層漸變色,能夠實現四個角被切掉。
.bevel-corners{
background:#58a;
background:
linear-gradient(-45deg,transparent 15px, #58a 0) bottom right,
linear-gradient(45deg,transparent 15px, #58a 0) bottom left,
linear-gradient(135deg,transparent 15px, #58a 0) top left,
linear-gradient(-135deg,transparent 15px, #58a 0) top right;
background-size:50% 50%;
background-repeat:no-repeat;
}
複製代碼
繼續增長難度,實現 弧形切角, 原理都同樣,換湯不換藥,只需將線性漸變改成徑向漸變便可。
.scoop-corners{
background: #58a;
background:
radial-gradient(circle at top left, transparent 15px, #58a 0) top left,
radial-gradient(circle at top right, transparent 15px, #58a 0) top right,
radial-gradient(circle at bottom right, transparent 15px, #58a 0) bottom right,
radial-gradient(circle at bottom left, transparent 15px, #58a 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
}
複製代碼
實現最後一個圖形--餅圖(綠色爲餅圖,棕色來顯示比率)
基於 transform 的解決方案
思路:把圓形的左右兩部分指定爲上述兩種顏色,而後用僞元素覆蓋上去,經過旋轉來 決定露出多大的扇區。
20%的餅圖代碼以下:
.pie {
width: 100px;
height: 100px;
border-radius: 50%;
background: yellowgreen;
background-image:linear-gradient(90deg, transparent 50%, #655 0);
}
.pie:before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
transform: rotate(.2turn);
}
複製代碼
當旋轉超過50%以後,餅圖就變成了下圖這樣,
而後咱們可讓旋轉的僞元素的顏色反一下,變成棕色既能夠實現50%-100%比率的餅圖,
60%的餅圖代碼以下:
.pie:before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: #655;
transform-origin: left;
transform: rotate(.1turn);
}
複製代碼
若是本文有幫到你,不妨給點個贊👍,我會更加有動力創做!