1. 程式人生 > 實用技巧 >CSS案例:實現書頁任意折角效果

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);

        }