A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 武汉分校-小舞 黑马粉丝团   /  2017-8-17 14:48  /  1488 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 武汉分校-小舞 于 2017-8-17 15:11 编辑

自适应的椭圆

  1.自适应的椭圆
  通过border-radius这个属性;border-radius它可以单独指定水平和垂直半径。用 / 分隔这两个值。并且该属性的值不仅可以接受长度值,还能接收百分比的值。百分比的值会基于元素的尺寸进行解析,宽是水平半径的解析,高是垂直半径的解析。
  所以可以把两个半径的值都设置成50%
border-radius: 50% / 50%;
/* 值都是50% 就可以简化成border-radius: 50%; */

  2.半椭圆的实现
  border-radius的值是可以分开设置的,用空格进行分开,甚至可以为四个角提供完全不同的水平和垂直的半径。
  border-radius四个值的渲染顺序是从左上角开始,顺时针渲染;
  当只给定3个值时,第四个值和第二个相等;
  当给定两个值时,第三个值和第一个值相等,第四个值和第二个值相等。
  所以半椭圆的实现方法就是:
border-radius: 50% / 100% 100% 0 0;

/*
* 会解析成下面的样子
    border-top-left-radius: 50% 100%;
    border-top-right-radius: 50%100%;
    border-bottom-right-radius: 50%0px;
    border-bottom-left-radius: 50%0px;
*/

  同理的四分之的椭圆的生成方法:
/* 不能设置圆角的就设置成 0 */
border-radius: 100% 0 0 0;

 平行四边形的实现
  在生成平行四边形时,直接对当前对div使用transform: skew(-45deg);变形,会导致div里面的内容也会发生变形;file:///C:/Users/%E9%A1%B9%E5%8D%8E/AppData/Local/Temp/msohtmlclip1/01/clip_image001.gif
  通用的解决办法是通过伪元素的方法,就是把所有的样式用到伪元素上,对伪元素进行变形,由于内容不在伪元素里,所以内容不会受到影响。具体的实现如下:
<div class="parallelogram">
    click
</div>
.parallelogram {
    text-align: center;
    position: relative;
}

.parallelogram::before {
    transform: skew(-45deg);
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    z-index: -1;
    content: ' ';
    background: #fb3;
}
  这种技巧不仅对于skew()变形来说有用,还适用于其他任何变形样式,当想变形任何一个元素而不想改变它的内容的时候都可以用到它。
 菱形图片的生成
  在css中,有些需求是要把图片裁剪成菱形,使用css可以很好的解决这个问题,为不需要预先把图片裁剪成菱形而影响后期的维护。

基于变形的方案

  直接使用类似平行四边形的方式旋转,给img设置max-width: 100%,会导致图片被裁剪成八边形。因为100%会被解析成div的边长。所以解决这个问题的办法就是让图片的宽等于div这个容器的对角线的长度,比较好的办法就是把图片用scale放大根号2倍(大概是1.42倍),具体实现的代码如下:
<div class="picture">
    <img src="cat.jpg"/>
</div>
.picture {
    width: 400px;
    height: 400px;
    transform: rotate(45deg);
    overflow: hidden;
}

.picture1 > img {
    max-width: 100%;
    height: 400px;
    transform: rotate(-45deg)scale(1.42);
}
  scalewidth放大的区别:
  scale的缩放图片是以它的中心点进行缩放的(在不指定transform-origin的前提下),通过width属性来放大图片时,只会以它左上角的原点进行缩放,然后用额外的负边距来调整图片的位置。

裁切路径方案
上面的办法还需要前套一层多余的html标签,使用clip-path这个属性,这个原本是svg的属性,使用polygon()这个多边形的函数,使用的百分比的值会解析为元素自身的尺寸。

img {
    clip-path: polygon(50% 0, 100%50%, 50% 100%, 0 50%);
}
  clip-path这个属性还能参与动画,只要动画是在同一个形状函数之间进行的,而且点的数量是相同的就可以,比如我们希望鼠标hover时平滑的扩展为完成的面积,只需这样:
.picture {
    clip-path: polygon(50% 0, 100%50%, 50% 100%, 0 50%);
    transition: 1s clip-path;
}
.picture:hover {
    clip-path: polygon(0 0, 100% 0,100% 100%, 0 100%);
}
切脚效果的实现

径向渐变的方式

  实现一个角被切掉的效果,可以使用渐变,渐变接受一个角度作为方向,并且允许文字溢出并超出切角区域(因为它只是背景图案),具体实现如下:
div {
  background: #58a;
  background: linear-gradient(-45deg,transparent 15px, #58a 0);
}
  实现两个切角的办法:
div {
    width: 200px;
    height: 100px;
    background: #58a;
    background:linear-gradient(-45deg, transparent 15px, #58a 0)
               right, linear-gradient(45deg, transparent 15px, #65a
                0) left;
    background-size: 50% 100%;
    background-repeat: no-repeat;
}

  同理的四个切角的实现:
div {
    width: 200px;
    height: 100px;
    background: #58a;
    background:linear-gradient(135deg, transparent 15px, #58a 0) top
left, linear-gradient(-135deg, transparent15px, #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;
}
  上面的代码可维护比较差,在改变切角和颜色时都要修改多处,所以我们可以使用scssmixin来写:
@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);
  最后生成的效果是左上角和右下角是15px的切角,右上角和左下角是5px的切角。上面的minxin设置了初值,当传入的值少于四个值时,就跟border-radius赋值一样。
  一样的道理我们也可以创建弧形切角,至少改成径向渐变
div {
    width: 200px;
    height: 100px;
    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;
}

内联SVGborder-image的方式

  SVG 可以实现与尺寸完全无关的完美缩放,当文本溢出的时候,则会起到普通边框的作用,令文字折行。具体的实现如下:
div {
  width: 200px;
  height: 100px;
  border: 15px solid transparent;
  border-image: 1url('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,31,3 0,2"/>\</svg>');
}

  解决中间的背景色的填充可以给div块加一个和border一样的背景色:
div {
    width: 200px;
    height: 100px;
    border: 15px solid transparent;
    border-image: 1url(data:image/svg+xml,\<svg xmlns="http://www.w3.org/2000/svg"width="3" heigh="3" fill="%2358a">\<polygonpoints="0,1 1,0 2,0 3,1 3,2 2,3 1,3 0,2"/>\</svg>);
    background: #58a;
    background-clip: padding-box;
}

裁切路径方案
CSS 裁切路径最神奇的地方在于我们可以同时使用百分比数值(它会以元素自身的宽高作为基数度进行换算)和绝对长度值,从而提供巨大的灵活性。

  如果用裁切路径将一个元素切出20px大小的斜面切角,具体的代码如下:
background: #58a;
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);

  梯形标签页的实现
div {
    position: relative;
    display: inline-block;
    padding: .5em 1em .35em;
    color: white;
}

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(5deg);
    transform-origin: bottom;
}
  变形效果会让这个元素以它自身的中心线为轴进行空间上的旋转,这会让它的尺寸很难控制,解决办法可以设置transform-origin:bottom;,当它在3D空间中旋转时,把它的底边固定。固定底边的同时,高度的缩水会变得更加显眼。为了解决这个问题,可以通过变形属性(scaleY())来改变它的尺寸。
  具体代码如下:
nav > a {
    position: relative;
    display: inline-block;
    padding: .3em 1em 0;
}
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;
}
  通过把transform-origin改成bottom leftbottom right,就可以立即得到左侧倾斜或右侧倾斜的标签页。
  这个方法的缺点是:斜边的角度依赖于元素的宽度。

 简单的饼图的绘制
  思路是把圆形的左右两部分指定为上述两种颜色,然后用伪元素覆盖上去,通过旋转来决定露出多大的扇区。
  代码如下:
.pie {
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background: yellowgreen;
    background-image:linear-gradient(to right, 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;
}
  这种方式还支持动画,就可以用CSS动画来实现一个饼图从0 变化到100% 的动画,从而得到一个炫酷的进度指示器:
@keyframes spin {
    to { transform: rotate(.5turn); }
}
@keyframes bg {
    50% { background: #655; }
}
.pie::before {
    content: '';
    display: block;
    margin-left: 50%;
    height: 100%;
    border-radius: 0 100% 100% 0 /50%;
    background-color: inherit;
    transform-origin: left;
    animation: spin 3s linearinfinite, bg 6s step-end infinite;
}
  生成多个不同比率的静态饼图的办法,可以通过上面的那个动画的实现,需要设置动画处于暂停状态,然后设置负的动画延时直接跳转到动画中的任意时间点, 最终实现的代码如下:
<div class="pie"style="animation-delay: -20s">
    <span>20</span>
</div>
<div class="pie"style="animation-delay: -60s">
    <span>60</span>
</div>
.pie{
    position: relative;
    width: 100px;
    height: 100px;
    line-height: 100px;
    border-radius: 50%;
    background: yellowgreen;
    background-image:linear-gradient(to right, transparent 50%, #655 0);
    color: #000;
    text-align: center;
}

@keyframes spin {
    to { transform: rotate(.5turn); }
}
@keyframes bg {
    50% { background: #655; }
}

.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 linearinfinite, bg 100s step-end infinite;
    animation-play-state: paused;
    animation-delay: inherit;
}
.pie span {
    position: relative;
    z-index: 10;
}

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马