html - 使用纯 HTML/CSS 创建树状图(多个父级)

标签 html css tree

我想创建一个有多个父节点的树状图。这个想法是为 Dota 2 元素创建一个图表,其中可以将多个元素制成一个元素(加上一个配方),和/或可以将一个元素制成多种可能性(不止一个父元素)。

enter image description here

我的引用资料之一来自 thecodeplayer's code .

这里是 my work到目前为止在 jsfiddle 上。

<div class="items">
  <ul>
    <li>
        <a href="#" class="">Dagon</a>
        <a href="#" class="">Veil of Discord</a>
        <a href="#" class="">Other Parent Item</a>
      <ul>
        <li>
          <a href="#">Null Talisman</a>
            <ul>
            <li><a href="#">Circlet</a></li>
            <li><a href="#">Mantle of Intelligence</a></li>
            <li><a href="#">Recipe: Null Talisman</a></li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</div>

CSS

<style type="text/css">
* {
  margin: 0 auto;
  padding: 0;
  text-align: center;
  color: black;
  font-family: tahoma;
}

.items ul {
  padding-top: 20px;
  position: relative;
}

/* Make all children "inline" */
.items li {
  float: left;
  text-align: center;
  list-style-type: none;
  position: relative;
  padding: 20px 5px 0 5px;
}

/* Add horizontal connector. Note: they are 2 pseudo-elements */
.items li::before, .items li::after {
  content: '';
  position: absolute;
  top: 0;
  right: 50%;
  width: 50%;
  height: 45px;
  z-index: -1;
  border-top: 1px solid red;
}

.items li::after {
  border-left: 1px solid green;
  left: 50%;
  right: auto;
}

/* Remove left and right connector from a single child */
.items li:only-child::after, .items li:only-child::before {
  display: none;
}

.items li:only-child {
  padding-top: 0;
}

/* Remove "outer" connector */
.items li:first-child::before, .items li:last-child::after {
  border: 0 none;
}
/* Add back the down connector for last node */
.items li:last-child::before {
  border-right: 1px solid blue;
  border-radius: 0 5px 0 0;
}

/* Add curve line to the first child's connector */
.items li:first-child::after {
  border-radius: 5px 0 0 0;
}


/* Add down connector from parent */
.items ul ul::before {
  content: '';
  border-left: 1px solid magenta;
  z-index: -1;
  height: 20px;
  position: absolute;
  top: 0px;
  left: 50%;
  width: 0;
}

/* Add cosmetic for each item */
.items li a {
  font-size: 12px;
  background-color: white;
  border: 1px solid #ccc;
  padding: 5px 10px;
  text-decoration: none;
  display: inline-block;
  border-radius: 4px;
}

.items li a:hover {
  background-color: #EEE;
}

/* Experimental for multiple parents */
/* Add margin for the parents */
.items li a+a {
  position: relative;
  margin-bottom: 12px;
}
/* Implement also for the first parent */
.items li a:first-child {
  position: relative;
  margin-bottom: 12px;
}

/* 
- Add "down" connector (vertical line) from each parent 
- Currently it will also select the single parent
*/
.items li > a:not(:only-child)::after{
  content: '';
  position: absolute;
  border-right: 1px solid pink;
  top: 20px;
  height: 20px;
  width: 0;
  left: 50%;
  z-index: -1;
}

/* Starting to fvcked up from here */

/* Making the horizontal connector line after each multiple parent */
.items li > a:not(:only-of-type):not(:last-of-type)::before {
  content: '';
  position: absolute;
  top: 40px;
  left: auto;
  width: 100%;
  border-top: 1px solid indigo;
}

.items li > a:last-of-type:not(:first-child)::before {
  content: '';
  position: absolute;
  top: 40px;
  right: auto;
  width: 100%;
  border-top: 1px solid indigo;
}
</style>

我的尝试(失败了,或者不够好)是创建另一个伪元素(::before 或::after) <a> (多父)元素。

最佳答案

我建议做的是将 left 属性设置为 50% 在最左边和最右边的 ::before 伪-类,然后调整最左边和中间伪类的宽度以覆盖偏移量。

我还建议将向下连接器的 top 增加 2px 以避免尖锐的“悬垂”。

有点草率,但这是我的尝试:

* {
  margin: 0 auto;
  padding: 0;
  text-align: center;
  color: black;
  font-family: tahoma;
}

.items ul {
  padding-top: 20px;
  position: relative;
}


/* Make all children "inline" */

.items li {
  float: left;
  text-align: center;
  list-style-type: none;
  position: relative;
  padding: 20px 5px 0 5px;
}


/* Add horizontal connector. Note: they are 2 pseudo-elements */

.items li::before,
.items li::after {
  content: '';
  position: absolute;
  top: 0;
  right: 50%;
  width: 50%;
  height: 45px;
  z-index: -1;
  border-top: 1px solid red;
}

.items li::after {
  border-left: 1px solid green;
  left: 50%;
  right: auto;
}


/* Remove left and right connector from a single child */

.items li:only-child::after,
.items li:only-child::before {
  display: none;
}

.items li:only-child {
  padding-top: 0;
}


/* Remove "outer" connector */

.items li:first-child::before,
.items li:last-child::after {
  border: 0 none;
}


/* Add back the down connector for last node */

.items li:last-child::before {
  border-right: 1px solid blue;
  border-radius: 0 5px 0 0;
}


/* Add curve line to the first child's connector */

.items li:first-child::after {
  border-radius: 5px 0 0 0;
}


/* Add down connector from parent */

.items ul ul::before {
  content: '';
  border-left: 1px solid magenta;
  z-index: -1;
  height: 20px;
  position: absolute;
  top: 2px; /* Changed */
  left: 50%;
  width: 0;
}


/* Add cosmetic for each item */

.items li a {
  font-size: 12px;
  background-color: white;
  border: 1px solid #ccc;
  padding: 5px 10px;
  text-decoration: none;
  display: inline-block;
  border-radius: 4px;
}

.items li a:hover {
  background-color: #EEE;
}


/* Experimental for multiple parents */


/* Add margin for the parents */

.items li a+a {
  position: relative;
  margin-bottom: 12px;
}


/* Implement also for the first parent */

.items li a:first-child {
  position: relative;
  margin-bottom: 12px;
}


/* 
- Add "down" connector (vertical line) from each parent 
- Currently it will also select the single parent
*/

.items li>a:not(:only-child)::after {
  content: '';
  position: absolute;
  border-right: 1px solid pink;
  top: 20px;
  height: 20px;
  width: 0;
  left: 50%;
  z-index: -1;
}


/* Starting to fvcked up from here */


/* Making the horizontal connector line after each multiple parent */

.items li>a:not(:only-of-type):not(:last-of-type)::before {
  content: '';
  position: absolute;
  top: 40px;
  left: auto;
  width: 110%; /* Changed */
  border-top: 1px solid indigo;
}

.items li>a:last-of-type:not(:first-child)::before {
  content: '';
  position: absolute;
  top: 40px;
  right: auto;
  width: 42%; /* Changed */
  border-top: 1px solid indigo;
}


/* ADDED STYLES */
.items li>a:first-of-type:first-child::before {
  left: 50%;
}

.items li>a:last-of-type:last-child::before {
  left: 50%;
}
<div class="items">
  <ul>
    <li>
      <a href="#" class="">Dagon</a>
      <a href="#" class="">Veil of Discord</a>
      <a href="#" class="">Other Parent Item</a>
      <ul>
        <li>
          <a href="#">Null Talisman</a>
          <ul>
            <li><a href="#">Circlet</a></li>
            <li><a href="#">Mantle of Intelligence</a></li>
            <li><a href="#">Recipe: Null Talisman</a></li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</div>

关于html - 使用纯 HTML/CSS 创建树状图(多个父级),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49809112/

相关文章:

javascript - onclick一个元素,div的滑动切换

javascript - 如何使用 jQuery(schema.org 微格式)查找和读取元数据?

html - 第 n 个子选择器 css

javascript - 如何比较两个 CSS 选择器?

python - 该代码如何找到二叉树的最小深度?

tree - 如何通过索引获取子树?

sql - 如何用SQL表示数据树?

html - 如何将文字放在图片之前?

html - Bootstrap - 图像上的固定位置

javascript - 视差滚动 : Unwanted gap in between layers