CSS实现步骤条

目标

  需要实现如下的效果

 

要求

  • 要求内容能够自适应,比如添加步骤5、步骤6, 内容能够自动等宽,而不是手动修改width;
  • 步骤之间的横线也要自适应,能够随着页面宽度的拉伸而伸长;
  • 步骤数字能够自动计算,而不是手动修改添加;
  • 良好的语义化

思路

  • 页面布局使用 ul li;
  • 步骤圆的效果使用 box-shadow ,或者 使用 两个标签叠加,或者 使用 渐变( radial-gradient ,但这种实现方式锯齿很严重,放弃),这里用 box-shadow实现;
  • 内容自适应使用 flex 的 flex-grow;
  • 步骤数字自动计算使用 counter;
  • 步骤内的数字、步骤下面的文字、圆形状以及横线都使用伪类实现;

提示:下面展现的代码是基于上一步骤的代码进行累加的。

实现

  • 基本布局,实现内容自适应

 1 <ul>
 2         <!-- 第一步 -->
 3         <li>
 4         </li>
 5         <!-- 第二步 -->
 6         <li>
 7         </li>
 8         <!-- 第三步 -->
 9         <li>
10         </li>
11         <!-- 第四步 -->
12         <li>
13         </li>
14 </ul>

  首先整体的内容自适应 css 如下

1 ul {
2            list-style: none;  /* 取消默认样式 */
3            display: flex; /* 使用flex */
4 }
5 
6 ul li {
7             flex-grow: 1;
8  }

  设置上面的CSS后,不管添加多少个 li ,都会均匀分布。

  • 实现步骤圆

  因为 li 标签的宽度是等分的,并且没有高度,如果直接给 li 设置 box-shadow 以及 border-radius,就会出现下面的效果。

  li 不仅 宽度太大,也没有高度,如果手动设置widht 以及 height 就会打破内容自适应的效果,所以需要在 li 下添加额外的标签或者使用伪类来实现。

  为了html结构的精简,这里使用伪类实现。如下:

 1 ul  li::before {
 2             content: "";
 3             width: 3rem;  /* 步骤圆的宽 */
 4             height: 3rem; /* 步骤圆的高 */
 5             background: #bcbcbc; /* 里面的小圆 */
 6             box-shadow: 0 0 0 0.5rem #bcbcbc, 0 0 0 1rem transparent; /* 两层投影 改变投影颜色就可以实现步骤的不同状态 这里默认未完成状态 */
 7             border-radius: 50%; /* 设置形状为原型 */
 8             margin: 1rem; /* 没有设置margin的话,会位置不正确,因为投影不占用位置,而这里投影确实需要占用,所以手动给margin */
 9             display: block; /* 需要设置为块级 不然不生效*/
10 }

  

   效果有了,但貌似圆不是在中心位置,需要在伪类的父级元素设置 ,使伪类居中,这里使用 felx的当时居中,如下:

/* 在 ul li 中添加 */
display: flex;
justify-content: center;


/* 现阶段 ul li 完整如下 */
ul  li {
            flex-grow: 1;
            display: flex;
            justify-content: center;
}

   已经居中了。

  • 实现步骤内的数字

   数字自动计算使用 counter,所以需要在 li 的 父级,也就是 ul , 声明一个counter变量,在 ul 中 添加 counter-reset: steps; ,并且在 li 的伪类 before 中使用counter,代码如下:

/* ul 现阶段完整样式*/
ul {
            list-style: none;  /* 取消默认样式 */
            display: flex; /* 使用flex */
            counter-reset: steps; /* 声明counter变量,名为 steps */
 }

/* ul  li::before 中使用counter */
counter-increment: steps; /* 使 steps 自增 */
content: counter(steps); /* 修改content的内容为steps的值 */

/* ul  li::before  现阶段完整样式*/
ul  li::before {
            width: 3rem;  /* 步骤圆的宽 */
            height: 3rem; /* 步骤圆的高 */
            background: #bcbcbc; /* 里面的小圆 */
            box-shadow: 0 0 0 0.5rem #bcbcbc, 0 0 0 1rem transparent; /* 两层投影 改变投影颜色就可以实现步骤的不同状态 这里默认未完成状态 */
            border-radius: 50%; /* 设置形状为原型 */
            margin: 1rem; /* 没有设置margin的话,会位置不正确,因为投影不占用位置,而这里投影确实需要占用,所以手动给margin */
            display: block; /* 需要设置为块级 不然不生效*/
            counter-increment: steps; /* 使 steps 自增 */
            content: counter(steps); /* 修改content的内容为steps的值 */
    
            /* 使 步骤数字水平垂直居中,并设置字号 */
            display: flex;
            color: white;
            justify-content: center;
            align-items: center;
            font-size: 1.5rem;
}              

  • 实现步骤横线

  同样使用伪类实现,样式如下:

ul li:nth-child(n+2):after {
    content: '';
    height: .3rem;
    width: 100%;
    background: #bcbcbc;
}

  ul li:nth-child(n+2) : 选择除了第一个li标签以外的所有 li。

  这还不够,会发现效果相差极大

   横线与步骤圆挤在一起,需要将横线脱离出来,并且定位到中间。使用 position,样式如下:

  

ul li:nth-child(n+2):after {
            content: '';
            height: .3rem;
            width: 100%;
            background: #bcbcbc;
            position: absolute;
            left: -50%; /* 刚好以圆中心从右往左 */
 }

/* 并且需要以 li 为相对位置,所以需要在 ul li 中 添加 position: relative; */
ul  li {
            flex-grow: 1;
            display: flex;
            justify-content: center;
            position: relative;
}

  

  上述实现后,横线不是垂直居中,这里直接在 ul li 中直接使用 align-items: center; 进行垂直居中

  

/* ul li 现阶段完整样式 */
ul  li {
            flex-grow: 1;
            display: flex;
            justify-content: center;
            position: relative;
            align-items: center;
}

  

   这里横线覆盖了数字,在before那里设置z-index即可。就不展示样式了。

  

  • 实现步骤文字

  这里同样使用伪类实现,但需要在 li 下添加额外标签,html 如下:

<ul>
        <!-- 第一步 -->
        <li>
            <div></div>
        </li>
        <!-- 第二步 -->
        <li>
            <div></div>
        </li>
        <!-- 第三步 -->
        <li>
            <div></div>
        </li>
        <!-- 第四步 -->
        <li>
            <div></div>
        </li>
    </ul>

  样式如下:

ul li div {
            color: black; /* 设置文字颜色 */
 }
 ul li div:before {
            content: "第"counter(steps)"步";  /* 使用counter */
            color: inherit;
            position: absolute; /* 定位位置 */
            bottom: -2rem;
            left: 50%;
            transform: translateX(-50%); /* 水平居中 */
 }

  • 步骤的不同状态

  这里直接改变 box-shadow的颜色即可, 给完成状态的样式单独一个类(active),在html 中添加相应class,再修改样式即可,样式如下:

ul  li.active:nth-child(n+2)::after {
            background: #00bc9b;
        }

ul  li.active::before {
            background: #00bc9b;
            box-shadow: 0 0 0 0.5rem rgb(255 255 255), 0 0 0 1rem #00bc9b;
}

  

  

完整代码

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8     <title>步骤条</title>
  9     <style>
 10         *{
 11             padding: 0;
 12             margin: 0;
 13         }
 14 
 15         ul {
 16             list-style: none;  /* 取消默认样式 */
 17             display: flex; /* 使用flex */
 18             counter-reset: steps;
 19         }
 20         ul  li {
 21             flex-grow: 1;
 22             display: flex;
 23             justify-content: center;
 24             position: relative;
 25             align-items: center;
 26         }
 27 
 28         ul  li::before {
 29             width: 3rem;  /* 步骤圆的宽 */
 30             height: 3rem; /* 步骤圆的高 */
 31             background: #bcbcbc; /* 里面的小圆 */
 32             box-shadow: 0 0 0 0.5rem #bcbcbc, 0 0 0 1rem transparent; /* 两层投影 改变投影颜色就可以实现步骤的不同状态 这里默认未完成状态 */
 33             border-radius: 50%; /* 设置形状为原型 */
 34             margin: 1rem; /* 没有设置margin的话,会位置不正确,因为投影不占用位置,而这里投影确实需要占用,所以手动给margin */
 35             display: block; /* 需要设置为块级 不然不生效*/
 36             counter-increment: steps; /* 使 steps 自增 */
 37             content: counter(steps); /* 修改content的内容为steps的值 */
 38 
 39             /* 使 步骤数字水平垂直居中,并设置字号 */
 40             display: flex;
 41             color: white;
 42             justify-content: center;
 43             align-items: center;
 44             font-size: 1.5rem;
 45             position: relative;
 46 
 47             z-index: 1;
 48         }
 49 
 50         ul li:nth-child(n+2):after {
 51             content: '';
 52             height: .3rem;
 53             width: 100%;
 54             background: #bcbcbc;
 55             position: absolute;
 56             left: -50%;
 57         }
 58 
 59         ul li div {
 60             color: black;
 61         }
 62         ul li div:before {
 63             content: "第"counter(steps)"步";
 64             color: inherit;
 65             position: absolute;
 66             bottom: -2rem;
 67             left: 50%;
 68             transform: translateX(-50%);
 69         }
 70 
 71         ul  li.active:nth-child(n+2)::after {
 72             background: #00bc9b;
 73         }
 74 
 75         ul  li.active::before {
 76             background: #00bc9b;
 77             box-shadow: 0 0 0 0.5rem rgb(255 255 255), 0 0 0 1rem #00bc9b;
 78         }
 79     </style>
 80 </head>
 81 
 82 <body>
 83     <ul>
 84         <!-- 第一步 -->
 85         <li class="active">
 86             <div></div>
 87         </li>
 88         <!-- 第二步 -->
 89         <li class="active">
 90             <div></div>
 91         </li>
 92         <!-- 第三步 -->
 93         <li class="active">
 94             <div></div>
 95         </li>
 96         <!-- 第四步 -->
 97         <li>
 98             <div></div>
 99         </li>
100     </ul>
101 </body>
102 
103 </html>
View Code
Welcome to my blog!
原文地址:https://www.cnblogs.com/blogCblog/p/14439145.html