更新了问题:
我想在时间轴中显示事件,如下图所示:
事件数据项有两个属性:“开始时间”和“长度”,因此可以将数据想象成一个看起来像这样的表:
event name | start | length
-----------+-------+-------
1 | 0 | 200
1.1 | 30 | 100
1.1.1 | 40 | 50
1.2 | 140 | 50
2 | 205 | 100
2.1 | 220 | 20
2.2 | 250 | 20
2.3 | 280 | 20
... | ... | ...
数据有一些特点:
事件永远不会以下列方式重叠......
+---------+ +---------+
| A | | C |
+---------+ +---------+
+---------+ or +---------+
| B | | D |
+---------+ +---------+
...因为B将是A的孩子,但它必须在A结束之前结束。 C在D内开始,因此D将是C的父级(并且必须显示在C之上),但是存在与A和B相同的问题。
因此,只有一种方式可以显示事件。
目前我正在尝试这样做:x-position设置为margin-left
,但任何其他属性都可以。 div
按x值排序:
<div class="container">
<div class="item" style="margin-left:0; width: 200px;">
1
</div>
<div class="item" style="margin-left:30px; width: 100px;">
1.1
</div>
<div class="item" style="margin-left:40px; width: 50px;">
1.1.1
</div>
<div class="item" style="margin-left:140px; width: 50px;">
1.2
</div>
<div class="item" style="margin-left:205px; width: 100px;">
2
</div>
<div class="item" style="margin-left:220px; width: 20px;">
2.1
</div>
<div class="item" style="margin-left:250px; width: 20px;">
2.2
</div>
<div class="item" style="margin-left:280px; width: 20px;">
2.3
</div>
</div>
.container {
padding: 0.5rem 0 1.5rem 0;
background-color: #EEE;
border: 1px solid #888;
overflow-x: auto;
}
.item {
height: 2rem;
margin-bottom: -1rem;
font-size: 60%; font-family: sans-serif;
background-color: #BBB;
border: 1pt solid #EEE;
overflow: hidden;
}
这是当前结果(在这种情况下,事件名称是数字,但它们可以是任意字符串):
每行只有一个div
,因此每个后续div
都低于其前任。
任何想法如何使用纯CSS执行此操作而无需计算元素的y位置?
示例代码可在此处找到:http://jsfiddle.net/hiddenbit/PvBjt/
答案 0 :(得分:0)
答案 1 :(得分:0)
我已将您的.item
更改为position: absolute;
并给出了子项的类以及像素top
值:
.item {
position: absolute;
}
.sub-item {
top:35px;
}
.sub-sub-item {
top: 55px;
}
<强> Updated fiddle 强>
答案 2 :(得分:0)
即使要求非常模糊,也要在环中投掷我的2个想法。
我为大多数元素添加了margin-top
;等级x.x
得到margin-top:20px
,等级x.x.x
获得margin-top:40px
。与@YaMo相似的方法。
<强> HTML 强>
<div class="container">
<div class="item" style="margin-left:0; width: 200px;">1</div>
<div class="item" style="margin-left:30px; margin-top:20px; width: 100px;">1.1</div>
<div class="item" style="margin-left:40px; margin-top:40px; width: 50px;">1.1.1</div>
<div class="item" style="margin-left:140px; margin-top:20px; width: 50px;">1.2</div>
<div class="item" style="margin-left:205px; width: 100px;">2</div>
<div class="item" style="margin-left:220px; margin-top:20px; width: 20px;">2.1</div>
<div class="item" style="margin-left:250px; margin-top:20px; width: 20px;">2.2</div>
<div class="item" style="margin-left:280px; margin-top:20px; width: 20px;">2.3</div>
</div>
<强> CSS 强>
.item {
position:absolute; /* just add to existing properties */
}
元素的一些实际结构允许更清晰的HTML和更通用的CSS。我无法想出通用规则的唯一部分是项1.2
的宽度。这当然取决于能否改变HTML结构。
<强> HTML 强>
<div class="container">
<ul>
<li class="item">1
<ul>
<li class="item">1.1
<ul>
<li class="item">1.1.1</li>
</ul>
</li>
<li class="item">1.2</li>
</ul>
</li>
<li class="item">2
<ul>
<li class="item">2.1</li>
<li class="item">2.2</li>
<li class="item">2.3</li>
</ul>
</li>
</ul>
</div>
<强> CSS 强>
.container {
padding: 0.5rem 0 1.5rem 0;
background-color: #EEE;
border: 1px solid #888;
}
.item {
height:2rem;
background-color: #BBB;
border: 1pt solid #EEE;
display:inline-block;
vertical-align:top;
min-width:20px;
}
li:only-child {
min-width:50px;
}
ul {
margin:0;
padding:0;
list-style-type:none;
}
.container > ul > li {
display:inline-block;
vertical-align:top;
font-size: 60%; font-family: sans-serif;
}
ul li:first-child {
margin-left:20px;
}
ul li:last-child {
margin-right:10px;
}
答案 3 :(得分:0)
似乎无法仅使用CSS布局div
。因此我使用JavaScript制作了以下解决方案。
遍历数据列表并动态添加div
。使用绝对定位:
left
设置为开始时间top
堆栈数据结构用于跟踪隐式父项<强> HTML:强>
<div id="container"></div>
<强> JavaScript的:强>
var data = [
["1", 0, 200 ],
["1.1", 30, 100 ],
["1.1.1", 40, 50 ],
["1.2", 140, 50 ],
["2", 205, 100 ],
["2.1", 220, 20 ],
["2.2", 250, 20 ],
["2.3", 280, 20 ]
];
var endStack = [];
var maxStackHeight = 0;
var container = document.getElementById("container");
data.forEach(function(row) {
// create div
var div = document.createElement("div");
div.className = "item";
div.appendChild(document.createTextNode(row[0]));
var x = row[1]; var w = row[2];
div.style.left = x.toString() + "px";
div.style.width = w.toString() + "px";
// get level of div
for (var i = endStack.length-1; i >= 0; i--) {
if (x > endStack[i]) {
// current event starts after current top-of-stack ends → remove
endStack.pop();
} else {
// current event is child of current top-of-stack event
break;
}
}
// set y position based on stack height
div.style.top = (endStack.length).toString() + "rem";
// append to container
container.appendChild(div);
// push end of added event to stack
endStack.push(x + w);
// set maximum stack height
maxStackHeight = Math.max(maxStackHeight, endStack.length);
});
// set container height based on maximum stack height
container.style.height = (maxStackHeight + 1.1).toString() + "rem";
<强> CSS:强>
#container {
background-color: #EEE;
border: 0.1rem solid #888;
overflow-x: auto;
position: relative;
}
.item {
position: absolute;
height: 2rem;
font-size: 60%; font-family: sans-serif;
background-color: #BBB;
border: 0.1rem solid #EEE;
overflow: hidden;
}
答案 4 :(得分:0)
以下是使用my other answer和JavaScript中的CSS创建结构化<ul>
事件的替代解决方案。
<强>的JavaScript 强>
window.onload=function(){
var events = [
{ name: '1', start: 0, length: 300},
{ name: '1.1', start: 30, length: 100},
{ name: '1.1.1', start: 40, length: 50},
{ name: '1.2', start: 140, length: 50},
{ name: '1.3', start: 200, length: 50},
{ name: '2', start: 305, length: 100},
{ name: '2.1', start: 320, length: 20},
{ name: '2.2', start: 350, length: 20},
{ name: '2.3', start: 380, length: 20},
{ name: '3', start: 410, length: 50}
];
var html = [];
var containerEventEnd = [];
var prevEventEnd = Infinity;
for (var i = 0; i < events.length; i++) {
var e = events[i];
var eventEnd = e.start + e.length;
if (e.start > containerEventEnd[1]) {
containerEventEnd.shift();
html.push('</ul>');
}
if (eventEnd > containerEventEnd[0]) {
containerEventEnd.shift();
containerEventEnd.unshift(eventEnd);
}
if (e.start > prevEventEnd) {
html.push('</li>');
} else {
html.push('<ul>');
containerEventEnd.unshift(eventEnd);
}
html.push('<li class="item">' + e.name); // every item is just an <li>
prevEventEnd = eventEnd;
}
document.getElementById('container').innerHTML = html.join('\n');
};
<强> CSS 强>
#container {
padding: 0.5rem 0 1.5rem 0;
background-color: #EEE;
border: 1px solid #888;
}
.item {
height:2rem;
background-color: #BBB;
border: 1pt solid #EEE;
display:inline-block;
vertical-align:top;
min-width:20px;
}
li:only-child {
min-width:50px;
}
ul {
margin:0;
padding:0;
list-style-type:none;
}
#container > ul > li {
display:inline-block;
vertical-align:top;
font-size: 60%; font-family: sans-serif;
}
ul li:first-child {
margin-left:20px;
}
ul li:last-child {
margin-right:10px;
}
HTML
<div id="container"></div>