用单div实现CSS绘图方法

2013年5月,我参加了 CSSConf,看到了Lea Verou 关于 border-radius 的演讲,你可能会认为这个属性很不起眼。但是这个演讲让我大开眼界,认识到 CSS 还有很多行为我是不了解的。回忆起我还是艺术生的那段时光,不断地推动着我成为所选媒介的专家。作为一个 Web 设计师,CSS 是我的媒介,因此我尽我所能地学习,探索它的极限。

用单div实现CSS绘图方法

  为什么只有一个 p?

回忆我以前学画的时候,课堂上还做了混合颜色的实验,我们就使用三原色,红、黄、蓝,创造出了其他颜色的光谱。这个实验的目的是让我们了解颜色的特性,同时这种限制也让我们明白了混合的力量。你当然可以买一只绿色的笔,但是你也可以使用蓝色和黄色把绿色做出来。限制你的可选项,会让你重新评估手头上已有的工具。

我决定开始一个使用CSS 绘画的项目,过段时间我就会给出一个只用 CSS 绘制的新东西。为了得到更大的挑战,探索 CSS 的潜力,我给自己定了这个限制,只是用一个 p。不能直接买一只绿色的笔(添加更多的 p),我要做的就是尽其所能地结合 CSS 属性来实现我的目的。

  工具箱

一个 p 加上浏览器支持的那些 CSS 属性,看起来可用的工具太少了。但是我发现问题不在于你在使用多少东西,而在于你如何看待你在使用的东西。

  伪元素

因为 CSS 有伪类,所以虽然只有一个 p,但实际上我可以使用三个元素。因此,使用p,p:before,p:after,我们可以这样:

使用单p实现CSS 绘图方法汇总 三联

  复制代码

代码如下:

p { background: red; }

p:before { background: yellow; }

p:after { background: blue; }

容易想到,这三个元素可以并排成为三个叠在一起的层。因此,在我的脑海中,它看起来是下面这样的:

形状

使用 CSS 和单个元素,我们可以制作三种基础图形。使用width和height属性制作正方形/矩形,使用border-radius制作圆/椭圆,使用border制作三角形/梯形。

我们还可以使用 CSS 创建其他图形,不过大部分都可以简单组合这些基础图形来实现,这些简单的图形最容易制作,也最容易修改。

  多个相同的形状

使用叠加的box-shadow,我们可以创建多个相同的形状,这些形状可以拥有不一样的大小、颜色和模糊效果。我们可以在x或者y轴上移动这些图形,因此几乎可以绘制无限的图形。

复制代码

代码如下:

p {

box-shadow: 170px 0 10px yellow,

330px 0 0 -20px blue,

330px 5px 5px -20px black;

}

我们甚至可以给box-shadow添加box-shadow。注意它们申明顺序。再者,把它们当做层更容易理解。

  渐变

渐变通过给定一个光源,可以被用来制造明暗和深浅效果,可以让简单扁平的图形看起来更真实。结合多个background-image,我们可以使用很多层的渐变来实现更加复杂光影,甚至是更多的图形。

复制代码

代码如下:

p {

background-image: linear-gradient(to right, gray, white, gray, black);

}

p:after {

background-image: radial-gradient(circle, yellow 50%, transparent 50%), linear-gradient(to right, blue, red);

}

  视觉

最困难的部分视觉,即如何拼凑这些形状成为可被感知的绘图。随着我越来越注重绘图的技巧,发现视觉这一步很重要。为了做到这一点,我常常凝视这主题相关的图片,将其切割为多个可视的'部分。都是一个个形状,都是一个个颜色。我把整张图片简化为一些小的带颜色形状或者区块,我知道(大体上)如何使用 CSS 来实现它们。

  实例

我们一起仔细看看两个绘图,并学习如何分解成不同的区块,合成一个大的图形。第一个就是一支绿色的蜡笔。

蜡笔由两个基础图形构成:矩形的笔身和三角形的笔尖。

我必须实现下面这些点来捕获真实蜡笔的感觉:

纸质包装上不同的颜色印刷在包装上的形状和文字条纹暗示蜡笔是圆的明暗效果,暗示圆形的蜡笔和光源

首先,我使用p和background颜色制作蜡笔的身体部分,从顶部到底部渐变,并使用box-shadow暗示立体感:

复制代码

代码如下:

p {

background: #237449;

background-image: linear-gradient(to bottom,

transparent 62%,

black(.3) 100%);

box-shadow: 2px 2px 3px black(.3);

}

然后,我使用一个从左到右的linear-gradient制作纸包装。alpha值为.6,这样的之前的渐变可以透出来。

复制代码

代码如下:

p {

background-image: linear-gradient(to right,

transparent 12px,

rgba(41,237,133,.6) 12px,

rgba(41,237,133,.6) 235px,

transparent 235px);

}

接下来,我继续使用同样的方式,从左到右渐变,制作蜡笔上的条纹。

复制代码

代码如下:

p {

background-image: linear-gradient(to right,

transparent 25px,

black(.6) 25px,

black(.6) 30px,

transparent 30px,

transparent 35px,

black(.6) 35px,

black(.6) 40px,

transparent 40px,

transparent 210px,

black(.6) 210px,

black(.6) 215px,

transparent 215px,

transparent 220px,

black(.6) 220px,

black(.6) 225px,

transparent 225px);

}

纸包装上印刷的椭圆,使用一个radial-gradient轻松搞定!

复制代码

代码如下:

p {

background-image: radial-gradient(ellipse at top,

black(.6) 50px,

transparent 54px);

}

我刚才单独展示了各个部分,不过别忘了background-image看起来是这样的:

  复制代码

代码如下:

p {

// ellipse printed on wrapper

background-image: radial-gradient(ellipse at top,

black(.6) 50px,

transparent 54px),

// printed stripes

linear-gradient(to right,

transparent 25px,