这是我参与更文挑战的第6天,活动详情查看: 更文挑战
切角效果
难题
目前很多开发者更倾向于使用背景图片来达到目的,比如说使用三角形盖住元素的顶角来模拟切角效果,或者使用一张或者多张已经切过角的图片来作为整个元素的背景。
解决方案
渐变可以接受一个角度(比如 45deg )作为方向,而且色标的位置信息也可以是绝对的长度值,这一点丝毫不受容器尺寸的影响。
background: #58a;
background: linear-gradient(135deg, transparent 15px, #58a 0) top left,
linear-gradient(-135deg, transparent 15px, #58a 0) top right,
linear-gradient(-45deg, transparent 15px, #58a 0) bottom right,
linear-gradient(45deg, transparent 15px, #58a 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
复制代码
如果用上述代码修改背景色的时候需要修改五处,在改变切角尺寸的时候需要改变四处,可以使用SCSS来写,代码如下:
@mixin beveled-corners($bg, $tl:0, $tr:$tl, $br:$tl, $bl:$tr) {
background: $bg;
background:
linear-gradient(135deg, transparent $tl, $bg 0) top left,
linear-gradient(225deg, transparent $tr, $bg 0) top right,
linear-gradient(-45deg, transparent $br, $bg 0) bottom right,
linear-gradient(45deg, transparent $bl, $bg 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
}
// 调用
@include beveled-corners(#58a, 15px, 5px);
复制代码
弧形切角
内凹圆角(跟圆角方向相反)可以使用径向渐变替代上述线性渐变来实现。
background: greenyellow;
background:
radial-gradient(circle at top left,
transparent 15px, greenyellow 0) top left,
radial-gradient(circle at top right,
transparent 15px, greenyellow 0) top right,
radial-gradient(circle at bottom right,
transparent 15px, gold 0) bottom right,
radial-gradient(circle at bottom left,
transparent 15px, gold 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
复制代码
内联 SVG 与 border-image 方案
渐变方案的代码繁琐冗长,而且一旦想要修改的话,需要修改多处。因此使用 border-image
,并通过一个内联的 SVG 图像来产生切角效果。由于尺寸无关紧要( border-image
会解决缩放问题,而 SVG 可以实现与尺寸完全无关的完美缩放——这就是矢量图的好处),每个切片的尺寸都可以设置为 1,以便理解和书写。切角的尺寸是 1,直线边缘也都是 1。
border: 15px solid transparent;
border-image: 1 url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="3" height="3" fill="%2358a"><polygon points="0,1 1,0 2,0 3,1 3,2 2,3 1,3 0,2"/></svg>');
复制代码
这样可以得到一个有切角边框的矩形,需要添加背景颜色。因此添加:
background: #58a;
复制代码
但是发现切角不见了,如下图2,于是使用 background-clip 避免背景色蔓延到边框区域。
background-clip: padding-box;
复制代码
给 div 设置一个与背景色一致的边框色,当 border-image 生效时,边框忽略不计;当 border-image 不生效时,边框色可以提供一个比较平稳的回退措施。
梯形标签页
难题
梯形的定义比平行四边形还要广泛一些:只要一对边平行就可以,另外两条边可以是任意角度。
解决方案
在现实的三维世界中旋转一个矩形,由于透视的关系,最终看到的二维的图像就是一个梯形。可以使用 CSS 中的 3D 旋转模拟效果。
transform: perspective(.5em) rotateX(5deg);
复制代码
但是变换后发现内容的文字也进行了变化,而且 对元素应用了3D变形之后,其内部的变形效应是“不可逆转”的,这一点跟 2D 的不同,因此只能将其变形应用在伪元素上。
nav>a {
position: relative;
display: inline-block;
padding: 1em 3em .1em;
}
nav>a::before {
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: -1;
background: #ccc;
background-image: linear-gradient( hsla(0, 0%, 100%, .6), hsla(0, 0%, 100%, 0));
border: 1px solid rgba(0, 0, 0, .4);
border-bottom: none;
border-radius: .5em .5em 0 0;
box-shadow: 0 .15em white inset;
transform: perspective(.5em) rotateX(5deg);
transform-origin: bottom;
}
nav>a:nth-child(2)::before{
transform-origin: bottom left;
}
nav>a:nth-child(3)::before{
transform-origin: bottom right;
}
复制代码
简单的饼图
基于 transform 的解决方案
HTML
<div class="pie">0%</div>
<div class="pie">20%</div>
<div class="pie">40%</div>
<div class="pie">60%</div>
<div class="pie">80%</div>
复制代码
CSS
.pie {
display: inline-block;
position: relative;
width: 100px;
line-height: 100px;
border-radius: 50%;
background: yellowgreen;
background-image: linear-gradient(to right, transparent 50%, salmon 0);
color: transparent;
text-align: center;
}
@keyframes spin {
to { transform: rotate(.5turn); }
}
@keyframes bg {
50% { background: salmon; }
}
.pie::before {
content: '';
position: absolute;
top: 0; left: 50%;
width: 50%; height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
animation: spin 50s linear infinite, bg 100s step-end infinite;
animation-play-state: paused;
animation-delay: inherit;
}
复制代码
JS
function $$(selector, context) {
context = context || document;
var elements = context.querySelectorAll(selector);
return Array.prototype.slice.call(elements);
}
$$('.pie').forEach(function (pie) {
var p = pie.textContent;
pie.style.animationDelay = '-' + parseFloat(p) + 's';
});
复制代码
最后说一句
如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下,您的支持是我坚持写作最大的动力,多谢支持。