这篇文章我大概地列举了一些创建各种形状的常见方式,并记下每种方式的优势与不足。
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伪元素生成一个三角形,拼成一个五角形。
优点:
- 你几乎可以使用伪元素生成任何形状
- 不需要像图片一样,增加HTTP请求。
缺点:
- 在大项目中,可能维护比较麻烦,并且耗时较长。
box-shadow
这可能是使用CSS绘制形状最奇怪的方式了。使用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;
}

这个属性有很多创建形状的方法,比如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,来帮你实现。

更多资料,请看bennettfeely.com/clippy/和Clipping and Masking in CSS
优点:
缺点:
- 如果你想让文字包裹形状,那么你需要使用
clip-path和shape-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有一个很棒的教程。
优点:
缺点:
总结
选择绘制图形就跟你选择那种垂直居中布局一样,根据你的需要去选择。上面列举了这些方式,希望对你下次需要绘制图形有所帮助。
扩展阅读
- Almanac entry for clip-path
- More info about clip-path
- W3C on CSS Shapes
- The Shapes of CSS
- Getting started with CSS Shapes
- Clippy
- Adobe’s CSS Shapes CodePen collection
- Clipping and masking in CSS
- Border-radius: 50% vs 100%
- How to get started with CSS shapes
- Shapes editor Chrome extension
- Canvas tutorial on MDN
- A compendium of SVG information
本文根据@Robin Rendle的文章所译,整篇译文带有我们自己的理解和意思,如果有译得不好的地方或者不对之处,还请大家指点。英文出处:Working with Shapes in Web Design 如需转载,请注明出处:w3ctrain.com/2015/08/09/…<