前言

在前端的业务场景中,经常看到有关时间轴的一些样式,通过一条线贯穿头部和尾部,每个节点中有这个节点的相关标记,那么如果我们相关的样式要怎么实现呢?

水平的轴

代码地址:https://codepen.io/robinson90/pen/oNvxBWZ

效果图:

image.png

实现思路:
1.顶部的线或者其他轴的效果,通过另外一个div实现
2.与节点相关的样式,包括位置与内容,通过伪元素实现

具体代码:

  1. <div class="crossline">
  2. <div class="line"></div>
  3. <ul class="stepUl">
  4. <li class="step">13
  5. </li>
  6. <li class="step">34
  7. </li>
  8. <li class="step">34
  9. </li>
  10. </ul>
  11. </div>
  1. *{
  2. margin:0;
  3. padding:0;
  4. border:none;
  5. }
  6. li{list-style:none}
  7. .crossline{
  8. padding-top:20px;
  9. .line{
  10. border-bottom:1px dashed gray;
  11. }
  12. .stepUl{
  13. display:flex;
  14. margin-top:10px;
  15. .step:nth-child(2){
  16. &::after{
  17. position:absolute;
  18. background:#fff;
  19. top:-25px;
  20. content:'>b';
  21. display:inline-block;
  22. left:50%;
  23. padding:0 5px;
  24. background:#fff;
  25. }
  26. }
  27. .step:nth-child(3){
  28. margin-right:0;
  29. &::after{
  30. position:absolute;
  31. background:#fff;
  32. top:-25px;
  33. content:'>c';
  34. width:50%;
  35. height:20px;
  36. display:inline-block;
  37. left:50%;
  38. background:#fff;
  39. }
  40. }
  41. .step:nth-child(1){
  42. &::before{
  43. position:absolute;
  44. background:#fff;
  45. top:-25px;
  46. content:'';
  47. width:50%;
  48. height:20px;
  49. display:inline-block;
  50. left:0%;
  51. background:#fff;
  52. }
  53. &::after{
  54. position:absolute;
  55. background:#fff;
  56. top:-25px;
  57. content:'a';
  58. display:inline-block;
  59. left:50%;
  60. padding:0 5px;
  61. background:#fff;
  62. }
  63. }
  64. .step{
  65. flex:1;
  66. position:relative;
  67. margin-right:5px;
  68. border:1px solid red;
  69. }
  70. }
  71. }

垂直方向的时间轴

实现效果

image.png

实现思路:

整体与上面的思路一致,也是用边框做贯穿轴,然后用每个节点的伪元素去抹去不需要的部分,同时用另一个伪元素去实现节点标记本身。(代码见上面地址)

element-ui 的时间线

组件地址:https://element.eleme.cn/#/zh-CN/component/timeline

样式效果:

image.png

实现思路:
1 每个节点包含三个部分,分别用于实现竖线,节点样式,主体内容
2 为了保障向下的间距,每个节点包含了向下的20padding作为间距,这里不使用margin是因为需要使用节点的边框来实现时间轴效果
3 竖线使用绝对定位,拿到盒模型的全部高度,使用灰色线
4 节点样式使用绝对定位,圆角
5 主题内容留出向左间距

代码模拟:

  1. .crossline3{
  2. margin-left:30px;
  3. .step{
  4. position:relative;
  5. height:50px;
  6. .tail{
  7. position: absolute;
  8. left: 4px;
  9. height: 100%;
  10. border-left: 2px solid #e4e7ed;
  11. }
  12. .dot{
  13. position: absolute;
  14. background-color: #e4e7ed;
  15. border-radius: 50%;
  16. display: flex;
  17. justify-content: center;
  18. align-items: center;
  19. left: -1px;
  20. width: 12px;
  21. height: 12px;
  22. }
  23. .wrapper{
  24. position: relative;
  25. padding-left: 28px;
  26. top: -3px;
  27. }
  28. }
  29. }

步骤条

由此,大家很容易联想到与时间轴类似的另一个前端样式,步骤条,步骤条在轴的样式上与时间轴相同,不同的只是其不关注内容的部分,只关注自己的样式实现。那么我们不妨也看下element-ui是如何实现这部分的样式的,应用了哪些技巧?

组件地址:https://element.eleme.cn/#/zh-CN/component/steps

效果图:

image.png

image.png

实现思路:

1.顶部与下面为同宽的div,处于同一个父容器中,所以保持同一个宽度,形成左面对其非常容易
2.顶部的图标覆盖效果:首先定位划线灰色,然后用一个带图标的标签覆盖,背景为白色即可

实现代码:
因为实现的代码比较简单,这里就略过,有兴趣的可以去看下element-ui的源码。

备注:那么它最后一条是如何实现没有划线的呢?技巧也很简单,用同类型的选择器,拿到同同类型的最后一个,划线不显示即可。

  1. .el-step:last-of-type .el-step__line{
  2. display:none
  3. }

小结

通过本文,希望你能了解到如何实现一些类似时间轴、步骤条,以及目前大部分组件如何处理的思路,本文最开始提供的思路是个人思考所得,更为简单,但可能存在样式不够丰富的问题,毕竟伪元素和元素还是有区别的。

其中特别希望大家注意到的一点是,如果你的内容是变化的,而相关的轴是变化的,那么首先这个轴一定是在所有节点的大容器外层绝对定位实现的,或者像element-ui一样,拿到每个元素的绝对宽高去划线然后拼接的,目前针对这点,还没有更优化的思路。