CSS案例:實現書頁任意折角效果
書頁任意角度折角效果示意圖
<div class='note'> 歡迎來到二狗哥的部落格,HTML、CSS、JavaScript等前端程式碼研究,你我共勉! </div>
程式碼程式設計要求:
1、折線與上邊緣構成角度為30°;2、背景顏色色標#6d98bd,折角部分色標#577b98;3、為增加逼真效果,需要為折角新增陰影;4、折角不能遮蓋內容文字部分;
書頁任意角度折角效果分解為兩個步驟:(1)繪製滿足要求的特定三角形;(2)將三角形位置設定為指定座標地點。
構建數學模型進行分析:
矩形ABCD代表主體元素(.note),三角形EFB1代表折角元素,並且三角形EFB1與三角形EBF關於EF軸對稱。
實現思路:主體採用相對定位,翻折部分用偽元素通過絕對定位來實現。主體元素(.note)的背景翻折部分(虛線三角形),通過線性漸變顏色顯示剪去翻折部分。
上面是數學模型的區域性放大圖,採用背景線性漸變來剪去目標三角形,剪去部分為透明色(transparent)。重點是確定達到指定線性漸變的漸變角度以及色標長度值。根據W3C中線性漸變漸變線的定義,想要EF為分界線,漸變角度為210°,透明色漸變長度等於線段BH長度值(BH與EF互相垂直)。
根據幾何圖形對稱軸的特性有:
EB=EB1
FB=FB1
根據直角三角形的關係,我們可以得出:
BE=√3 BF
EB長度等於偽元素的高度y,BF長度等於偽元素的寬度x。若是網頁設計時,相關圓角和尺寸都會由設計時進行確定,有比較詳細的標註。這裡採用圓角邊框半徑用5px,透明色標長度18px效果比較理想。考慮程式碼的後期維護性,轉換為相對單位em。主元素的CSS程式碼如下:
.note { font-size: 12px; color: rgb(199, 197, 197); width: 200px; height: 100px; padding: 20px; border-radius: .4166em; /* 5px */ position: relative; background: #6d98bd; /* 回退機制 */ background: linear-gradient(210deg, transparent 1.5em, #6d98bd 0); }
對於目標三角形來說,由於透明色色標已經確定,它的長度和高度與BH關聯確定。根據三角函式,可知:高度值y=2BH=3em,寬度值x= 2BH/√3代入數值計算,值約為:1.732em。
.note::before { content: ''; display: block; width: 1.73em; height: 3em; }
偽元素顯示為直角三角形,同樣通過線性漸變來實現。線性漸變色標分界線為對角線,根據線性漸變定義,可以知道透明色色標色標值為漸變線長度的50%。
background: linear-gradient(60deg, #577b98 50%, transparent 0);
這樣初步實現了折角部分效果,下面重點是進行定位。預設的偽元素(.note::before)為主元素(.note)的第一個子元素,位於其內容盒中的左上角。目標位置靠近右上角,並需要經過一定的旋轉實現。
偽元素位於主元素右上角後,需要上移FL距離,然後以F點為旋轉點,旋轉60°,即達到目標位置。FL=y-x=1.27em。
絕對定位與位置轉換:
position: absolute; right: 0; top: 0; transform: translateY(-1.27em) rotate(-30deg); transform-origin: bottom right;
左下角圓弧:
border-bottom-left-radius: inherit;
最後增加陰影效果,讓折角更加逼真:
box-shadow: -.2em .2em .3em -.1em rgba(0, 0, 0, .15);
完整的程式碼:
.note { font-size: 12px; color: rgb(199, 197, 197); width: 200px; height: 100px; padding: 20px; border-radius: .4166em; /* 5px */ position: relative; background: #6d98bd; /* 回退機制 */ background: linear-gradient(210deg, transparent 1.5em, #6d98bd 0); } .note::before { content: ''; display: block; width: 1.73em; height: 3em; position: absolute; background: linear-gradient(60deg, #577b98 50%, transparent 0); right: 0; top: 0; border-bottom-left-radius: inherit; transform: translateY(-1.27em) rotate(-30deg); transform-origin: bottom right; box-shadow: -.2em .2em .3em -.1em rgba(0, 0, 0, .15); }