关于如下内容,咱们假设结构层的变动是不容许的。css
咱们也尽可能不去添加额外的HTML,以作到样式层与结构层的分离,如若实在没有其余的可能性,才退而求其次来增长额外的HTML。html
众所周知,制做与圆相关的图形,用到的属性就要 border-radius
了。咱们知道,border-radius
能够单独指定水平和垂直半径,使用斜杠 (/) 来分开,两个值相等能够制做一个圆弧,若是不相等,即是一个椭圆弧了。git
.demo{
border-radius: 100px / 75px;
}
复制代码
其实border-radius是一个简写属性,咱们有两种方式能够为元素的每一个角指定不一样的值。github
第一种简写方式dom
.demo{
border-radius:10px 20px 30px 40px / 50px 60px 70px 80px;
/* 斜杠(/)前表明水平半径,后表明垂直半径,顺序分别为左上角开始,顺时针走向,因此这段代码表示左上角(10px/50px) 右上角(20px/60px)右下角(30px/70px)左下角(40px/80px) */
}
复制代码
第二种是分开写的方式svg
.demo{
border-top-left-radius:10px/50px;
border-top-right-radius:20px/60px;
border-bottom-right-radius:30px/70px;
border-bottom-left-radius:40px/80px;
}
复制代码
若是生成一个自适应的椭圆就很简单了,只要每一个角的水平半径为宽的50%,垂直半径为高的50%,就ok了。 代码简写为:函数
.ellipse{
border-radius:50%;
}
复制代码
平行四边形也是页面中常出现的一种图形,咱们可能很容易就想到,使用skew()将矩形倾斜必定角度便可。oop
.parallelograms{
transform: skew(-45deg);
/*...... */
}
复制代码
惋惜效果不如人意,文字也跟着倾斜了,这时候很容易想到,借助一层dom结构,再把内部文字倾斜回来。post
<div class="parallelograms">
<div>二十首情诗与绝望的歌</div>
</div>
复制代码
.parallelograms{
margin: 50px auto;
max-width: 200px;
padding: 10px;
line-height: 30px;
text-align: center;
color:#fff;
background-color: #58a;
transform:skew(-45deg);
}
.parallelograms div{
transform: skew(45deg);
}
复制代码
接下来咱们讨论第二种方式,使用 伪元素来实现,这时候就体现了伪元素的好处。 关于伪元素的内容可参考个人另外一边文章你所不知道的cssui
思路:咱们能够把伪元素做为第一种方法中的辅助结构层,把全部样式(背景、边框等)应用到伪元素上,而后再对伪元素进行变形,获得咱们的平行四边形形状,而正式内容不受影响,而后把伪元素定位z-index
设为-1,即可漏出正文的内容。
.parallelograms{
margin: 50px auto;
max-width: 200px;
padding: 10px;
line-height: 30px;
text-align: center;
color:#fff;
position: relative;
}
.parallelograms:before{
content:'';
position: absolute;
left:0;
top:0;
right:0;
bottom:0;
background-color: #58a;
transform:skew(-45deg);
z-index: -1;
}
复制代码
提醒: 这个技巧不只对 skew()
变形来讲颇有用,还适用于其余任何变形样式, 当咱们想变形一个元素而不想变形它的内容时就能够用到它。
看到这个图形状,是否是立刻想起上一小节平行四边形的制做,同样的道理,须要把图片用一个
rotate()
变形样式:
<div class="diamond">
<img src="https://avatars1.githubusercontent.com/u/8121621?v=4" alt="..." />
</div>
复制代码
.diamond {
margin:30px auto;
width: 100px;
height: 100px;
transform: rotate(45deg);
overflow: hidden;
border: 1px solid red; /*为了更好的展现问题*/
}
.diamond img {
max-width: 100%;
transform: rotate(-45deg);
}
复制代码
奈何,天不遂人愿!问题在于 max-width:100%
中的100%是指width的100%,也就是400px,而正方形旋转后最长边为对角线,是 根号2倍的width,天然图片的宽度不够了,咱们可使用 scale() 变形样式来把这个图片放大。找到问题后,咱们修复它,
.diamond {
margin:30px auto;
width: 100px;
height: 100px;
transform: rotate(45deg);
overflow: hidden;
border: 1px solid red; /*为了更好的展现问题*/
}
.diamond img {
max-width: 100%;
transform: rotate(-45deg) scale(1.42);
}
复制代码
这个方法须要一层额外的 HTML 标签,这是咱们不作优先考虑的。同时有一个最大的问题就是,只能处理正方形图片,不然就会失效。
在上节中咱们使用过伪元素的技巧,一样能够用在这里,代码以下:
.diamond{
margin:30px auto;
width: 100px;
height: 100px;
overflow: hidden;
position: relative;
transform: rotate(45deg);
}
.diamond:before{
content:'';
position: absolute;
left: 0;
right:0;
top:0;
bottom:0;
transform: rotate(-45deg) scale(1.42);
background: url(https://avatars1.githubusercontent.com/u/8121621?v=4);
background-size: cover;
}
复制代码
原理与上面借助结构层是同样的,因此面临一样的问题,只能处理正方形图片。
接下来咱们使用一种更为好用的方法来解决不是正方形的图片。(裁切路径方案)
.diamond{
/*......*/
clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
复制代码
clip-path
属性是从svg中借鉴过来的,裁切路径容许咱们把元素裁剪为咱们想要的任何形状。polygon()函数容许咱们用一系列(以逗号分隔的)坐标点来指定任意的多边形。
该方法一样能够实现上个章节中的平行四边形,如下章节中的切角、梯形等等任意形状,只须要按顺序排列坐标点便可,如下章节再也不作过多展现,本身能够多多尝试。
切角效果,很容易想到的就是个人上篇文章 你该知道的《css揭秘》--背景与边框篇 中的条纹背景制做中用到的线性渐变 linear-gradient()
咱们很轻易的能够实现一个角被切掉的效果,代码以下:
.bevel-corners{
background: #58a; /*linear-gradient不支持的状况下,做为代码回退机制*/
background:linear-gradient(-45deg, transparent 15px, #58a 0);
}
复制代码
接下来使用两层渐变背景实现两个角被切掉。
background-size
让每层渐变分别只占据整个元素一半的面积,而且
background-repeat
设为
no-repeat
。
代码以下:
.bevel-corners{
background: #58a;
background:
linear-gradient(-45deg, transparent 15px, #58a 0) right,
linear-gradient(45deg, transparent 15px, #58a 0) left;
background-size:50% 100%;
background-repeat:no-repeat;
}
复制代码
一样的原理,咱们把每层渐变改成整个元素的四分之一,则四层渐变色,能够实现四个角被切掉。
.bevel-corners{
background:#58a;
background:
linear-gradient(-45deg,transparent 15px, #58a 0) bottom right,
linear-gradient(45deg,transparent 15px, #58a 0) bottom left,
linear-gradient(135deg,transparent 15px, #58a 0) top left,
linear-gradient(-135deg,transparent 15px, #58a 0) top right;
background-size:50% 50%;
background-repeat:no-repeat;
}
复制代码
继续增长难度,实现 弧形切角, 原理都同样,换汤不换药,只需将线性渐变改成径向渐变便可。
.scoop-corners{
background: #58a;
background:
radial-gradient(circle at top left, transparent 15px, #58a 0) top left,
radial-gradient(circle at top right, transparent 15px, #58a 0) top right,
radial-gradient(circle at bottom right, transparent 15px, #58a 0) bottom right,
radial-gradient(circle at bottom left, transparent 15px, #58a 0) bottom left;
background-size: 50% 50%;
background-repeat: no-repeat;
}
复制代码
实现最后一个图形--饼图(绿色为饼图,棕色来显示比率)
基于 transform 的解决方案
思路:把圆形的左右两部分指定为上述两种颜色,而后用伪元素覆盖上去,经过旋转来 决定露出多大的扇区。
20%的饼图代码以下:
.pie {
width: 100px;
height: 100px;
border-radius: 50%;
background: yellowgreen;
background-image:linear-gradient(90deg, transparent 50%, #655 0);
}
.pie:before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: inherit;
transform-origin: left;
transform: rotate(.2turn);
}
复制代码
当旋转超过50%以后,饼图就变成了下图这样,
而后咱们可让旋转的伪元素的颜色反一下,变成棕色既能够实现50%-100%比率的饼图,
60%的饼图代码以下:
.pie:before {
content: '';
display: block;
margin-left: 50%;
height: 100%;
border-radius: 0 100% 100% 0 / 50%;
background-color: #655;
transform-origin: left;
transform: rotate(.1turn);
}
复制代码
若是本文有帮到你,不妨给点个赞👍,我会更加有动力创做!