引入:border-radius
border-radius可以单独指定水平和垂直半径,只要用一个斜杠(/)分隔这两个值即可。这个特性允许我们在拐角处创建椭圆圆角:
border-radius: 100px / 75px;
两组值会展开为四个值的:
border-radius: 10px / 5px 20px;
/*相当于*/
border-radius: 10px 10px 10px 10px / 5px 20px 5px 20px
1 自适应的椭圆
根据其内容自动调整并适应。如果它的宽高相等,就显示为一个圆;如果宽高不等,就显示为一个椭圆:
border-radius: 50%;
2 半椭圆
上半椭圆
border-radius: 50% / 100% 100% 0 0;
左半椭圆
border-radius: 100% 0 0 100% / 50%;
3 四分之一椭圆
其中一个角的水平和垂直半径值都需要是100%,而其他三个角都不能设为圆角:
border-radius: 100% 0 0 0;
border-radius优秀示例:https://simurai.com/archive/buttons/#flexibility
4 平行四边形
说到四边形,我们可能会想到用下面的办法创建:
transform: skewX(-45deg);
然而上面的写法会导致它的内容也发生了斜向变形。下面有几种方法让内容不倾斜:
方法一:嵌套元素
对内容再应用一次反向的 skew() 变形,从而抵消容器的变形效果:
<div class="example">
<div>平行四边形</div>
</div>
.example{
transform: skewX(-45deg);
}
.example>div{
transform: skewX(45deg);
}
方法二:伪元素
另一种思路是把所有样式(背景、边框等)应用到伪元素上,然后再对伪元素进行变形。
给宿主元素应用 position: relative 样式,并为伪元素设置 position:
absolute,然后再把所有偏移量设置为零,以便让它在水平和垂直方向上都
被拉伸至宿主元素的尺寸。此时,用伪元素生成的方块是重叠在内容之上的,可设置z-index: -1 样式避免覆盖:
.example{
position: relative;
}
.example::before{
content: '';
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
z-index: -1;
background: orange;
transform: skew(-45deg);
}
5 菱形图片
方法一:基本变形
<div class="example">
<img src="https://z3.ax1x.com/2021/04/19/cTN9C8.jpg"/>
</div>
.example{
width: 400px;
transform: rotate(45deg); //容器旋转
overflow: hidden;
}
.example > img {
max-width: 100%;
transform: rotate(-45deg) scale(2.2); //图片旋转 适当放大填补空白
}
方法二:截取路径
使用 clip-path 属性。它最大的缺陷在于其浏览器支持程度还很有限。这个例子使用 polygon()
(多边形)函数来指定一个菱形,直接给image元素添加该样式即可:
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
这个属性甚至可以参与动画,只要我们的动画是在同一种形状函数(比如这里是 polygon())之间进行的,而且点的数量是相同的。下面的动画效果是,图片在鼠标悬停时平滑地
扩展为完整的面积:
.example{
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
transition: 1s clip-path;
}
.example:hover {
clip-path: polygon(0 0, 100% 0,
100% 100%, 0 100%);
}
clip-path属性文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/clip-path
6 切角效果
方法一:渐变
需要把一个透明色标放在切角处,然后在相同位置设置另一个色标,并且把它的颜色设置为我们想要的背景色:
background:linear-gradient(-45deg, transparent 15px, orange 0);
如果要设置两个切角呢?
background:
linear-gradient(-45deg, transparent 15px, orange 0),
linear-gradient(45deg, transparent 15px, orange 0);
/*上面的情况,这两层渐变会默认填满整个元素,因此它们会相互覆盖。
使用 background-size 让每层渐变分别只占据整个元素一半的面积:*/
background:
linear-gradient(-45deg, transparent 15px, #58a 0) right,
linear-gradient(45deg, transparent 15px, #655 0) left;
background-size: 50% 100%;
background-repeat: no-repeat;
四个切角
background:
linear-gradient(135deg, transparent 15px, orange 0) top left,
linear-gradient(-135deg, transparent 15px, orange 0) top right,
linear-gradient(-45deg, transparent 15px,orange 0) bottom right,
linear-gradient(45deg, transparent 15px, orange 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
linear-gradient属性文档:https://developer.mozilla.org/zh-CN/docs/Web/CSS/linear-gradient()
弧形切角
与上方切角的区别是:这里是用径向渐变来替代上述线性渐变:
background:
radial-gradient(circle at top left,transparent 15px, orange 0) top left,
radial-gradient(circle at top right,transparent 15px, orange 0) top right,
radial-gradient(circle at bottom right,transparent 15px, orange 0) bottom right,
radial-gradient(circle at bottom left,transparent 15px, orange 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
方法二:内联 SVG 与 border-image
通过渐变实现时,代码会比较冗长,且更改属性时需要更改多处。
border: 17px solid transparent;
border-image: 1 url('data:image/svg+xml,\
<svg xmlns="http://www.w3.org/2000/svg" width="3" height="3" fill="orange">\
<polygon points="0,1 1,0 2,0 3,1 3,2 2,3 1,3 0,2"/>\
</svg>');
background:orange;
background-clip: padding-box;
- 使用的切片尺寸是 1,这并不表示 1 像素,它所对应的是SVG 文件的坐标系统(因此不需要单位)
- fill关键词添加背景色,
- 由于边框已设置成透明色,所以加上background-clip让背景不去绘制边框(border)
方法三:裁切路径
方法二有个局限:只能指定某个实色的背景或一个边缘接近某个实色的背景图案。如果我们想设置其他类型的背景呢(比如纹理、平铺图案或一道线性渐变)
background: orange;
clip-path: polygon(
20px 0, calc(100% - 20px) 0, 100% 20px,
100% calc(100% - 20px), calc(100% - 20px) 100%,
20px 100%, 0 calc(100% - 20px), 0 20px
);
- 好处:可以使用任意类型的背景,甚至可以对替换元素(比如图片)进行裁切。
- 坏处:如果要改动切角的尺寸,我们需要修改八处;当内边距不够宽时,它会裁切掉文本。
未来
CSS 背景与边框(第四版)(http://dev.w3.org/csswg/css-backgrounds-4/)将引入一个全新的属性 corner-shape,可以彻底解决这个痛点。这个属性需要跟 border-radius 配合使用,从而产生各种不同形状的切角效果,而切角的尺寸正是 border-radius 的值。举例来说,为容器的四个角指定 15px 的斜面切角就是如此简单:
border-radius: 15px;
corner-shape: bevel;
7 梯形标签页
通过3D旋转模拟
.example17{
background: orange;
transform:perspective(.5em) rotateX(2deg)
}
由于单纯给一个元素加上3D效果,文字也会出现扭曲。那么就通过加伪元素来解决:
.example17{
position:relative;
display:block;
}
.example17::before{
content:"";
position:absolute;
top:0;right:0;bottom:0;left:0;
z-index:-1;
background: orange;
transform:perspective(.5em) rotateX(2deg) scaleY(1.3);
transform-origin:bottom;
}
变形是以它自身的中心线为轴进行旋转的,所以要加上
transform-origin:bottom
方便控制;而scaleY(1.3)
可以伸长高度,保持它原有的高度。(示例中有圆角与倾斜的示例)