我正在尝试使用CSS构建以下组件,但是我无法获得第一个和最后一个点来对齐行的末尾。
它必须能够支持任意数量的点(1到4之间),我也不能依赖于flexbox。
我有一个生成HTML的React组件,如下所示:
<div class="row">
<div class="col first" style="width:33%">
<div class="marker complete"></div>
<label>Feedback</label>
</div>
<div class="col" style="width:33%">
<div class="marker partial"></div>
<label>Observation</label>
</div>
<div class="col last" style="width:33%">
<div class="marker review"></div>
<label>Documentation</label>
</div>
</div>
JavaScript会在呈现前计算列大小,in my codepen implementation,我只是将每列中的所有内容都集中在一起。
我可以通过使用first
和last
类来相对定位最终项目来破解解决方案,但是当屏幕大小发生变化时,我总是会开始寻找线条的边缘从分数后面出来。
有没有人知道一个更合理的布局来开始构建它?
答案 0 :(得分:1)
我的想法是将row
设置为display: table-row
,然后使用伪元素生成水平条。但是,您遇到了单独使用CSS和HTML无法知道的问题,即第一个和最后一个圆的位置相对于容器的大小。因此,无法使用全宽项目。
另一种方法是使用标签作为伪元素的根项。它们总是列的整个宽度,因此它们可以很好地指示需要使用的内容。
following proposed solution应该适用于IE9。唯一使用的特殊事物是calc
和after
。 (如果您愿意,也可以使用calc
代替transform: translate
。)
基本思想是使用一个表行,它会自动缩放,然后使用标签作为根,您可以在其上构建进度条。
label:after {
content: "";
height: .5em;
background: #e2e2e2;
width: 100%;
position: absolute;
top: calc((100% - 1.5em) / 2); /* -1 to compensate text, -.5 for height bar */
left: 0;
z-index: -1;
}
.first label:after, .last label:after {
width: 50%;
}
.first label:after {
left: auto;
right: 0;
}
.single label:after {content: none;}
答案 1 :(得分:0)
你去吧。我认为这就是你要找的东西。
<div class="row">
<div class="col" style="width:33%">
<div class="marker marker1 complete"></div>
<label>Feedback</label>
</div>
<div class="col2" style="width:33%">
<div class="marker marker2 partial"></div>
<label>Observation</label>
</div>
<div class="col3" style="width:33%">
<div class="marker marker3 review"></div>
<label>Documentation</label>
</div>
</div>
https://jsfiddle.net/norcaljohnny/e6nm2rbv/
*如果允许使用JS,我可以根据数字和字长添加一些条件并调整标记缩进。
基本上我为每个块使用了显示块,边距和辅助标记类。
答案 2 :(得分:-1)
.row {
display: table;
margin: 0 auto;
position: relative;
width: 100%;
}
.col {
display: table-cell;
width: 33%;
text-align: center;
}
.marker {
width: 30px;
height: 30px;
background-color: lightgray;
border-radius: 30px;
margin: 0 auto;
}
.complete {
background-color: blue;
}
.partial {
background-color: blue;
box-sizing: border-box;
border: 8px solid lightgray;
}
.review {
background-color: lightblue;
}
.col:not(:last-child) > .marker:after {
content: '';
display: inline-block;
width: 67%;
height: 0;
border: 3px solid lightgray;
position: absolute;
left: 16.5%;
top: 12.5px;
z-index: -10;
}
/* ------------------------------------------- */
.wrapper {
display: flex;
align-items: center;
justify-content: center;
padding: 0 100px;
}
.point {
height: 30px;
background-color: lightgray;
border-radius: 30px;
flex: 0 0 30px;
position: relative;
}
.line {
height: 0;
border: 3px solid lightgray;
flex: 1 0;
}
.blue {
background-color: blue;
}
.lightblue {
background-color: lightblue;
}
.border {
background-color: lightgray;
background-image: radial-gradient(at center center, blue 0, blue 8px, transparent 8px, transparent 100%);
}
.point label {
position: absolute;
left: -50%;
top: 100%;
text-align: center;
}
&#13;
<h1>Non flex</h1>
<div class="row">
<div class="col first">
<div class="marker complete"></div>
<label>Feedback</label>
</div>
<div class="col">
<div class="marker partial"></div>
<label>Observation</label>
</div>
<div class="col last">
<div class="marker review"></div>
<label>Documentation</label>
</div>
</div>
<h1>Flex</h1>
<div class="wrapper">
<div class="point blue">
<label>Feedback</label>
</div>
<div class="line"></div>
<div class="point blue border">
<label>Observation</label>
</div>
<div class="line"></div>
<div class="point lightblue">
<label>Documentation</label>
</div>
</div>
&#13;