在 Web 开发中生成几何图形的几种方式

2015-07-22 W.Y. 更多博文 » 博客 » GitHub »

CSS Shapes

原文链接 https://bubkoo.github.io/2015/07/22/working-with-shapes-in-web-design/
注:以下为加速网络访问所做的原文缓存,经过重新格式化,可能存在格式方面的问题,或偶有遗漏信息,请以原文为准。


当我们在进行 Web 开发时,很多时候都是在有意或无意地创建一些矩形,深究一下,到底有多少中方式来得到一个几何图形呢?本文将简单介绍几种生成圆形、三角形和多边形的方式,并分析每种方式的优缺点。

下面是可能使用到的方式:

  1. border-radius
  2. border
  3. rotating shapes with transform
  4. pseudo elements
  5. box-shadow
  6. wrapping text into shapes with shape-outside
  7. clip-path on an element
  8. SVG assets
  9. canvas

<!--more-->

border-radius

使用 border-radius 样式属性是得到圆形的最简单的方式:

.element {
  height: 500px;
  width: 500px;
  border-radius: 50%;
}

border-radius 的属性值可以是长度值或百分比。值为 50%100% 时都可以得到一个圆形,Jessica Eldredge 有篇文章介绍了为什么要使用 50% 而不是 100%

使用该属性还可以制作出其他形状,如圆角矩形,椭圆形等。

优点:

  • 支持现代浏览器;
  • 只需要少量的 CSS。

深入阅读

border

通过设置 CSS 中的 border 属性我们可以一些不同的图形,例如,通过将一个元素的三个边框颜色设置为透明,我们可以模拟一个三角形的样子:

.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;
}

我们可以使三角形指向任何想要的方向,下面是一个动画教程:

你可以使用 CSS 三角形生成器来帮你自动生成一个三角形,如果你想以编程的方式来实现一个三角形,这里有一个 CSS 的 Mixin

也可以是使用该技术来得到一个梯形:

优点:

  • 浏览器都支持;
  • 有现成的工具可用,比如,CSS 形状生成器,可以很方便地生成你想要的几何形状。

transform

可以使用 transform 来做出特定的形状,如钻石形状:

.diamond {
  transform: rotate(45deg);
}

在上面例子中,由于 transform 旋转,导致图形溢出了父元素,我们可以通过 transform-origin 来调整:

.diamond {
  transform: rotate(45deg);
  transform-origin: 0 100%;
}

优点:

  • 支持现在浏览器。

缺点:

  • 需要使用 transform-origin 来修正元素的位置,这可能会不好调整。

Pseudo elements

Pseudo elements(伪元素)是利用 CSS 制作几何形状的重要工具,大大提高了可制作形状的数量,如下面的五角形:

使用 :before 为元素,我们生成了两个不同的形状,其中一个在另一个的上面,通过上例中的 CSS 可知,为了得到这个形状,对两个形状的位置要求非常严格。这是我对使用 CSS 来制作复杂形状最不满意的地方:越复杂的形状要求越复杂的代码,一旦你得到五边形或六边形后,你会发现这样的代码非常丑陋,在项目中这样的的代码是不可维护的。

优点:

  • 可以制作任何你想要的形状;
  • 不用像图片一样需要额外的 HTTP 请求。

缺点:

  • 在大型项目中,制作复杂形状的代码会变得不可维护,也不是长久之计。

box-shadow

这也许是使用 CSS 制作形状最奇怪的方式,因为使用 box-shadow 可以创造惊人的艺术效果。看下面的 demo:

优点:

  • 你可以使用 box-shadow 制作形状?

缺点:

  • 如果将来想修改图形,需要精确找到像素位置对应的 box-shadow 属性,这是个烦人的工作;
  • 得到的形状不可以被第三方软件编辑,比如 Illustrator,Photoshop 或 Sketch。

使用 shape-outside 使文字围绕图形

使用 shape-outside 属性可以使文字围绕图形(圆、椭圆或多边形)。需要注意的是:目前这个属性只对浮动元素有效。看下面这个简单的例子:

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

shape-outside 属性对应的方法有:circle()ellipse()polygon()inset(),下面这个例子使用了 ellipse() 方法:

.element {
  shape-outside: ellipse(150px 300px at 50% 50%);
}

使用 ellipse() 方法时需要指定椭圆需要的 x 和 y 半径,其次是椭圆的中心位置。在上例中,椭圆的中心位置就位于元素的中心位置上。

然后,这里有一个需要注意的问题:当使用 shape-outside 属性时,并不会影响元素本身的形状,只影响了围绕它的其他元素的形状。如果为该元素这是一个边框和背景,我们将发现该元素仍然是一个矩形:

你可以这样来理解:使用了 shape-outside 属性的元素只改变了围绕它的其他元素,而元素本身的几何形状并没有改变。为了改变元素自身的形状可以将 shape-outsideclip-path() 结合使用,例如:

还有很多没有涉及到的内容,如果想要深入了解 shape-outside 属性,可以参考这篇文章

优点:

  • 可以实现文字环绕形状效果;
  • 可以设置形状的 marginpaddingborder 属性,这可以使我们对元素位置进行精细控制。

缺点:

  • IE 和 Firefox 不支持该属性;
  • 不改变元素的实际形状。

clip-path

与上面介绍的 shape-outside 属性一样,clip-path 属性可以使用的方法有:inset()polygon()ellipse(),看下面这个例子:

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

clip-path 属性是完全支持 CSS3 动画的:

可以使用 Clippy 这样的工具来生成你需要的代码:

Clippy

深入阅读可以参考:

优点:

  • 可以制作复杂的形状,而不需要图片这样的额外资源。

缺点:

  • 实现文字环绕图片效果需要结合使用 clip-pathshape-outside 这两个属性。

SVG

使用 SVG(可缩放的矢量图形)可以制作出任何你想要的图形,如 console、logo、图标、社会媒体按钮等。

本文并不会教你如何使用 SVG,因为涉及太多的最佳实践和技术细节。通常,如果一个项目需要使用到图形,我的首选肯定是 SVG,因为这意味着更少的奇怪的不可预知的代码,也意味着如果设计师需要对图形进行润色,他们可以随时编辑这些形状。

如果想详细了解 SVG,这里有一篇关于 SVG 的汇总文章

优点:

  • 较小的文件大小;
  • 可以在任何流行的图形编辑器中编辑它们;
  • 不熟悉 CSS 和 JavaScript 的人也可以制作它们;
  • 无失真缩放;
  • 广泛的浏览器支持和大量的兼容方案;
  • 可以将它们添加到页面标签中,并可以支持屏幕阅读器
  • 支持 CSS 和 JavaScript 动画。

缺点:

  • 如果它们是非常简单的形状,你可以使用纯 CSS 的方案来实现。

canvas

使用 canvas 元素来制作图表和互动式游戏非常有用,因为它的设计初衷就是用来绘制图表。canvas 绘图教程超出了本文的范围,这里你需要了解的是用 canvas 可以做什么,下面是使用 canvas 来绘制一个正方形:

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

对每个 canvas,我们需要给 .getContext() 方法传递 "2d" 这个字符串参数,目前还没有 3d 上下文,也许将来会支持。

在 MDN 上有一系列关于 canvas 的教程

优点:

  • 制作游戏和交互式图表。

缺点:

  • 依赖 JavaScript。

总结

选择一种制作图形的方式,就与选择一种垂直对齐方式一样:没有最好的方案,只有最适合项目的方案。在我的项目开发中,我并没有只选择其中一种技术,而是将这些方式使用在最适合它们的位置,同时注意保持完善的文档,并且不给其他开发人员造成困扰。

参考资源