自适应的椭圆

可以使用border-radius将矩形元素设置成圆形

  • 完整椭圆

    border-radius可以单独指定水平半径和垂直半径,通过/分隔

    1
    2
    3
    4
    div {
    background: rgb(241, 176, 56);
    border-radius: 60px/20px;
    }

    要想形成一个完整的椭圆,可以取长宽的一半作为长短半径,如果想生成自适应的椭圆,可以使用百分比

    1
    2
    3
    4
    div {
    background: rgb(241, 176, 56);
    border-radius: 50%;
    }
  • 半椭圆

    border-radius是一个简写属性,包含:

    1. border-top-left-radius

    2. border-top-right-radius

    3. border-bottom-right-radius

    4. border-bottom-left-radius

    可以一次性向border-radius传递多个值

    1. 如果传递四个值,四个值会分别从左上角开始以顺时针顺序分配到各个角

    2. 如果传递三个值,则依次分配给左上角、右上+左下、左下

    3. 如果传递两个值,则依次分配给左上+右下、右上+左下

    也可以为四个角赋予不同的水平半径和垂直半径,用/分隔

    1
    2
    3
    4
    div {
    background: rgb(241, 176, 56);
    border-radius: 100% 0 0 100% / 50%;
    }
    1
    2
    3
    4
    div {
    background: rgb(241, 176, 56);
    border-radius: 50% / 100% 100% 0 0;
    }
  • 四分之一椭圆

    1
    2
    3
    4
    div {
    background: rgb(241, 176, 56);
    border-radius: 100% 0 0 0;
    }

平行四边形

通过skew()可以对矩形进行拉伸

parallelogram
1
2
3
div {
transform: skewX(-20deg);
}

这会导致div中的内容也会发生变形,解决方案有两种

  • 嵌套元素方案

    可以对内容进行一次反向的skew()变形

    1
    2
    3
    <div class="out">
    <span class="in">parallelogram</span>
    </div>
    1
    2
    3
    4
    5
    6
    7
    .out {
    transform: skewX(-20deg);
    }
    .in {
    display: inline-block;
    transform: skew(20deg);
    }
    parallelogram
  • 伪元素方案

    把所有样式应用到伪元素上,对伪元素进行变形

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    .parallelogram-pseudo {
    position: relative;
    width: 60%;
    height: 100px;
    text-align: center;
    font-size: 30px;
    line-height: 100px;
    }
    .parallelogram-pseudo::before {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: -1;
    background: rgb(241, 176, 56);
    transform: skew(-20deg);
    }
    parallelogram

菱形图片

  • 基于变形的方案

    对于正方形图案,可以使用这种方案:将图片用div包裹,div旋转,内部图片反向旋转

    1
    2
    3
    <div class="pic">
    <img src="http://csssecrets.io/images/adamcatlace.jpg">
    </div>
    1
    2
    3
    4
    5
    6
    7
    8
    9
    .pic {
    width: 400px;
    transform: rotate(45deg);
    overflow: hidden;
    }
    .pic > img {
    max-width: 100%;
    transform: rotate(-45deg);
    }

    使用scale(1.45)将旋转后的图片放大可以避免形成八边形

  • 裁剪路径方案

    使用clip-path属性裁剪元素

    1
    <img src="http://csssecrets.io/images/adamcatlace.jpg">
    1
    2
    3
    4
    img {
    -webkit-clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
    }

切角效果

渐变方案

可以以45deg位方向做线性渐变

1
2
3
div {
background: linear-gradient(45deg, transparent 30px, #69b 0)
}

切掉两个角:

1
2
3
4
5
6
div {
background: linear-gradient(-135deg, transparent 42.43px, #69b 0) top,
linear-gradient(-45deg, transparent 42.43px, #69b 0) bottom;
background-size: 100% 50%;
background-repeat: no-repeat;
}

切掉四个角:

1
2
3
4
5
6
7
8
div {
background: linear-gradient(135deg, transparent 20px, #69b 0) top left,
linear-gradient(-135deg, transparent 20px, #69b 0) top right,
linear-gradient(-45deg, transparent 20px, #69b 0) bottom right,
linear-gradient(45deg, transparent 20px, #69b 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
}

内凹圆角:

1
2
3
4
5
6
7
8
div {
background: radial-gradient(circle at top left, transparent 20px, #69b 0) top left,
radial-gradient(circle at top right, transparent 20px, #69b 0) top right,
radial-gradient(circle at bottom right, transparent 20px, #69b 0) bottom right,
radial-gradient(circle at bottom left, transparent 20px, #69b 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
}

裁剪路径方案

可以使用clip-path属性裁剪出切角

1
2
3
4
5
6
7
div {
background: #58a;
-webkit-clip-path: polygon(0 20px, 20px 0, calc(100% - 20px) 0, 100% 20px,
100% calc(100% - 20px), calc(100% - 20px) 100%, 20px 100%, 0 calc(100% - 20px));
clip-path: polygon(0 20px, 20px 0, calc(100% - 20px) 0, 100% 20px,
100% calc(100% - 20px), calc(100% - 20px) 100%, 20px 100%, 0 calc(100% - 20px));
}

梯形标签页

由于透视的关系,通过将矩形旋转可以形成梯形,需要设置transform-origin固定底边,设置scaleY补足高度

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
div {
position: relative;
}
div::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
background: #58a;
transform: scaleY(1.3) perspective(.5em) rotateX(2deg);
transform-origin: bottom;
}
Trapezoid

在Safari浏览器中3D transform变换可能会导致z-index渲染异常,解决办法见《Safari中transform3D变换导致的z-index异常》

一种梯形导航栏的写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<div class="my-nav">
<nav class="both-side">
<a href="#">Home</a>
<a href="#" class="selected">Projects</a>
<a href="#">About</a>
</nav>
<main>Content area</main>
<nav class="left">
<a href="#">Home</a>
<a href="#" class="selected">Projects</a>
<a href="#">About</a>
</nav>
<main>Content area</main>
<nav class="right">
<a href="#">Home</a>
<a href="#" class="selected">Projects</a>
<a href="#">About</a>
</nav>
<main>Content area</main>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
.my-nav {
padding: 40px;
font: 130%/2 Frutiger LT Std, sans-serif;
}
nav {
position: relative;
z-index: 1;
padding-left: 1em;
}
nav > a {
position: relative;
display: inline-block;
padding: .3em 1em 0;
color: inherit;
text-decoration: none;
margin: 0 -.3em;
}
nav a::before {
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
z-index: -1;
border-radius: .5em .5em 0 0;
background: #ccc linear-gradient(hsla(0, 0%, 100%, .6), hsla(0, 0%, 100%, 0));
box-shadow: 0 .15em white inset;
transform: scale(1.1, 1.3) perspective(.5em) rotateX(5deg);
transform-origin: bottom;
}
nav a.selected {
z-index: 2;
}
nav a.selected::before {
border-bottom: .1em solid #eee;
background-color: #eee;
margin-bottom: -.08em;
}
main {
display: block;
margin-bottom: 1em;
background: #eee;
padding: 1em;
border-radius: .15em;
}
nav.left > a::before {
transform: scale(1.2, 1.3) perspective(.5em) rotateX(5deg);
transform-origin: bottom left;
}
nav.right {
padding-left: 2em;
}
nav.right > a::before {
transform: scale(1.2, 1.3) perspective(.5em) rotateX(5deg);
transform-origin: bottom right;
}
Content area
Content area
Content area