带有CSS3的动画3D条形图
关于如何使用CSS创建动画三维条形图的教程。
这一切都是从一个小实验开始的,这个实验受到了来自Nettuts +的教程的启发,它展示了如何使用CSS,图像和JavaScript将3D条形图嵌入到HTML页面中。在阅读完教程之后,我挑战自己将这个想法变成纯粹的CSS,看看我能做多少。最初的挑战是创造一个经典的半透明的6方框3D盒子。最后的挑战是创建一个完整的三维条形图,我们将在本教程中创建。
你可以看看我以前做过这里。
请注意:本教程的结果只能在支持相应CSS属性的浏览器中按预期方式工作。
我们写下一些关键的要求。图表应该是
背景无关
自适应(独立于条数)
可扩展(就像矢量图形)
轻松定制(颜色,大小和比例)
规划阶段是任何项目中最重要的部分。所以让我们制定一个计划。
在实际编写代码之前,我通常会写下所有可能遇到的挑战,并在一个特定的项目中考虑我所能想到的解决方案,并重复这个过程直到我看到一个看起来像是可以执行的策略。下面是我为这个项目提出的解决方案的挑战列表:
挑战#1 - 一个可移动的内部块的酒吧
我们知道:
一个酒吧应该被表示为由六面组成的三维盒子
内块应能在运动中垂直移动。应该有一个选项来隐藏块。
我们需要什么:
1格,由三面组成(背面,底面,左边)
前部外壳1格,由3面组成(正面,顶部,右侧)
内部块为1格,由3个边组成,与前面的外壳完全一样,但Z值较低
1格容器,将所有三块相对放置,并在右下角应用一个坚实的背景补丁
1个带有溢出的容器:隐藏时,隐藏栏内的内部块,当它归零时
这总共有5个div。
你可能想知道为什么我们需要两个容器?那么,这可能是一个棘手的部分,但我会尽力解释。
我们每栏至少需要一个容器(相对于前面的壳体,后面的壳体和内部的模块)。我们知道我们的酒吧应该是可扩展的,所以我们用百分比来操纵酒吧的填充值,这就要求我们的酒吧的高度等于酒吧的一边的高度。
看起来不错,但是等一下,看起来还有另一个问题 - 应该有一个隐藏内部块的选项,这意味着它应该“在酒吧下面”并隐藏在那里。你可以说我们有一个解决方案 - 溢出:隐藏,对不对?是的,但不是那个容器,因为它的高度比杆的实际高度短。这就是为什么我们添加另一个容器,并应用溢出:隐藏。
希望这是有道理的。让我们继续。
挑战2 - 图表持有者
图表持有人应该
用三维轴和三面(背景,底部,左)
独立于后台
适应条数及其属性(高度,宽度等)
从外面有X和Y轴标签
我们需要什么:
1个无序列表
X轴标签的每个列表项中的1个元素
每个列表项目内部有1个栏
1个列表项,其中有一个无序列表,用于Y轴标签
嗯,无序列表?使用条形图的定义列表是否更有意义?那么,它可能更多的语义,但我们不能使用它,因为我们必须将每个酒吧和自己的X轴标签包装在一个容器中,以便相对定位它们。
好的,但为什么我们不使用列表项而不是第二个容器呢?嗯,我们不能这样做,因为我们必须将X轴标签放在图的外面,因为我们知道吧的第二个容器隐藏了溢出它的任何内容,我们将使用列表项来确保所有元素都被正确定位。
实施
现在我们有了一个策略,让我们把它转换成代码。
请注意,本教程中不会使用供应商前缀。当然,您可以在演示的CSS文件中找到它们。
挑战#1 - 一个可移动的内部块的酒吧
50
让我们再次回顾一下每个元素的目的:
酒吧包装 - 隐藏。酒吧内,当它滑落下面的酒吧
bar-container - 相对位置.bar-foreground,.bar-inner,.bar-foreground,并将补丁放置在底角
酒吧背景 - 创建三面的外壳:背部,底部,左侧
酒吧内 - 最重要的部分可能 - 内部块
酒吧前景 - 创建三面的外壳:前,上,右
首先,让我们风格的容器。
/* Bar wrapper - hides the inner bar when it goes below the bar, required */
.bar-wrapper {
overflow: hidden;
}
/* Bar container - this guy is a real parent of a bar's parts - they all are positioned relative to him */
.bar-container {
position: relative;
margin-top: 2.5em; /* should be at least equal to the top offset of background casing */
/* because back casing is positioned higher than actual bar */
width: 12.5em; /* required, we have to define the width of a bar */
}
/* right bottom patch - make sure inner bar's right bottom corner is "cut" when it slides down */
.bar-container:before {
content: "";
position: absolute;
z-index: 3; /* to be above .bar-inner */
bottom: 0;
right: 0;
/* Use bottom border to shape triangle */
width: 0;
height: 0;
border-style: solid;
border-width: 0 0 2.5em 2.5em;
border-color: transparent transparent rgba(183,183,183,1);
}
请注意,我们将.bar-container的宽度设置为12.5em。这个数字是酒吧的正面和右边宽度的总和 - 在我们的例子中是10 + 2.5 = 12.5
我们还使用边框来塑造三角形,并将其放置在.bar-container的右下角,以确保在竖直移动时内栏的“边”被切割。我们使用:before伪类生成这个元素; 我们将在本教程中使用:之前和之后:伪类很多。
现在让我们来设计背部外壳:
/* Back panel */
.bar-background {
width: 10em;
height: 100%;
position: absolute;
top: -2.5em;
left: 2.5em;
z-index: 1; /* just for reference */
}
.bar-background:before,
.bar-background:after {
content: "";
position: absolute;
}
/* Bottom panel */
.bar-background:before {
bottom: -2.5em;
right: 1.25em;
width: 10em;
height: 2.5em;
transform: skew(-45deg);
}
/* Left back panel */
.bar-background:after {
top: 1.25em;
right: 10em;
width: 2.5em;
height: 100%;
/* skew only the Y-axis */
transform: skew(0deg, -45deg);
}
正如你所看到的,我们把2.5em的套管向右移动。果然,我们歪斜了左右两边45度。请注意,我们将第一个偏移值设置为0deg,第二个偏移值设置为-45deg,这使我们能够垂直倾斜该元素。
现在是时候风格的前壳。
/* Front panel */
.bar-foreground {
z-index: 3; /* be above .bar-background and .bar-inner */
}
.bar-foreground,
.bar-inner {
position: absolute;
width: 10em;
height: 100%;
top: 0;
left: 0;
}
.bar-foreground:before,
.bar-foreground:after,
.bar-inner:before,
.bar-inner:after {
content: "";
position: absolute;
}
/* Right front panel */
.bar-foreground:before,
.bar-inner:before {
top: -1.25em;
right: -2.5em;
width: 2.5em;
height: 100%;
background-color: rgba(160, 160, 160, .27);
transform: skew(0deg, -45deg);
}
/* Top front panel */
.bar-foreground:after,
.bar-inner:after {
top: -2.5em;
right: -1.25em;
width: 100%;
height: 2.5em;
background-color: rgba(160, 160, 160, .2);
transform: skew(-45deg);
}
这里没有什么新东西,一切和后面的箱体样式一样,我们只是用不同的方向。
好的部分是,我们将这些样式应用于前部壳体和内部块体。为什么不?他们的形状完全一样。
好吧,现在我们还没有应用内部块的样式。
.bar-inner {
z-index: 2; /* to be above .bar-background */
top: auto; /* reset position top */
background-color: rgba(5, 62, 123, .6);
height: 0;
bottom: -2.5em;
color: transparent; /* hide text values */
transition: height 1s linear, bottom 1s linear;
}
/* Right panel */
.bar-inner:before {
background-color: rgba(5, 62, 123, .6);
}
/* Top panel */
.bar-inner:after {
background-color: rgba(47, 83, 122, .7);
}
大!酒吧都设置。让我们继续看图表。
挑战2 - 图表支架(带有轴标签)
2011
2012
25%
50%
75%
100%
正如您所看到的,我们使用无序列表和项目内的span元素来定位X轴和Y轴标签。
/** Graph Holder container **/
.graph-container {
position: relative; /* required Y axis stuff, Graph Holder's left and bottom sides to be positions properly */
display: inline-block; /* display: table may also work.. */
padding: 0; /* let the bars position themselves */
list-style: none; /* we don't want to see any default
markers */
/* Graph Holder's Background */
background-image: linear-gradient(left , rgba(255, 255, 255, .3) 100%, transparent 100%);
background-repeat: no-repeat;
background-position: 0 -2.5em;
}
这里棘手的部分是背景。我们使用线性渐变来填充图形容器,并将其提升2.5em。为什么?因为我们的图形持有人的底部(我们将下一个样式)是2.5em高,并倾斜了45度,所以在右下角有一个空的空间。
现在让我们设计底部。
/* Graph Holder bottom side */
.graph-container:before {
position: absolute;
content: "";
bottom: 0;
left: -1.25em; /* skew pushes it left, so we move it a bit in opposite direction */
width: 100%; /* make sure it is as wide as the whole graph */
height: 2.5em;
background-color: rgba(183, 183, 183, 1);
/* Make it look as if in perspective */
transform: skew(-45deg);
}
我们把它倾斜45度,稍微向左移一点,以确保它的位置正确。
现在,让我们的风格留在我们的图形持有者的一边:
/* Graph Holder left side*/
.graph-container:after {
position: absolute;
content: "";
top: 1.25em; /* skew pushes it up so we move it down a bit */
left: 0em;
width: 2.5em;
background-color: rgba(28, 29, 30, .4);
/* Make it look as if in perspective */
transform: skew(0deg, -45deg);
}
这里没什么特别的 就像往常一样将元件倾斜45度,并将其稍微推下,以便正确定位。
我们完成了图表的持有者。现在,让我们添加一些魔术到持有我们的酒吧的列表项目:
/* Bars and X-axis labels holder */
.graph-container > li {
float: left; /* Make sure bars are aligned one next to another*/
position: relative; /* Make sure X-axis labels are positioned relatively to this element */
}
/* A small hack to make Graph Holder's background side be wide enough
...because our bottom side is skewed and pushed to the right, we have to compensate it in the graph holder's background */
.graph-container > li:nth-last-child(2) {
margin-right: 2.5em;
}
/* X-axis labels */
.graph-container > li > span {
position: absolute;
left: 0;
bottom: -2em;
width: 80%; /* play with this one if you change perspective depth */
text-align: center;
font-size: 1.5em;
color: rgba(200, 200, 200, .4);
}
这里发生了一些事情。首先,我们把我们的酒吧放在一起。通常情况下,我试图使用浮动块非常小心,但在这种情况下,它完全符合我的意见。
其次,我们在最后一栏添加一些右边距。这样我们确保我们给图表底部的足够的空间显示在右下角。尝试删除它,你会明白我的意思。
好的,我们快到了。剩下的最后一件事是添加Y轴标记。
/* Markers container */
.graph-container > li:last-child {
width: 100%;
position: absolute;
left: 0;
bottom: 0;
}
/* Y-axis Markers list */
.graph-marker-container > li {
position: absolute;
left: -2.5em;
bottom: 0;
width: 100%;
margin-bottom: 2.5em;
list-style: none;
}
/* Y-axis lines general styles */
.graph-marker-container > li:before,
.graph-marker-container > li:after {
content: "";
position: absolute;
border-style: none none dotted;
border-color: rgba(100, 100, 100, .15);
border-width: 0 0 .15em;
background: rgba(133, 133, 133, .15);
}
/* Y-axis Side line */
.graph-marker-container > li:before {
width: 3.55em;
height: 0;
bottom: -1.22em;
left: -.55em;
z-index: 2; /* be above .graph-container:after */
transform: rotate(-45deg);
}
/* Y-axis Background line */
.graph-marker-container li:after {
width: 100%;
bottom: 0;
left: 2.5em;
}
/* Y-axis text Label */
.graph-marker-container span {
color: rgba(200, 200, 200, .4);
position: absolute;
top: 1em;
left: -3.5em; /* just to push it away from the graph.. */
width: 3.5em; /* give it absolute value of left offset */
font-size: 1.5em;
}
正如您所看到的,我们将100%的宽度设置到我们的标记支架上,以便能够在整个图形中绘制,使用虚线边框来设置我们的Y轴线并定位跨度元素,使得Y轴标签为在图表之外。借助:之前和之后:我们可以保持我们的HTML很干净。
那么,我们完成了图表的所有样式的设置,但是我们没有设置一些重要的变量 - 尺寸,颜色和条形填充值!我们说我们的图表是可定制的,对吗?所以,我决定不把变量和其余的代码混合在一起,这样你就可以和他们一起玩。
/****************
* SIZES *
****************/
/* Size of the Graph */
.graph-container,
.bar-container {
font-size: 8px;
}
/* Height of Bars */
.bar-container,
.graph-container:after,
.graph-container > li:last-child {
height: 40em;
}
/****************
* SPACING *
****************/
/* spacing between bars */
.graph-container > li .bar-container {
margin-right: 1.5em;
}
/* spacing before first bar */
.graph-container > li:first-child {
margin-left: 1.5em;
}
/* spacing after last bar */
.graph-container > li:nth-last-child(2) .bar-container {
margin-right: 1.5em;
}
/****************
* Colors *
****************/
/* Bar's Back side */
.bar-background {
background-color: rgba(160, 160, 160, .1);
}
/* Bar's Bottom side */
.bar-background:before {
background-color: rgba(160, 160, 160, .2);
}
/* Bar's Left Back side */
.bar-background:after {
background-color: rgba(160, 160, 160, .05);
}
/* Bar's Front side */
.bar-foreground {
background-color: rgba(160, 160, 160, .1);
}
/* Bar's inner block */
.bar-inner,
.bar-inner:before { background-color: rgba(5, 62, 123, .6); }
.bar-inner:after { background-color: rgba(47, 83, 122, .7); }
/*************************************
* Bars Fill *
* Just an example of filling 3 bars *
*************************************/
.graph-container > li:nth-child(1) .bar-inner { height: 25%; bottom: 0; }
.graph-container > li:nth-child(2) .bar-inner { height: 50%; bottom: 0; }
.graph-container > li:nth-child(3) .bar-inner { height: 75%; bottom: 0; }
在本教程提供的演示中,您不会找到这个部分,因为我在这里做了一些更有趣的事情 - 我使用单选按钮让您在不修改代码的情况下使用变量。随意查看它的源代码。但是,如果您只需要自定义静态图形,请从上方获取代码片段,然后根据您的偏好进行自定义。
结论
让我们来看看本教程中介绍的一些精选的CSS规范/技巧。所以,我们已经使用了
transform:skew()和transform:rotate()为了转换我们的元素,使它们一起产生一个3D对象的错觉
:之前和之后:伪类生成与CSS的元素,并保持我们的HTML标记相对干净
:nth-last-child()和:不是用于定位特定列表项的伪类,并避免向标记中添加额外的类/ ID
线性渐变连同background-position一起部分填充背景元素
rgba()用于alpha透明度的颜色
边界来创建像三角形的形状
- ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY COL2)/ ROWNUMBER() OVER( PARTITION BY COL1 ORDER BY CO
- 干货 | 前端常用的通信技术
- TP-LINK WR941N路由器研究
- ORA-01113问题的简单分析(r6笔记第3天)
- Tensorflow 中 learning rate decay 的奇技淫巧
- hive数据:名词解释
- 巧妙使用exchange partition的一个案例(r6笔记第1天)
- r与rjava
- 使用expect运行动态脚本(r6笔记第19天)
- 数据库日志中一条"异常"信息所包含的细节(r6笔记第18天)
- linux下编辑VI窗口插入与编辑命令
- rman中三个不完全恢复场景(r6笔记第16天)
- 关于delete,drop,truncate的问题 (r6笔记第14天)
- R语言进行分析,比较详细的一篇,亲测过哦
- HTML 教程
- HTML 简介
- html div 标签介绍
- html span 标签介绍
- html a 超链接标签
- HTML Br换行标签介绍
- HTML P段落标签介绍
- HTML br与p标签区别
- Html H 标题标签
- html px em pt长度单位
- HTML form 标签
- HTML radio 单选框
- HTML B 加粗标签
- HTML strong加粗粗体标签
- HTML em 强调标签
- HTML i 斜体标签
- HTML u下划线标签
- HTML s 删除线标签
- Html img 图片标签
- Html上标注sup与下标注sub标签
- HTML nobr 禁止换行标签
- HTML hr 水平线标签
- HTML label 标签
- HTML input 标签
- HTML textarea 标签
- HTML select下拉列表标签
- HTML checkbox 多选框
- HTML font color 标签
- HTML iframe 框架标签
- HTML Table 表格
- HTML dl dt dd 标签
- HTML ol li有序列表标签
- HTML ul li 无序列表标签
- HTML 注释
- CSS 教程
- CSS 简介
- CSS 语法
- CSS Id 和 Class选择器
- CSS 样式的创建
- CSS background 背景介绍
- CSS 文本样式
- CSS font 字体
- CSS A 链接
- CSS ul ol列表样式
- CSS TABLE 样式
- CSS 框模型
- CSS border 边框
- CSS Outlines 轮廓
- CSS 外边距 Margin
- CSS Padding 内边距
- CSS 分组和嵌套选择器
- CSS 尺寸 (Dimension)
- CSS Display 属性
- CSS Position 定位
- CSS Float 浮动
- CSS 水平对齐(Horizontal Align)
- CSS 组合选择符
- CSS 伪类
- CSS 伪元素
- CSS 导航栏
- CSS 下拉菜单
- CSS 图片廊
- CSS 图像透明/不透明
- CSS sprite 图像拼合技术
- CSS 媒体类型
- CSS 属性选择器
- CSS 实例