zoukankan      html  css  js  c++  java
  • 《CSS揭秘》 |形状

    本章示例:https://codepen.io/sanhuamao1/pen/XWpPgeL?editors=1100

    引入:border-radius

    border-radius可以单独指定水平和垂直半径,只要用一个斜杠(/)分隔这两个值即可。这个特性允许我们在拐角处创建椭圆圆角:

    border-radius: 100px / 75px;
    

    cjW0u8.png

    两组值会展开为四个值的:

    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 菱形图片

    方法一:基本变形

    cjWq81.png

    <div class="example">
      <img src="https://z3.ax1x.com/2021/04/19/cTN9C8.jpg"/>
    </div>
    
    .example{
       400px;
      transform: rotate(45deg); //容器旋转
      overflow: hidden;
    }
    
    .example > img {
      max- 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)可以伸长高度,保持它原有的高度。(示例中有圆角与倾斜的示例)

  • 相关阅读:
    使用SQL Server Management Studio 创建数据库备份作业
    ClickOnce 获取客户端发布版本号
    在C#用HttpWebRequest中发送GET/HTTP/HTTPS请求
    找不到方法:“Void System.Data.Objects.ObjectContextOptions.set_UseConsistentNullReferenceBehavior(Boolean)
    常用操作类
    数据库命名规范
    expression动态构成
    C# 获得当前方法 和 方法调用链 的 方法
    EF架构封装类
    基于微软企业库的分层代码框架
  • 原文地址:https://www.cnblogs.com/sanhuamao/p/14696726.html
Copyright © 2011-2022 走看看