我有一个系统,该系统生成节点列表,这些节点之间可能有也可能没有其他元素。我想用连接节点的线水平显示此列表,如下例所示。
两个节点之间的内容是可变的,甚至可以包含图像和表格等更复杂的元素。节点本身仅被标记为文本(点A,点B等)。
在尝试可视化节点的第一次尝试中,我仅使用带有:before
和:after
CSS伪元素的垂直列表来绘制节点之间的线。但是,我很难将这种方法转换为水平列表。
水平方法:(由于下面的Mayank Gupta's answer而更新)
h1, h2 {
margin: 0;
padding: 0;
}
ul {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
flex-direction: row;
text-align: center;
list-style-type: none;
font-size: 1.5em;
}
ul li {
display: flex;
justify-content: flex-start;
flex: 2;
position: relative;
border-bottom: 2px solid #000;
padding-bottom: 10px;
}
ul li:after {
position: absolute;
bottom: -5px;
left: 0;
font-family: "Font Awesome 5 Free";
font-weight: 300;
content: "\f111";
height: 17px;
width: 23px;
background: #fff;
}
ul h2 {
margin: 0 0 0 -1em;
padding: 0;
}
ul li:last-of-type {
border: none;
}
ul li > div {
flex: 0 0 auto;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
<link href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" rel="stylesheet"/>
<ul>
<li>
<h2>Node A</h2>
<div>Content</div>
</li>
<li>
<h2>Node B</h2>
<div>Content</div>
</li>
<li>
<h2>Node C</h2>
</li>
</ul>
此方法存在问题:
我该如何解决这些问题?
答案 0 :(得分:1)
这是我的答案-本质上,您将display:flex
添加到ul
列表中,并通过使用flex:0 0 auto
和固定宽度来确保节点具有固定大小。这样可以使上下文之间的大小可变。
关于节点的连接,尽管可以使用:before
和:after
伪元素来完成,但是有一种更简单的方法;只需对沿元素宽度并排的整个列表(ul
元素)使用伪元素(在示例中,实际上left
和right
具有一个值30px来补偿我设置的任意边距。
HTML:
<ul>
<li class="node"><label>Point A</label></li>
<li class="context"><span>Content here Content here Content here</span></li>
<li class="node"><label>Point B</label></li>
<li class="context"><span>Content here</span></li>
<li class="node"><label>Point C</label></li>
</ul>
CSS:
ul {
list-style-type: none;
display: flex;
width: 100%;
margin: 50px 0 0 0;
padding: 0 30px;
position: relative;
}
ul:before {
content: "";
display: block;
position: absolute;
left: 30px;
right: 30px;
top: 50%;
margin-top: -1px;
height: 2px;
background: steelblue;
}
.node {
flex: 0 0 auto;
display: block;
width: 12px;
height: 12px;
border-radius: 12px;
border: 2px solid steelblue;
position: relative;
background: #fff;
}
.node label {
position: absolute;
top: -30px;
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
}
.context {
flex: 1 1 auto;
}
.context span {
display: block;
margin-top: -15px;
text-align: center;
}
这是一个工作的小提琴: https://jsfiddle.net/8ksxtz60/
答案 1 :(得分:0)
尝试此代码
h1, h2 {
margin: 0;
padding: 0;
}
ul {
display: flex;
align-items: center;
}
ul li {
position: relative;
width: 33%;
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
border-bottom: 1px solid #ddd;
padding-bottom: 10px;
}
ul li:after {
position: absolute;
bottom: -10px;
left: 0;
font-family: "Font Awesome 5 Free";
font-weight: 300;
content: "\f111";
height: 17px;
width: 17px;
background: #fff;
}
<link href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" rel="stylesheet"/>
<ul>
<li>
<h2>Node A</h2>
<div>Content</div>
</li>
<li>
<h2>Node B</h2>
<div>Content</div>
</li>
<li>
<h2>Node C</h2>
<div>Content</div>
</li>
</ul>
答案 2 :(得分:0)
这在某种程度上回答了您的问题[*] [* =但是,在我看到您的第一张图片而不看h2 / div内容之前,我已经编写了大部分代码。
答案大部分是HTML / CSS,但是有少量的javascript可以将li类(直到选定点的节点)设置为有效。
运行该代码段,然后依次单击节点项以查看正在绘制的线。
编辑:重新。您的问题:
关于最后一个节点,您可以选择给它一个不同的宽度,删除border-width / margin / padding或display:none。如果使用:last-child选择器,则可以使用CSS根据需要为最后一项提供不同的属性值。
关于不同的字体/未对齐,我想大多数使用不同字体的代码也是如此。尝试始终使用一种字体(在这种情况下,我认为这是更好的做法)。至于失准,如果图像尺寸变化最大,导致失准,请尝试使用固定宽度
object-fit
(包含/按比例缩小应该最适合您)您可以将div设置为溢出,不要忘记wrap
以标签为中心:您是否尝试过简单地添加text-align: center;
?不确定有关负偏移量的建议,因为这与其他CSS相关/相对。必须看到完整的CSS / HTML布局。
重新。可能重叠的div:为您的内容设置max-width
,并在必要时将overflow
/ overflow-y
设置为自动。
希望这会有所帮助!
var nodelist1 = document.getElementById("connect");
var mynodes = nodelist1.getElementsByTagName("li");
for (var i = 0; i < mynodes.length; i++) {
mynodes[i].addEventListener("click", function() {
var currNode = document.getElementsByClassName("active");
currNode[0].className = currNode[0].className.replace("active", "");
this.className += "active";
});
}
body {
font-family: "Font Awesome 5 Free";
/* padding: 2em;*/
}
#connect {
font-weight: 300;
content: "\f111";
}
h1,
h2 {
margin: 0;
padding: 0;
}
li {
vertical-align: middle;
display: inline-block;
position: relative;
color: white;
width: 4em;
height: 4em;
text-align: center;
margin: 0em .8em;
line-height: 4em;
border-radius: 1em;
background: navy;
}
li::before {
content: '';
position: absolute;
top: 2em;
left: -3em;
min-width: 4em;
/*width of connecting line*/
height: .2em;
background: maroon;
z-index: -1;
}
li:first-child::before {
display: none;
/*at pos 1, other nodes are 'disabled' line is light blue*/
}
.active {
background: navy;
}
.active~li {
background: lightgray;
}
.active~li::before {
background: lightblue;
}
.content {
display: none;
width: 5em;
max-height: 6em;
overflow-y: scroll;
overflow-x: none;
line-height: 1em;
color: red;
padding: 0;
margin: 0;
}
.active .content {
display: block;
}
<link href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" rel="stylesheet" />
<ul id="connect">
<li>1</li>
<li class="active">2</li>
<li>
<h2>Node A</h2>
<div class="content">Manuel: hello how are you I speak English I learn it from a book</div>
</li>
<li>4</li>
<li>5</li>
</ul>