使用 CSS Grid 创建条形图

Avatar of Preethi
Preethi

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费积分!

如果您正在寻找更易于管理的方式来创建条形图,或者正在寻找使用 CSS Grid 布局的用例,我帮您搞定!

在我们开始处理图形之前,我想谈谈编写条形代码,何时 Grid 是图形的良好方法,我们还将介绍在开始之前可能需要考虑的一些代码选择。

前言

条形是一个非常基本的形状:您可以使用 CSS 的 widthheight、网格或表格单元格的数量等来控制其尺寸,具体取决于您如何编写代码。就图形而言,我们主要想要控制的是图形中条形的高度。

使用网格单元格(例如 此处)控制高度对于高度以固定值递增的设计很方便——没有中间值。例如,手机中的信号条或当您不介意设置大量网格行以更好地控制条形高度直至其最小值时,例如 IRL 图形纸。

Five vertical purple bars that get progressively taller from left to right like a signal indicator on a cell phone.

对于我的图形,我还想要渐变条形以及垂直和水平轴标签。因此,为了简化操作,我决定使用渐变大小来控制条形高度,并根据所需的垂直轴标签数量确定网格行数。

此外,除了图形的内容——条形、轴标签和标题外,HTML 中不会存在任何数据,例如有关条形颜色和尺寸的数据。

data-* 属性用于在 HTML 中提供此类信息。但我不希望在编码时在 HTML 和 CSS 之间来回切换,并决定完全将内容与设计分离。这完全取决于您。如果您觉得使用 data-* 可能有利于您的项目,那就试试吧。

我在下面创建了一个图表,您可能会发现它在阅读代码时很有用。它描绘了图形和包含它的网格。数字代表网格线。

Four gold cylindrical bars on a graph where the y-axis goes from 0 to 100 in increments of 10 and the x-axis is labeled with different smiley face emoji.

让我们编写代码吧。

HTML 代码

Grid 可以自动将项目放置在上下和左右方向。为了利用这一点,我将按y 轴标签(从上到下)、条形和 x 轴标签(从左到右)的顺序添加图形内容。这样,我只需要编写 HTML 标记,CSS 就会自动帮我放置条形了!

<figure aria-hidden="true">
    <div class="graph">
        <span class="graphRowLabel">100</span>
        <span class="graphRowLabel">90</span>
        <span class="graphRowLabel">80</span>
        <span class="graphRowLabel">70</span>
        <span class="graphRowLabel">60</span>
        <span class="graphRowLabel">50</span>
        <span class="graphRowLabel">40</span>
        <span class="graphRowLabel">30</span>
        <span class="graphRowLabel">20</span>
        <span class="graphRowLabel">10</span>
        <div  class="graphBar"></div>
        <div  class="graphBar"></div>
        <div  class="graphBar"></div>
        <div  class="graphBar"></div>
        <div  class="graphBar"></div>
        <span><sup>Y </sup>&frasl;<sub> X</sub></span>
        <span class="graphColumnLabel">&#x1f60a;</span>
        <span class="graphColumnLabel">&#x1f604;</span>
        <span class="graphColumnLabel">&#x263a;&#xfe0f;</span>
        <span class="graphColumnLabel">&#x1f601;</span>
        <span class="graphColumnLabel">&#x1f600;</span>
    </div>
    <figcaption>Made with CSS Grid &#x1f49b;</figcaption>
</figure>

<span class="screenreader-text">Smiling face with squinting eyes: 10%, grinning face with squinting eyes: 65%, smiling face: 52%, grinning face with smiling eyes: 100%, and grinning face: 92%.</span>

注意:如果您对可访问性感兴趣,请知道我不是可访问性专家。但是当我尝试使条形变得可访问时,屏幕阅读器的体验非常糟糕。使用 aria-labelledby 效果也不好。因此,我添加了图形的文本描述并将其隐藏在视觉显示中。这使得阅读更加自然。

CSS 代码

这就是魔法发生的地方。

/* The grid container */
.graph {
  display: grid;
  grid:  repeat(10, auto) max-content / max-content repeat(5, auto);
  /* ... */
}

我们使用这两行 CSS 代码在网格中定义了11 行和 6 列:10 行自动调整大小,1 行调整为其“最大内容”;1 列调整为其“最大内容”,5 列自动调整大小。CSS Grid 太棒了。

图形条需要覆盖从第一行到倒数第二行的网格,因为我们使用最后一行作为 x 轴标签。我为条形设置了 100% 的高度,以及 grid-row: 1 / -2;,这意味着“从第一条水平网格线跨越到倒数第二条”。

/* A grid item */
.graphBar{
  height: 100%;
  grid-row: 1 / -2;
}

条形还具有向上的线性渐变。渐变彩色部分的大小是条形高度的指示器,而条形高度又取自每个条形自身的 CSS 规则作为自定义变量。

/* A grid item */
.graphBar{
  /* Same as before */
  background: palegoldenrod linear-gradient(to top, gold var(--h), transparent var(--h));
}

为了控制条形的宽度和它们之间的间距,我使用固定宽度并使用 justify-self: center; 将其居中。如果需要,您可以使用 grid-column-gap 在列之间创建间隙。以下是将所有条形内容整合在一起的完整代码

/* A grid item */
.graphBar{
  height: 100%;
  grid-row: 1 / -2;
  background: palegoldenrod linear-gradient(to top, gold var(--h), transparent var(--h));
  width: 45px;
  justify-self: center;
}

您是否注意到其中的 CSS 变量 (var(--h))?我们需要指定每个条形的精确高度,并且可以使用该变量以百分比的形式确定背景渐变的高度

.graphBar:nth-of-type(1) {
  grid-column: 2;
  --h: 10%;
}
.graphBar:nth-of-type(2) {
  grid-column: 3;
  --h: 65%;
}
.graphBar:nth-of-type(3) {
  grid-column: 4;
  --h: 52%;
}
/* and so on... */

就是这样!样式设置完成后,图形如下所示

这里有一些演示特定的样式,但我们到目前为止涵盖的所有内容都将为您提供条形图的基本框架。我创建的 y 轴标签位于网格线上方,以获得稍微更简洁的布局。我通过使用 border-radius 和椭圆形伪元素分别获得了条形的圆柱形和横截面边缘。如果没有它们,您将得到一个直上直下的矩形条。