[译] 前端绘制图形的几种方式

3,057 阅读6分钟
原文链接: www.w3ctrain.com

这篇文章我大概地列举了一些创建各种形状的常见方式,并记下每种方式的优势与不足。

border-radius

border-radius可能是创建圆形最简单的方式了,比如:

.element {
  height: 500px;
  width: 500px;
  border-radius: 50%;
}
See the Pen <a href="http://codepen.io/team/css-tricks/pen/LVembR/">LVembR</a> by CSS-Tricks (<a href="http://codepen.io/css-tricks">@css-tricks</a>) on <a href="http://codepen.io">CodePen</a>.

你可以在border-radius上使用任何长度值,px值,百分比或其他单位都可以。如果你有兴趣也可以看看这篇文章 why we should use 50% instead of 100%

当然我们还可以使用border-radius创建一些圆角矩形。

优点:

  • 主流浏览器都支持
  • 简单易用,只要一点CSS

Shapes with border

我们可以使用border创建很多不同形状,比如,把border三边设成transparent就出现一个三角形。

.triangle {
  height: 0;
  width: 0;
  border-left: 100px solid red;
  border-right: 100px solid transparent;
  border-bottom: 100px solid transparent;
  border-top: 100px solid transparent;
}
See the Pen <a href="http://codepen.io/team/css-tricks/pen/vOpjXZ/">vOpjXZ</a> by CSS-Tricks (<a href="http://codepen.io/css-tricks">@css-tricks</a>) on <a href="http://codepen.io">CodePen</a>.

如果你不是很明白,可以再看看下面的Demo。

See the Pen <a href="http://codepen.io/chriscoyier/pen/lotjh/">Animation to Explain CSS Triangles</a> by Chris Coyier (<a href="http://codepen.io/chriscoyier">@chriscoyier</a>) on <a href="http://codepen.io">CodePen</a>.

网上也有很多在线工具可以帮你生成三角形。

当然还可以生成梯形。

.trapezium {
  border-bottom: 100px solid #333;
  border-left: 50px solid transparent;
  border-right: 50px solid transparent;
  height: 0;
  width: 100px;
}

如果需要生成特定的形状,比如钻石,我们可以使用transform等属性。

.diamond {
  height: 150px;
  width: 150px;
  background-color: #7FDBFF;
  transform: rotate(45deg);
}

上面的代码会生成一个旋转了45度的矩形。我们还可以使用transform-origin来调整旋转原点。
优点:

  • 浏览器兼容性好
  • 缺点:

  • 需要根据具体情况调整transform-origin

    Pseudo elements

    为元素在创建形状方面非常重要。让一个元素变成三头六臂。比如我们画一个五角形。

    .pentagon {
        position: relative;
        width: 54px;
        border-width: 50px 18px 0;
        border-style: solid;
        border-color: #01ff70 transparent;
    }
    .pentagon:before {
        content: "";
        position: absolute;
        height: 0;
        width: 0;
        top: -85px;
        left: -18px;
        border-width: 0 45px 35px;
        border-style: solid;
        border-color: transparent transparent #01ff70;
    }

    上面的代码,我们生成一个倒梯形,并使用::before伪元素生成一个三角形,拼成一个五角形。
    pentagon.jpg

    优点:

    • 你几乎可以使用伪元素生成任何形状
    • 不需要像图片一样,增加HTTP请求。

    缺点:

    • 在大项目中,可能维护比较麻烦,并且耗时较长。

    box-shadow

    这可能是使用CSS绘制形状最奇怪的方式了。使用box-shadow可以创建像素图形,比如:

    See the Pen <a href="http://codepen.io/HelKyle/pen/VLRPLq/">Sonic The Hedgehog</a> by Helkyle (<a href="http://codepen.io/HelKyle">@HelKyle</a>) on <a href="http://codepen.io">CodePen</a>.

    优点:

  • 牛逼,box-shadow都能创建图形。
  • 缺点:

    • 如果将来需要改动图片的话,将会很麻烦,因为你得重新算值。
    • 图像是不可以使用PS,AI,Sketch等软件修改的。

    Wrapping text around shapes with shape-outside

    使用 shape-outside属性,文字可以围绕圆形,椭圆形,多边形等形状。需要特别说明的是,这个属性现在只对浮动元素起作用,也许将来会变。看看下面这个例子:

    .element {  
      float: left;
      shape-outside: circle(50%);
      width: 200px;
      height: 200px;
    }

    https://cdn.css-tricks.com/wp-content/uploads/2015/06/shape-outside.png

    这个属性有很多创建形状的方法,比如circle(),ellipse(),polygon(),inset()等。

    比如下面这个例子:

    See the Pen <a href="http://codepen.io/HelKyle/pen/EjMZPQ/">EjMZPQ</a> by Helkyle (<a href="http://codepen.io/HelKyle">@HelKyle</a>) on <a href="http://codepen.io">CodePen</a>.
    .element {
      shape-outside: ellipse(150px 300px at 50% 50%);
    }

    ellipse() 方法需要x,y轴的半径值,接着是原点相对于包裹元素的坐标,比如上面的代码创建的椭圆形状就是半径分别为150px,300px,并且原点位于.element中心。

    这里需要指出,使用shape-outside的时候,我们并没有改变.element本身的形状,我们修改的是元素周围其他元素的相对关系,而没有改变元素本身的形状,不信的话,你加个背景颜色看看。扩展阅读

    优点:

    • 允许动态调整文字的形状,这在响应式界面上很重要。
    • 可以给边界盒子加上margin,padding,border等值,让我们更好地控制。

    缺点:

    • IE,Firefox不支持。
    • 没有修改元素本身的形状。

    clip-path

    跟前面的例子差不多,我们可以在clip-path上使用inset(), polygon(), 和ellipse()等值,看看下面的例子:

    .element {
        width: 200px;
        height: 200px;
        clip-path: polygon(0% 100%, 100% 100%, 0% 0%);
    }
    

    上面的代码通过连接三个点绘制一个三角形。(0 100%)是左下角,(100% 100%)是右下角,(0% 0%)是左上角。

    当然使用clip-path属性是完全可以动态变化的,看看下面这个例子。

    See the Pen <a href="http://codepen.io/HelKyle/pen/waOgzK/">waOgzK</a> by Helkyle (<a href="http://codepen.io/HelKyle">@HelKyle</a>) on <a href="http://codepen.io">CodePen</a>.

    如果你觉得太多麻烦,你可以借助网上的工具比如Clippy,来帮你实现。

    https://dn-w3ctrain.qbox.me/clippy.jpg

    更多资料,请看bennettfeely.com/clippy/Clipping and Masking in CSS
    优点:

  • 我们可以绘制复杂的形状而不需要引入图片
  • 缺点:

    • 如果你想让文字包裹形状,那么你需要使用clip-pathshape-outside

    SVG

    你可以使用可缩放矢量图(Scalable Vector Graphics)绘制任何你心仪的形状。

    如果你感兴趣的话可以看看how to use SVG,就我个人而言,如果项目中需要用到绘制形状的话,我会优先使用SVG,你可以了解更多

    优点:

    • 体积小(如果你优化了的话)
    • 你可以使用任何主流的图像编辑器绘制
    • 不熟悉CSS和JavaScript的人也可以用
    • 可以无限放大但不会出现锯齿
    • 浏览器兼容性强
    • 可以使用CSS和JS做动画

    缺点:

    • 如果形状非常简单的话,你还是使用纯CSS实现比较好

    canvas

    canvas元素经常被用来绘制图形或者实现交互游戏,它最初的设计就是用JavaScript来绘制图形的。
    当然这篇文章不是要教你如何使用canvas,但我们可以告诉你它可以被用来干什么。我们简单绘制一个正方形:

    var canvas = document.querySelector('canvas');
    var ctx = canvas.getContext('2d');
    ctx.fillStyle = '#0074d9';
    ctx.fillRect(0, 0, 100, 100);
    

    每一个canvas我们都要传个2d参数到.getContext()函数里面。因为这不是3d 的上下文。将来可能会有。

    MDN有一个很棒的教程

    优点:

  • 制作小游戏和交互式图表非常有用
  • 缺点:

  • 必需JavaScript支持
  • 总结

    选择绘制图形就跟你选择那种垂直居中布局一样,根据你的需要去选择。上面列举了这些方式,希望对你下次需要绘制图形有所帮助。

    扩展阅读

    本文根据@Robin Rendle的文章所译,整篇译文带有我们自己的理解和意思,如果有译得不好的地方或者不对之处,还请大家指点。英文出处:Working with Shapes in Web Design 如需转载,请注明出处:w3ctrain.com/2015/08/09/…<