我们正在构建的组织结构图
这是我们将要创建的 css 图表:
See the Pen CSS Charts: How to Create a Horizontal Organizational Chart by Envato Tuts+ (@tutsplus) on CodePen.
在最大 1300 像素宽的屏幕上,图表将以垂直布局显示。在较大的屏幕上,其数据将水平显示。请务必通过在大屏幕上打开演示并调整浏览器窗口大小来检查此行为。
1.指定容器
我们的图表将存在于一个容器中:
<div class="container"> <!-- chart goes here --></div>
2.定义一些基本样式
在检查其级别之前,我们将设置一些重置规则和辅助类:
:root {
--level-1: #8dccad;
--level-2: #f5cc7f;
--level-3: #7b9fe0;
--level-4: #f27c8d;
--black: black;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
ol {
list-style: none;
}
body {
margin: 50px 0 100px;
text-align: center;
font: 20px/1.5 "Inter", sans-serif;
}
h1,
h2,
h3,
h4 {
font-size: inherit;
}
.container {
max-width: 800px;
padding: 0 10px;
margin: 0 auto;
display: grid;
align-items: center;
justify-content: center;
grid-column-gap: 20px;
grid-template-columns: auto auto;
}
.rectangle {
position: relative;
padding: 20px;
width: 200px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.15);
}
注意rectangle课堂。我们将把它附加到图表的每个节点/元素上。
此外,请注意容器样式。感谢 CSS Grid,我们可以将图表分成两部分。第一个将包括第一级,而第二个将包括所有其他级别。另外,我们将给容器一个最大宽度,它只影响较小的屏幕。
注意:为简单起见,我没有优化 CSS。这将帮助您更好地了解每个级别的样式。
3.指定级别
在这一点上,我们将仔细研究图表水平。您可能还记得上一个教程中的内容,我们将有四个:
1级
第一级将仅包含一个节点:
html
为了描述它,我们将使用一个h1标签,因为它是我们图表中最重要的部分:
<h1 class="level-1 rectangle">...</h1>
CSS
我们将使用它的::before伪元素来创建第一层和第二层之间的关系:
/*CUSTOM VARIABLES HERE*/
.level-1 {
background: var(--level-1);
}
.level-1::before {
content: "";
position: absolute;
top: 50%;
left: 100%;
transform: translateY(-50%);
width: 20px;
height: 2px;
background: var(--black);
}
2 级
第二级将由两个节点组成:
HTML
为了描述它,我们将使用带有两个列表项的有序列表。每个列表项将包含一个h2元素:
<ol class="level-2-wrapper">
<li>
<h2 class="level-2 rectangle">...</h2>
</li>
<li>
<h2 class="level-2 rectangle">...</h2>
</li>
</ol>
CSS
每个列表项都将充当一个包含两列的网格容器。我们将其第一个的内容定位在列轴的上边缘,而将其最后一个的内容定位在列轴的下边缘。
我们还将定义元素的::before和::after伪h2元素。他们的工作将是创建相邻级别之间的关联:
/*CUSTOM VARIABLES HERE*/
.level-2-wrapper {
position: relative;
padding-left: 20px;
border-left: 2px solid var(--black);
}
.level-2-wrapper::before {
display: none;
content: "";
position: absolute;
top: -20px;
left: 10px;
width: 2px;
height: calc(100% + 40px);
background: var(--black);
}
.level-2-wrapper::after {
display: none;
content: "";
position: absolute;
left: 10px;
bottom: -20px;
width: calc(100% - 10px);
height: 2px;
background: var(--black);
}
.level-2-wrapper > li {
position: relative;
display: grid;
align-items: flex-start;
grid-column-gap: 20px;
grid-template-columns: auto auto;
}
.level-2-wrapper > li:last-child {
margin-top: 100px;
align-items: flex-end;
}
.level-2 {
background: var(--level-2);
}
.level-2::before {
content: "";
position: absolute;
top: 50%;
right: 100%;
transform: translateY(-50%);
width: 20px;
height: 2px;
background: var(--black);
}
.level-2::after {
content: "";
position: absolute;
top: 50%;
left: 100%;
transform: translateY(-50%);
width: 20px;
height: 2px;
background: var(--black);
}
3 级
第三级将包括四个节点。
我们将前两个节点与第二层的第一个节点相关联,而后两个节点与其第二个节点相关联:
HTML
尽管如此,在第二级所在的初始列表中,我们将定义两个新列表。它们中的每一个都将包含两个列表项。对于每个项目将指定一个h3元素:
<ol class="level-2-wrapper">
<li>
...
<ol class="level-3-wrapper">
<li>
<h3 class="level-3 rectangle">...</h3>
</li>
<li>
<h3 class="level-3 rectangle">...</h3>
</li>
</ol>
</li>
<li>
...
<ol class="level-3-wrapper">
<li>
<h3 class="level-3 rectangle">...</h3>
</li>
<li>
<h3 class="level-3 rectangle">...</h3>
</li>
</ol>
</li>
</ol>
CSS
与上一个级别类似,我们将每个列表项视为一个网格容器并将其分成两列。
同样,我们将设置元素的::before和::after伪h3元素以创建所需的连接:
/*CUSTOM VARIABLES HERE*/
.level-3-wrapper {
position: relative;
top: 34px;
padding-left: 20px;
border-left: 2px solid var(--black);
}
.level-3-wrapper::before {
display: none;
content: "";
position: absolute;
top: 0;
left: 10px;
width: 2px;
height: 100%;
background: var(--black);
}
.level-3-wrapper::after {
display: none;
content: "";
position: absolute;
left: 10px;
bottom: 0px;
width: calc(100% - 10px);
height: 2px;
background: var(--black);
}
.level-3-wrapper > li {
display: grid;
grid-column-gap: 20px;
grid-template-columns: auto auto;
}
.level-3-wrapper > li:last-child {
margin-top: 80px;
}
.level-2-wrapper > li:last-child .level-3-wrapper {
top: -34px;
}
.level-3 {
background: var(--level-3);
}
.level-3::before {
content: "";
position: absolute;
top: 50%;
right: 100%;
transform: translateY(-50%);
width: 20px;
height: 2px;
background: var(--black);
}
.level-3::after {
content: "";
position: absolute;
top: 50%;
left: 100%;
transform: translateY(-50%);
width: 20px;
height: 2px;
background: var(--black);
}
注意:如果您的文本节点跨越到单独的行,则必须更改以下硬编码值:top: 34px和top: -34px.
级别 #4
第四级需要 16 个节点。这些将平均分配到四个列表中。
每个第三级节点将包含一个列表:
HTML
尽管如此,在第二级所在的初始列表中,我们将定义四个新列表。它们中的每一个都将包含四个列表项。对于每个项目,我们将指定一个h4元素:
<ol class="level-2-wrapper">
<li>
...
<ol class="level-3-wrapper">
<li>
...
<ol class="level-4-wrapper">
<li>
<h4 class="level-4 rectangle">...</h4>
</li>
...
</ol>
</li>
<li>
...
<ol class="level-4-wrapper">
<li>
<h4 class="level-4 rectangle">...</h4>
</li>
...
</ol>
</li>
</ol>
</li>
<li>
...
<ol class="level-3-wrapper">
<li>
...
<ol class="level-4-wrapper">
<li>
<h4 class="level-4 rectangle">...</h4>
</li>
...
</ol>
</li>
<li>
...
<ol class="level-4-wrapper">
<li>
<h4 class="level-4 rectangle">...</h4>
</li>
...
</ol>
</li>
</ol>
</li>
</ol>
CSS
再一次,我们将执行相同的操作。首先,我们将使用 CSS Grid 为第四级节点创建布局。然后,我们将指定用于建立连接的目标元素所需的伪元素:
/*CUSTOM VARIABLES HERE*/
.level-4-wrapper {
position: relative;
top: 34px;
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-column-gap: 20px;
padding-left: 20px;
}
.level-4-wrapper::before {
content: "";
position: absolute;
top: 0;
left: 0;
width: 2px;
height: 50%;
background: var(--black);
}
.level-3-wrapper > li:last-child .level-4-wrapper {
top: -34px;
}
.level-3-wrapper > li:last-child .level-4-wrapper::before {
top: auto;
bottom: 0;
}
.level-4 {
background: var(--level-4);
}
.level-4::before {
content: "";
position: absolute;
top: 50%;
right: 100%;
transform: translateY(-50%);
width: 20px;
height: 2px;
background: var(--black);
}
注意:如果您的文本节点跨越到单独的行,则必须更改以下硬编码值: top: 34px 和 top: -34px.
4.响应迅速
正如您已经猜到的那样,我们的样式遵循桌面优先的方法。一般来说,我更喜欢先构建大屏幕,然后再开发更小、更简单的屏幕。
在 1301 像素和 1650 像素之间的屏幕上,图表仍将处于水平模式,但其节点的宽度将更小(200 像素而不是 150 像素)。
在最大 1300px 宽的屏幕上,所有图表节点都将垂直显示,如下所示:
与水平布局不同,此处文本节点的宽度和排版根据其级别而有所不同。级别越高,宽度和排版就越大。
当然,您可以根据您的内容随意更改这些断点。
值得注意的是,这种设计与垂直图表的响应式布局相比略有不同:
如果您想知道,这个新实现背后没有任何特定目的。我只是想向您展示两种不同的响应式布局。随意在您的页面中使用任何这些。
以下是响应式样式:
@media screen and (max-width: 1650px) {
.rectangle {
width: 150px;
}
}
@media screen and (max-width: 1300px) {
body {
font-size: 16px;
}
h1,
h2,
h3,
h4 {
font-size: revert;
}
.rectangle {
padding: 20px 10px;
width: auto;
}
.container {
display: block;
}
.level-1 {
margin-bottom: 20px;
}
.level-1::before,
.level-2::after,
.level-3::after {
display: none;
}
.level-2-wrapper::before,
.level-2-wrapper::after,
.level-3-wrapper::before,
.level-3-wrapper::after,
.level-2-wrapper > li,
.level-3-wrapper > li {
display: block;
}
.level-2-wrapper {
padding-left: 30px;
border-left: none;
}
.level-2-wrapper > li:last-child {
margin-top: 50px;
}
.level-2-wrapper > li:last-child .level-3-wrapper,
.level-3-wrapper > li:last-child .level-4-wrapper,
.level-3-wrapper,
.level-4-wrapper {
top: 0;
}
.level-3-wrapper {
padding: 20px 0 20px 30px;
border-left: none;
}
.level-3-wrapper > li:last-child {
margin-top: 50px;
}
.level-4-wrapper {
padding: 20px 0 0 30px;
grid-template-columns: repeat(2, 1fr);
}
.level-4-wrapper > li:first-child {
margin-bottom: 20px;
}
.level-4-wrapper::before {
left: 10px;
height: 100%;
}
}
恢复关键字
从上面的样式中,请特别revert注意我们应用于标题的新 CSS 关键字。这将帮助我们恢复他们的默认浏览器样式。令人高兴的是,它的浏览器支持每天都在增长。
结论
这就是今天的全部内容,伙计们!至此,您拥有构建自己的纯 CSS 组织结构图所需的一切。
实际上,在实际场景中,您可能更喜欢使用像Highcharts.js这样功能强大的 javascript 库来创建这样的图表。然而,在不忽略其局限性的情况下突破 CSS 的极限始终是学习和扩展知识的好方法。此外,结合 CSS Grid 和伪元素等工具/功能,您可以完成非常简洁的事情。
- 1级
- html
- CSS
- 2 级
- HTML
- CSS
- 3 级
- HTML
- CSS
- 级别 #4
- HTML
- CSS
- 恢复关键字