• 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!
  • 相关阅读:
    快乐来源的研究
    这可能是经历中真实的农村
    golang入门到实战教程
    免费开源pdf阅读器SumatraPDF
    农村题材光棍儿
    在线头像卡通化
    微软出品电脑管家
    刚毕业的大学生、失业的父亲:父子返乡
    ApplicationEventPublisher的简单使用
    mysql里使用JSON_EXTRACT取值
  • 原文地址:https://www.cnblogs.com/blogCblog/p/14439145.html
Copyright © 2020-2023  润新知