基于单个 div 的 CSS 画图
原文: Single Div Drawings with CSS
译者: 前端外刊评论
译注:通读本文,强烈地感受到了技术与艺术的结合。赞作者的这句话:Restricting your available options forces you to re-evaluate the tools you already have. 限制你的可选项,会让你又一次评估手头上已有的工具。
为什么仅仅使用一个 Div?
2013年5月,我參加了 CSSConf,看到了Lea Verou 关于 border-radius 的演讲,你可能会觉得这个属性非常不起眼。可是这个演讲让我大开眼界,认识到 CSS 还有非常多行为我是不了解的。回顾起我还是艺术生的那段时光,不断地推动着我成为所选媒介的专家。
作为一个
Web 设计师,CSS 是我的媒介,因此我尽我所能地学习,探索它的极限。
为什么仅仅有一个 Div?
回顾我曾经学画的时候,课堂上还做了混合颜色的实验,我们就使用三原色。红、黄、蓝。创造出了其它颜色的光谱。
这个实验的目的是让我们了解颜色的特性,同一时候这样的限制也让我们明确了混合的力量。你当然能够买一仅仅绿色的笔,可是你也能够使用蓝色和黄色把绿色做出来。限制你的可选项。会让你又一次评估手头上已有的工具。
我决定開始一个使用 CSS 绘画的项目,过段时间我就会给出一个仅仅用 CSS 绘制的新东西。
为了得到更大的挑战,探索 CSS 的潜力,我给自己定了这个限制,仅仅是用一个 Div。不能直接买一仅仅绿色的笔(加入很多其它的 Div)。我要做的就是尽其所能地结合 CSS 属性来实现我的目的。
工具箱
一个 Div 加上浏览器支持的那些 CSS 属性,看起来可用的工具太少了。可是我发现问题不在于你在使用多少东西,而在于你怎样看待你在使用的东西。
伪元素
由于 CSS 有伪类,所以尽管仅仅有一个 Div,但实际上我能够使用三个元素。
因此。使用div
,div:before
,div:after
,我们能够这样:
div { background: red; }
div:before { background: yellow; }
div:after { background: blue; }
easy想到,这三个元素能够并排成为三个叠在一起的层。因此,在我的脑海中,它看起来是以下这种:
形状
使用 CSS 和单个元素,我们能够制作三种基础图形。使用 width
和 height
属性制作正方形/矩形。使用border-radius
制作圆/椭圆,使用 border
制作三角形/梯形。
我们还能够使用 CSS 创建其它图形。只是大部分都能够简单组合这些基础图形来实现,这些简单的图形最easy制作,也最easy改动。
多个同样的形状
使用叠加的 box-shadow
。我们能够创建多个同样的形状。这些形状能够拥有不一样的大小、颜色和模糊效果。我们能够在x或者y轴上移动这些图形,因此差点儿能够绘制无限的图形。
div {
box-shadow: 170px 0 10px yellow,
330px 0 0 -20px blue,
330px 5px 5px -20px black;
}
我们甚至能够给 box-shadow
加入 box-shadow
。
注意它们申明顺序。再者,把它们当做层更easy理解。
渐变
渐变通过给定一个光源,能够被用来制造明暗和深浅效果,能够让简单扁平的图形看起来更真实。结合多个background-image
,我们能够使用非常多层的渐变来实现更加复杂光影,甚至是很多其它的图形。
div {
background-image: linear-gradient(to right, gray, white, gray, black);
}
div:after {
background-image: radial-gradient(circle, yellow 50%, transparent 50%), linear-gradient(to right, blue, red);
}
视觉
最困难的部分视觉,即怎样拼凑这些形状成为可被感知的画图。随着我越来越注重画图的技巧,发现视觉这一步非常重要。
为了做到这一点,我经常注释这主题相关的图片,将其分割为多个可视的部分。
都是一个个形状,都是一个个颜色。我把整张图片简化为一些小的带颜色形状或者区块,我知道(大体上)怎样使用 CSS 来实现它们。
实例
我们一起细致看看两个画图,并学习怎样分解成不同的区块。合成一个大的图形。
第一个就是一支绿色的蜡笔。
蜡笔由两个基础图形构成:矩形的笔身和三角形的笔尖。
我必须实现以下这些点来捕获真实蜡笔的感觉:
- 纸质包装上不同的颜色
- 印刷在包装上的形状和文字
- 条纹暗示蜡笔是圆的
- 明暗效果,暗示圆形的蜡笔和光源
首先,我使用 div
和 background
颜色制作蜡笔的身体部分,从顶部究竟部渐变,并使用 box-shadow
暗示立体感:
div {
background: #237449;
background-image: linear-gradient(to bottom,
transparent 62%,
black(.3) 100%);
box-shadow: 2px 2px 3px black(.3);
}
然后,我使用一个从左到右的 linear-gradient
制作纸包装。
alpha
值为 .6
,这种之前的渐变能够透出来。
div {
background-image: linear-gradient(to right,
transparent 12px,
rgba(41,237,133,.6) 12px,
rgba(41,237,133,.6) 235px,
transparent 235px);
}
接下来,我继续使用相同的方式,从左到右渐变,制作蜡笔上的条纹。
div {
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
轻松搞定。
div {
background-image: radial-gradient(ellipse at top,
black(.6) 50px,
transparent 54px);
}
我刚才单独展示了各个部分,只是别忘了 background-image
看起来是这种:
div {
// ellipse printed on wrapper
background-image: radial-gradient(ellipse at top,
black(.6) 50px,
transparent 54px),
// printed stripes
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),
// wrapper
linear-gradient(to right,
transparent 12px,
rgba(41,237,133,.6) 12px,
rgba(41,237,133,.6) 235px,
transparent 235px),
// crayon body shading
linear-gradient(to bottom,
transparent 62%,
black(.3) 100%)
}
完毕了 div
,我们把注意力转移到 :before
伪类元素上,创建蜡笔的笔头。
使用实心和透明的边框,我制作了一个三角形,把它和我之前绘制的 div
放到一起。
div:before {
height: 10px;
border-right: 48px solid #237449;
border-bottom: 13px solid transparent;
border-top: 13px solid transparent;
}
比起蜡笔笔杆,笔头看起来有点平。我们能够使用 :after
伪类元素来修复这个问题。我加入一个从顶部究竟部的 linear-gradient
,制作了一个反光效果,贯穿整仅仅蜡笔。
div:after {
background-image: linear-gradient(to bottom,
white(0) 12px,
white(.2) 17px,
white(.2) 19px,
white(0) 24px);
}
这给那个扁平的三角形加入很多其它的层次感,更加真实。
制作接近尾声,我给 :after
加入一些文字,定位。使得看起来像是印刷在蜡笔包装上的一样。
div:after {
content: 'green';
font-family: Arial, sans-serif;
font-size: 12px;
font-weight: bold;
color: black(.3);
text-align: right;
padding-right: 47px;
padding-top: 17px;
}
大功告成!
另外一个实例
蜡笔作为一个不错的样例。非常好地展示了怎样使用 background-image
和 gradient
来产生真实的效果。
以下这个样例将展示多个 box-shadow
的强大之处:单 div
的照相机。
这是照相机的主体部分,使用 background-image
和 border-image
制作的。
以下是一张 gif,展示 :before
伪类元素(黑色的那个矩形),以及使用它的 box-shadow
创建出来的非常多照相机的细节部分。
div:before {
background: #333;
box-shadow: 0 0 0 2px #eee,
-1px -1px 1px 3px #333,
-95px 6px 0 0 #ccc,
30px 3px 0 12px #ccc,
-18px 37px 0 46px #ccc,
-96px -6px 0 -6px #555,
-96px -9px 0 -6px #ddd,
-155px -10px 1px 3px #888,
-165px -10px 1px 3px #999,
-170px -10px 1px 3px #666,
-162px -8px 0 5px #555,
85px -4px 1px -3px #ccc,
79px -4px 1px -3px #888,
82px 1px 0 -4px #555;
}
类似的,以下是 :after
(灰色的圆)以及使用它的 box-shadow
制作的几个细节部分。
div:after {
background: linear-gradient(45deg, #ccc 40%, #ddd 100%);
border-radius: 50%;
box-shadow: 0 3px 2px #999,
1px -2px 0 white,
-1px -3px 2px #555,
0 0 0 15px #c2c2c2,
0 -2px 0 15px white,
-2px -5px 1px 17px #666,
0 10px 10px 15px black(.3),
-90px -51px 1px -43px #aaa,
-90px -50px 1px -40px #888,
-90px -51px 0 -34px #ccc,
-90px -50px 0 -30px #aaa,
-90px -48px 1px -28px black(.2),
-124px -73px 1px -48px #eee,
-125px -72px 0 -46px #666,
-85px -73px 1px -48px #eee,
-86px -72px 0 -46px #666,
42px -82px 1px -48px #eee,
41px -81px 0 -46px #777,
67px -73px 1px -48px #eee,
66px -72px 0 -46px #666,
-46px -86px 1px -45px #444,
-44px -87px 0 -38px #333,
-44px -86px 0 -37px #ccc,
-44px -85px 0 -34px #999,
14px -89px 1px -48px #eee,
12px -84px 1px -48px #999,
23px -85px 0 -47px #444,
23px -87px 0 -46px #888;
}
有点疯狂?只是你看到了吧。 多个 box-shadow
确实能够给使用单个 div
画图加入非常多细节部分。
最大的挑战
我碰到了两个最大的挑战,三角形的限制和 gradient
独特的行为。
三角形的问题
由于三角形是使用 border
创建的,这极大地限制了我对它的利用。使用 border-image
给 border
加入gradient
。不能单独加入当中一边。无法给 border
创建出来的三角形加入 box-shadow
,由于 box-shadow
是加入在盒模型上的。因此要创建多个三角形就会非常困难。看起来就是以下这样:
div {
border-left: 80px solid transparent;
border-right: 80px solid transparent;
border-bottom: 80px solid red;
}
div:before {
border-left: 80px solid transparent;
border-right: 80px solid transparent;
border-bottom: 80px solid red;
border-image: linear-gradient(to right, red, blue);
}
div:after {
border-left: 80px solid transparent;
border-right: 80px solid transparent;
border-bottom: 80px solid red;
box-shadow: 5px 5px 5px gray;
}
多层渐变
渐变的行为就是会填满整个 background
。
在堆叠多个 gradient
的时候就显得非常讲技巧。须要花费额外的时间思考透明度、z-index
这些事,还要搞清楚什么要可见,什么不要。只是若能有效地使用 gradien
t,我们的画图能够包括非常多令人惊叹的细节。
Tardis 就是一个非常好的样例,显示或隐藏渐变,创建了一张细节极强的图片。
下图显示的是绘制的中间过程,能够看到数个从顶部究竟部的渐变,宽度填满整个容器。
使用从左到右和从右到左的 gradient
,我能够遮住一部分渐变,同一时候把其它部分渐变显示出来。
终于的结果看上去包括了非常多图形来构成 Tardis 的前面,但实际上它就是层叠的 linear-gradient
。
非常多时候不得不伪造呀。
动态地查看它们
源于这个项目。有一个很酷很实用的好东西突然出现。那就是 Rafael Carício(@rafaelcaricio) 开发的名为CSS
Gradient Inspector 的 Chrome 浏览器插件。这个开发工具能够探測且能够开关元素上的每个 gradient。看起来就像开关一个个层。(它在日常项目中也很实用。
)
我希望设计师和开发人员使用动画或者 JavaScript 的功能来做类似的尝试,或者对这些绘画做一些变形。
你能够到http://div.justjavac.com 或者 GitHub 上把玩一下这些
CSS。
基于单个 div 的 CSS 画图的更多相关文章
- 基于单个 div 的 CSS 绘图
为什么只使用一个 Div? 2013年5月,我参加了 CSSConf,看到了Lea Verou 关于 border-radius 的演讲,你可能会认为这个属性很不起眼.但是这个演讲让我大开眼界,认识到 ...
- [转]基于display:table的CSS布局
当IE8发布时,它将支持很多新的CSS display属性值,包括与表格相关的属性值:table.table-row和table-cell,它也是最后一款支持这些属性值的主流浏览器.它标志着复杂CSS ...
- div垂直居中 css div盒子上下垂直居中
div垂直居中 css div盒子上下垂直居中,让DIV盒子在任何浏览器中任何分辨率的显示屏浏览器中处于水平居中和上下垂直居中. div垂直居中常用于单个盒子,如一个页面里只有一个登录布局,使用div ...
- css Table布局:基于display:table的CSS布局
两种类型的表格布局 你有两种方式使用表格布局 -HTML Table(<table>标签)和CSS Table(display:table 等相关属性). HTML Table是指使用原生 ...
- 用div和css样式控制页面布局
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- DIV实现CSS 的placeholder效果
placeholder是HTML5中input的属性,但该属性并不支持除input以外的元素 但我们可以使用Css before选择器来实现完全相同的效果 <!DOCTYPE html> ...
- 利用扩展双屏技术及Chrome浏览器,高速剖析优秀网页Div及CSS构成,并高效实现原型创作
作为一个Web前台设计人员,应该充分利用可利用的硬件条件及专业的软件工具,迅速进入到高效氛围其中.实践中,我们能够利用扩展桌面双屏技术及Chrome浏览器高速剖析优秀网页Div及CSS构成,并高速实现 ...
- 典型的DIV+CSS布局——左中右版式
[效果] [HTML] <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Def ...
- HTML&CSS——使用DIV和CSS完成网站首页重构
1.DIV 相关的技术 Div 它是一个 html 标签,一个块级元素(单独显示一行).它单独使用没有任何意义,必须结合CSS来使用.它主要用于页面的布局. Span 它是一个 html 标签,一个内 ...
随机推荐
- IOS公司开发者账号申请详细教程--1 备用
谈到苹果开发者账号,我们需要区分一下个人账号.公司账号和企业账号这三种,还有一种是教育账号,这个就不多说了. 个人账号:个人申请用于开发苹果app所使用的账号,仅限于个人使用,申请比较容易,$99. ...
- 第 16 章 观察者模式【Observer Pattern】
以下内容出自:<<24种设计模式介绍与6大设计原则>> <孙子兵法>有云:“知彼知己,百战不殆:不知彼而知己,一胜一负:不知彼,不知己,每战必殆”,那怎么才能知己知 ...
- Java 判断操作系统类型(适用于各种操作系统)
Java 判断操作系统类型(适用于各种操作系统) 最近一段时间写一个授权的程序,需要获取很多信息来保证程序不能随意复制使用,必须经过授权才可以. 为了限制用户使用的操作系统,必须有统一的方法来获取才可 ...
- Python读写Redis数据库
import redis class Database: def __init__(self): self.host = 'localhost' self.port = 6379 def write( ...
- ACMer程序员智力拾遗
浏览网页偶得,遂记录下来,每天进步一点点-- 博客园真是个不错的平台,今天我让师姐也注册了-- 学会分享吧,孩子们-- 一.编程中无穷大量的设置 ...
- 【技术贴】解决QQ空间发表文章手机不显示换行
采用HTML模式,在需要换行的地方加入如下代码. <div><span style="font-family:微软雅黑;font-size:16px"> & ...
- log.isDebugEnabled()的使用
转自: http://huangxx.iteye.com/blog/190693 在使用log4j,common-log这样的log框架时,发现很多代码中这样写 if (log.isDebugEn ...
- VC下载文件 + 显示进度条
在codeproject里找了许久,发现这样一个VC下载文件并显示进度条的源码,于是添加了些中文注释: 1.下载线程函数: UINT DownloadFile(LPVOID pParam) { CWn ...
- jQuery zTree v3.5 实例3 异步树
最终效果: 点击非叶子节点时,向后台发送请求,获取下级菜单 前台代码如下: <%@ page language="java" contentType="text/h ...
- USACO3.43Electric Fence(pick定理)
忘记pick定理是什么了 想枚举来着 ..没枚出来 有篇pick定理的证明 貌似挺好 也没太看懂 /* ID: shangca2 LANG: C++ TASK: fence9 */ #include ...