赞
踩
实现的柱状图应该是:
挑战1 - 带有可伸缩内核的柱子
所以,我们需要:
总共有五个div。
每个柱体我们需要至少一个容器(以保证前三个div的位置),由于我们的柱体内核是可伸缩的,所以我们使用百分比来操纵内核的高度,这就要求容器的高度等于条形图Y轴的高度。
这看起来很好,但是,有另外一个问题,应该有一个选项可以隐藏移动中的内核,这意味着它应该“低于柱体”并且隐藏。你可能会说有一个解决方法 - overflow: hidden,是的,但是它不适用于这里的容器,因为它的高度要比实际的柱体高度短。
挑战2 - 坐标轴
坐标轴应该:
所以,我们需要:
挑战1 - 带有可伸缩内核的柱子
- <div class="bar-wrapper">
- <div class="bar-container">
- <div class="bar-background"></div>
- <div class="bar-inner">50</div>
- <div class="bar-foreground"></div>
- </div>
- </div>
回顾每个元素的用途:
设置容器的样式:
- /* Bar wrapper容器 - 当内核低于柱体高度时隐藏内核,必需的 */
- .bar-wrapper {
- overflow: hidden;
- }
- /* Bar container容器 - 这家伙是柱形图里真正的家长——子元素都是相对于它定位的。*/
- .bar-container {
- position: relative;
- margin-top: 2.5em;
- width: 12.5em;
- }
- /* 右下角的小块 - 确保内核向下滑动时右下角被“切割” */
- .bar-container:before {
- content: "";
- position: absolute;
- z-index: 3;
-
- bottom: 0;
- right: 0;
-
- 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。
我们还使用border属性来创建三角形,并将其放置在 .bar-container的右下角,以确保内核的侧边在垂直移动时能被“切割”。我们使用:before伪类来生成这个元素。
设置.bar-background:
- /* 背面 */
- .bar-background {
- width: 10em;
- height: 100%;
- position: absolute;
- top: -2.5em;
- left: 2.5em;
- z-index: 1;
- }
-
- .bar-background:before,
- .bar-background:after {
- content: "";
- position: absolute;
- }
-
- /* 底面 */
- .bar-background:before {
- bottom: -2.5em;
- right: 1.25em;
- width: 10em;
- height: 2.5em;
- transform: skew(-45deg);
- }
-
- /* 左后面 */
- .bar-background:after {
- top: 1.25em;
- right: 10em;
- width: 2.5em;
- height: 100%;
-
- /* 仅倾斜Y轴 */
- transform: skew(0deg, -45deg);
- }
如你所见,我们将.bar-background向上和向右移动2.5em。当然,我们把左后面和底面倾斜45度。请注意,:after伪元素中将第一个倾斜值设置为0deg,第二个设置为-45度,这样只倾斜元素的Y轴。
接着来设置.bar-foreground:
- /* 前面 */
- .bar-foreground {
- z-index: 3; /* 在 .bar-background 和.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;
- }
-
- /* 右前面 */
- .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);
- }
-
- /* 前面 */
- .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-background的样式一样,只是方向不同。
其中,部分的样式同时应用在了.bar-foreground和.bar-inner元素上,因为它们的样子是完全相同的。
好了,下面我们继续设置内核的样式。
- .bar-inner {
- z-index: 2; /* 在.bar-background的上面 */
- top: auto; /* 重置 top属性 */
- background-color: rgba(5, 62, 123, .6);
- height: 0;
- bottom: -2.5em;
- color: transparent; /* 隐藏文字 */
-
- transition: height 1s linear, bottom 1s linear;
- }
-
- /* 右面 */
- .bar-inner:before {
- background-color: rgba(5, 62, 123, .6);
- }
-
- /* 上面 */
- .bar-inner:after {
- background-color: rgba(47, 83, 122, .7);
- }
柱体的样式就设置好了,接下来我们来看坐标轴。
挑战2 - 坐标轴
- <ul class="graph-container">
- <li>
- <span>2011</span>
- <!-- 此处显示柱状图图的HTML标记 -->
- </li>
- <li>
- <span>2012</span>
- <!-- 此处显示柱状图图的HTML标记 -->
- </li>
- <li>
- <ul class="graph-marker-container">
- <li><span>25%</span></li>
- <li><span>50%</span></li>
- <li><span>75%</span></li>
- <li><span>100%</span></li>
- </ul>
- </li>
- </ul>
我们在项目中使用无序列表和span元素来定位X轴和Y轴标签。
这里有一个小点,我们使用线性渐变填充容器背景并将其提升2.5em,为什么?因为坐标轴的底端(我们将在下一个样式中设置)高度是2.5em。而且坐标轴倾斜了45度,所以右下角有一个空白区域。
坐标轴的X轴样式:
- /* X轴 */
- .graph-container:before {
- position: absolute;
- content: "";
-
- bottom: 0;
- left: -1.25em; /* 倾斜会将它向左推,所以我们将它向相反的方向移动一点。*/
-
- width: 100%; /* 确保它和整个组件一样宽 */
-
- height: 2.5em;
- background-color: rgba(183, 183, 183, 1);
-
- transform: skew(-45deg);
- }
我们把它倾斜45度,然后向左移动一点,以确保它的位置正确。
坐标轴的Y轴样式:
- /* Y轴 */
- .graph-container:after {
- position: absolute;
- content: "";
-
- top: 1.25em; /* 倾斜会将其向上推,因此我们将其向下移动一点。*/
- left: 0em;
-
- width: 2.5em;
- background-color: rgba(28, 29, 30, .4);
-
- transform: skew(0deg, -45deg);
- }
一样将元素倾斜45度,然后向下推一点,以便正确定位。
坐标轴的基本设置就是这些,接下来我们继续设置列表项里面的样式:
- .graph-container > li {
- float: left; /* 水平排列 */
- position: relative;
- }
- .graph-container > li:nth-last-child(2) {
- margin-right: 2.5em;
- }
- /* X轴的文字标签 */
- .graph-container > li > span {
- position: absolute;
- left: 0;
- bottom: -2em;
- width: 80%;
- text-align: center;
-
- font-size: 1.5em;
- color: rgba(200, 200, 200, .4);
- }
这里有两个要注意的点。首先,我们使用浮动将柱体水平排列。通常情况下都应该非常小心地使用浮动,它会带来高度塌陷等布局问题。所以,在这里你可以尝试变为设置display:inline-block来实现。
第二,我们在最后一个柱体上添加了一些右边距。这样我们就可以确保给坐标轴底部留出足够的空间,试着去掉它,你就会明白我的意思。
OK,我们就快完成了。最后要做的是添加Y轴的文字标记。
- /* 文字标记的容器 */
- .graph-container > li:last-child {
- width: 100%;
- position: absolute;
- left: 0;
- bottom: 0;
- }
-
- /* Y轴文字标记列表 */
- .graph-marker-container > li {
- position: absolute;
- left: -2.5em;
- bottom: 0;
- width: 100%;
- margin-bottom: 2.5em;
- list-style: none;
- }
-
- /* Y轴线条常规样式 */
- .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轴侧线 */
- .graph-marker-container > li:before {
- width: 3.55em;
- height: 0;
- bottom: -1.22em;
- left: -.55em;
- z-index: 2;
- transform: rotate(-45deg);
- }
-
- /* Y轴背景线 */
- .graph-marker-container li:after {
- width: 100%;
- bottom: 0;
- left: 2.5em;
- }
-
- /* Y轴文本标签 */
- .graph-marker-container span {
- color: rgba(200, 200, 200, .4);
- position: absolute;
-
- top: 1em;
- left: -3.5em;
- width: 3.5em;
-
- font-size: 1.5em;
- }
如你所见,我们将文字标记容器的宽度设置为100%,使得背景线能够覆盖整个坐标轴,使用虚线边框设置Y轴线条的样式并定位span元素,使文字标签位于坐标轴的外侧。使用:before和:after伪元素,可以减少HTML的代码量,让页面保持干净。
到这里,我们已经完成了柱状图的所有样式设置,但是我们缺少一些重要的变量——大小、颜色和条形填充值!上面说过我们的图表是可定制的,所以,我决定不把变量和其他代码混合在一起,这样你就可以更方便的自定义它们了。
- /****************
- * 尺寸 *
- ****************/
- /* 图表的整体大小 */
- .graph-container,
- .bar-container {
- font-size: 8px;
- }
- /* 柱体的高度 */
- .bar-container,
- .graph-container:after,
- .graph-container > li:last-child {
- height: 40em;
- }
-
- /****************
- * 间距 *
- ****************/
- /* 柱体的间距 */
- .graph-container > li .bar-container {
- margin-right: 1.5em;
- }
- /* 第一个柱体的左边距 */
- .graph-container > li:first-child {
- margin-left: 1.5em;
- }
- /* 最后一个柱体的右边距 */
- .graph-container > li:nth-last-child(2) .bar-container {
- margin-right: 1.5em;
- }
-
- /****************
- * 颜色 *
- ****************/
- /* 柱体的背面颜色 */
- .bar-background {
- background-color: rgba(160, 160, 160, .1);
- }
- /* 柱体的底面颜色 */
- .bar-background:before {
- background-color: rgba(160, 160, 160, .2);
- }
- /* 柱体的左后面颜色 */
- .bar-background:after {
- background-color: rgba(160, 160, 160, .05);
- }
- /* 柱体的正面颜色 */
- .bar-foreground {
- background-color: rgba(160, 160, 160, .1);
- }
- /* 内核的颜色 */
- .bar-inner,
- .bar-inner:before { background-color: rgba(5, 62, 123, .6); }
- .bar-inner:after { background-color: rgba(47, 83, 122, .7); }
-
- /*************************************
- * 内核的高度 *
- *************************************/
- .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; }
总结
源码下载地址:https://download.csdn.net/download/yuan_jlj/13696000
原文:https://mp.weixin.qq.com/s/dy8SFN_Rb48z4vluYIgVMw
让我们回顾一下文章中介绍的一些CSS规范/技术。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。