女王控的博客

CSS练手测试

练习地址:小测答题收集区

CSS测试一

2019 07 20 14 25 28

具体实现

overflow: hidden + float(不完美,显示的顺序与实际的 html 顺序不一致)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }

        .list {
            list-style: none;
            padding: 0;
        }

        .item {
            height: 40px;
            line-height: 40px;
            overflow: hidden; /* 创建BFC,以利于自动分配空间 */
        }

        .title {
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            color: rgb(182, 185, 190);
            font-size: 18px;
        }

        .tag-list {
            float: right;
            margin-left: 10px;
        }

        .tag-list > span {
            border: 1px solid;
            padding: 2px;
            font-size: 14px;
        }

        .tag-list > span:nth-child(1) {
            border-color: rgb(182, 185, 190);
            color: rgb(182, 185, 190);
        }

        .tag-list > span:nth-child(2) {
            border-color: rgb(223, 98, 97);
            color: rgb(223, 98, 97);
        }

        .tag-list > span:nth-child(3) {
            border-color: rgb(116, 162, 234);
            color: rgb(116, 162, 234);
        }
        /* 注意 title 必须放在后面 */

        /* 所有的方法都是按照此方法,不再举例 */
        .list[reserve] .title{
            direction: rtl;
        }
    </style>
</head>
<body>
    <ul class="list">
        <li class="item">
            <div class="tag-list">
                <span class="tag">标签1</span>
                <span class="tag">标签2</span>
                <span class="tag">标签3</span>
            </div>
            <div class="title">这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题</div>
        </li>
        <li class="item">
            <div class="tag-list">
                <span class="tag">标签1</span>
                <span class="tag">标签2</span>
                <span class="tag">标签3</span>
            </div>
            <div class="title">这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题</div>
        </li>
        <li class="item">
            <div class="tag-list">
                <span class="tag">标签1</span>
                <span class="tag">标签2</span>
                <span class="tag">标签3</span>
            </div>
            <div class="title">这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题</div>
        </li>
    </ul>

    <ul class="list" reserve>
        <li class="item">
            <div class="tag-list">
                <span class="tag">标签1</span>
                <span class="tag">标签2</span>
                <span class="tag">标签3</span>
            </div>
            <div class="title">这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题</div>
        </li>
        <li class="item">
            <div class="tag-list">
                <span class="tag">标签1</span>
                <span class="tag">标签2</span>
                <span class="tag">标签3</span>
            </div>
            <div class="title">这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题</div>
        </li>
        <li class="item">
            <div class="tag-list">
                <span class="tag">标签1</span>
                <span class="tag">标签2</span>
                <span class="tag">标签3</span>
            </div>
            <div class="title">这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题</div>
        </li>
    </ul>
</body>

</html>

flex + flex:1

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }

        .list {
            list-style: none;
            padding: 0;
        }

        .item {
            display: flex;
        }

        .title {
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            color: rgb(182, 185, 190);
            font-size: 18px;
            /* flex-grow: 1; 定义项目的放大比例,默认值为0,即如果存在剩余空间,也不放大
                flex-shrink: 1; 定义了项目的缩小比例,默认为1,即如果空间不足,项目将缩小。
                flex-basis: 0%; 定义了在分配多余空间之前,项目占据的主轴空间(main size)。
                浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小
            */
            flex: 1;
        }

        .tag-list {
            margin-left: 10px;
        }

        .tag-list > span {
            border: 1px solid;
            padding: 2px;
            font-size: 14px;
        }

        .tag-list > span:nth-child(1) {
            border-color: rgb(182, 185, 190);
            color: rgb(182, 185, 190);
        }

        .tag-list > span:nth-child(2) {
            border-color: rgb(223, 98, 97);
            color: rgb(223, 98, 97);
        }

        .tag-list > span:nth-child(3) {
            border-color: rgb(116, 162, 234);
            color: rgb(116, 162, 234);
        }
    </style>
</head>

<body>
  <ul class="list">
    <li class="item">
        <div class="title">这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题</div>
        <div class="tag-list">
            <span class="tag">标签1</span>
            <span class="tag">标签2</span>
            <span class="tag">标签3</span>
        </div>
    </li>
    <li class="item">
        <div class="title">这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题</div>
        <div class="tag-list">
            <span class="tag">标签1</span>
            <span class="tag">标签2</span>
            <span class="tag">标签3</span>
        </div>
    </li>
    <li class="item">
        <div class="title">这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题</div>
        <div class="tag-list">
            <span class="tag">标签1</span>
            <span class="tag">标签2</span>
            <span class="tag">标签3</span>
        </div>
    </li>
  </ul>
</body>

</html>

table + table-layout: fixed(兼容性较好)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }

        .list {
            list-style: none;
            padding: 0;
        }

        .item {
            display: table;
            width: 100%;
            line-height: 40px;
        }

        .title-container {
            display: table-cell;
            width: 9999px;
        }

        .table-fixed {
            /* 打点效果只有在 table-layout: fixed 才有效果 */
            table-layout: fixed;
            display: table;
            width: 100%;
        }

        .title {
            display: table-cell;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            color: rgb(182, 185, 190);
            font-size: 18px;
        }

        .tag-list {
            margin-left: 10px;
            display: table-cell;
            white-space: nowrap;
        }

        .tag-list > span {
            border: 1px solid;
            padding: 2px;
            font-size: 14px;
        }

        .tag-list > span:nth-child(1) {
            border-color: rgb(182, 185, 190);
            color: rgb(182, 185, 190);
        }

        .tag-list > span:nth-child(2) {
            border-color: rgb(223, 98, 97);
            color: rgb(223, 98, 97);
        }

        .tag-list > span:nth-child(3) {
            border-color: rgb(116, 162, 234);
            color: rgb(116, 162, 234);
        }
    </style>
</head>

<body>
  <ul class="list">
    <li class="item">
        <div class="title-container">
            <div class="table-fixed">
                <span class="title">
                    这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题
                </span>
            </div>
        </div>
        <div class="tag-list">
            <span class="tag">标签1</span>
            <span class="tag">标签2</span>
            <span class="tag">标签3</span>
        </div>
    </li>
    <li class="item">
        <div class="title-container">
            <div class="table-fixed">
                <span class="title">
                    这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题这是一个长度不确定的标题标题
                </span>
            </div>
        </div>
        <div class="tag-list">
            <span class="tag">标签1</span>
            <span class="tag">标签2</span>
            <span class="tag">标签3</span>
        </div>
    </li>
    <li class="item">
        <div class="title-container">
            <div class="table-fixed">
                <span class="title">
                    这是一个长度不确定的标题标题长度不确定的标题标题这是一个长度不确定长度不确定的标题标题这是一个长度不确定
                </span>
            </div>
        </div>
        <div class="tag-list">
            <span class="tag">标签1</span>
            <span class="tag">标签2</span>
            <span class="tag">标签3</span>
        </div>
    </li>
  </ul>
</body>

</html>

实现要点

  1. 大家布局其实这3类:float+overflow,然后是flex布局,很少人使用的table布局。
  2. float布局技巧:float:right+overflow:hidden;text-overflow:ellipsis;white-space:nowrap; 原理:overflow:hidden可以创建格式化上下文,也就是BFC,类似结界,不受浮动影响,自动分配剩余空间。
  3. flex布局:display:flex > flex: 1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  4. 重点是table布局:float布局有个非常明显的不足,那就是DOM的位置和视觉是不一致的。table布局虽然效果有,但是却有很多的不足。1. 左侧table-cell的尺寸不建议使用字符撑开,然后内容绝对定位打点布局有较大的限制。非table-layout:fixed的表格,其每个单元格尺寸宽度是根据里面内容自动分配的,如果你没有设置white-space: nowrap是自动宽度自适应的。但是设置了white-space: nowrap则尺寸表现就不符合要求,怎么办呢?其实很简单,再嵌套一层display:table;table-layout:fixed;的元素。table布局中,打点只能在table-layout:fixed的场景下。所以,我们设置很大宽度的table-cell的子元素display:table;table-layout:fixed;此时就能正常打点了。优点:兼容性更好,DOM顺序符合认知。
  5. 开头打点 direction: rtl 就可以。

CSS测试二

2019 07 20 16 54 02

具体实现

flex + flex:1

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        .btn-group {
            display: flex;
            margin-bottom: 32px;
        }

        .btn {
            flex: 1;
            margin: 0 0.5rem;
            padding: 6px 0;
            color: rgb(227, 140, 143);
            border: 1px solid currentColor;
            border-radius: 15px;
        }
    </style>
</head>

<body>
    <div class="btn-group">
        <button class="btn btn-danger">按钮</button>
    </div>
    <div class="btn-group">
        <button class="btn btn-danger">按钮</button>
        <button class="btn btn-danger">按钮</button>
    </div>
    <div class="btn-group">
        <button class="btn btn-danger">按钮</button>
        <button class="btn btn-danger">按钮</button>
        <button class="btn btn-danger">按钮</button>
    </div>
</body>

</html>

grid + grid-template-columns: repeat(auto-fit, minmax(0, 1fr))

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        .btn-group {
            display: grid;
            /* 设置行和列的大小,在行轨道或列轨道两边是网格线。 */
            /* repeat表示网格轨道的重复部分,以一种更简洁的方式去表示大量而且重复列的表达式 */
            /* minmax 是一个来定义大小范围的属性 */
            grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
            /* grid-auto-flow: column 也可以 */
            grid-gap: 1rem;
            margin-bottom: 32px;
        }

        .btn {
            margin: 0 0.5rem;
            padding: 6px 0;
            color: rgb(227, 140, 143);
            border: 1px solid currentColor;
            border-radius: 15px;
        }
    </style>
</head>

<body>
    <div class="btn-group">
        <button class="btn btn-danger">按钮</button>
    </div>
    <div class="btn-group">
        <button class="btn btn-danger">按钮</button>
        <button class="btn btn-danger">按钮</button>
    </div>
    <div class="btn-group">
        <button class="btn btn-danger">按钮</button>
        <button class="btn btn-danger">按钮</button>
        <button class="btn btn-danger">按钮</button>
    </div>
</body>

</html>

table + table-layout: fixed(兼容性较好)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        .btn-group {
            display: table;
            table-layout: fixed;
            width: 100%;
        }

        .btn-group-wrapper {
            display: table-cell;
            padding: 1rem;
        }

        .btn {
            width: 100%;
            margin: 0 0.5rem;
            padding: 5px;
            color: rgb(227, 140, 143);
            border: 1px solid rgb(227, 140, 143);
            border-radius: 15px;
        }
    </style>
</head>

<body>
    <div class="btn-group">
        <div class="btn-group-wrapper">
            <button class="btn btn-danger">按钮</button>
        </div>
    </div>
    <div class="btn-group">
        <div class="btn-group-wrapper">
            <button class="btn btn-danger">按钮</button>
        </div>
        <div class="btn-group-wrapper">
            <button class="btn btn-danger">按钮</button>
        </div>
    </div>
    <div class="btn-group">
        <div class="btn-group-wrapper">
            <button class="btn btn-danger">按钮</button>
        </div>
        <div class="btn-group-wrapper">
            <button class="btn btn-danger">按钮</button>
        </div>
         <div class="btn-group-wrapper">
            <button class="btn btn-danger">按钮</button>
        </div>
    </div>
</body>

</html>

实现要点

  1. flex和grid布局都能实现我们想要的效果,但是推荐使用flex布局,因为语义更好。grid更适合页面大的框架结构布局,偏向二维。本题语义偏向一维。虽然grid控制间隙更方便(grid-gap)。
  2. justify-content可以不需要,flex-wrap也是多余的,因为默认就是nowrap,flex-direction也是不需要的,因为默认就是row。因此,我们直接在容器元素设置display:flex就好了。
  3. 子项可以flex: 1,以及其他很多设置方法。例如flex: auto;(语义更合适-推荐)。设置flex:1实际上空间分配是不足的,于是,等分。因此设置flex:2, 3, 4…都是可以。还有就是width:100%,除了还有一种方法:width:-webkit-fill-available语义是更好的(推荐)。
  4. 下面是grid布局:grid-template-columns: repeat(auto-fit, minmax(0, 1fr))是一种方法,但是并不是最好的实现,因为这个比较难理解,也不好记忆。更好的实现是grid-auto-flow: column;
  5. 兼容性更好的table布局,IE8+都支持,放心使用。.table { display: table; table-layout: fixed; width: 100%; }.cell { display: table-cell;} 固定组合。务必掌握,基础必备布局知识。
  6. 不少人.container左右0.5rem,子项margin:0 .5rem实现1rem间隙,这样方式和实际开发是不符合的。实际开发左右1rem,是一个大的结构元素控制的。使用:last-child或者:first-child更符合实际开发,虽然代码更啰嗦了点,因为有一个重置。最好的实现其实还是使用:not()伪类(AsyncGuo的实现),:not(:last-child) {margin-right: 1rem;} 或者 .btnitem + .btnitem 或者 .btnitem ~ .btnitem(IE7+)

CSS测试三

2019 07 22 09 35 11

具体实现

flex + space-between

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        .container {
            display: flex;
            flex-direction: column;
            justify-content: space-between;
            min-height: 100vh;
        }

        .footer {
            color:#fff;
            background:#78a5f1;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="content">内容</div>
        <footer class="footer">底部</footer>
    </div>
</body>

</html>

fixed(不完美)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        .container {
            position: fixed;
            top: 0;
            height: 100%;
        }

        .footer {
            /* 这里有点不符合题意,超过一屏之后没有跟随在 content 后面 */
            position: absolute;
            width: 100%;
            bottom: 0;
            color:#fff;
            background:#78a5f1;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="content">内容</div>
        <footer class="footer">底部</footer>
    </div>
</body>

</html>

grid + space-between

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        .container {
            display: grid;
            min-height: 100vh;
            align-content: space-between;
        }

        .footer {
            color:#fff;
            background:#78a5f1;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="content">内容</div>
        <footer class="footer">底部</footer>
    </div>
</body>

</html>

flex + margin-top(完美)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        .container {
            display: flex;
            flex-direction: column;
            min-height: 100vh;
        }

        .footer {
            /* 元素如果没有高宽,尺寸会拉伸(或处在可拉伸上下文中)*/
            /* 则此时auto会智能分配剩余空间,实现上下左右或者居中对齐效果 */
            margin-top: auto;
            color:#fff;
            background:#78a5f1;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="content">内容</div>
        <footer class="footer">底部</footer>
    </div>
</body>

</html>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        .container {
            display: table;
            height: 100vh;
        }

        .footer {
            display: table-footer-group;
            color:#fff;
            background:#78a5f1;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="content">内容</div>
        <footer class="footer">底部</footer>
    </div>
</body>

</html>

实现要点

  1. 题意理解要准确:.content不拉伸,不要影响浏览器默认的滚动;
  2. flex布局是相对大家比较容易想到的实现:.container { display: flex; flex-direction: column; justify-content: space-between; min-height: 100vh;} 但是IE9不支持。
  3. 另外实现:.container{ display: table; min-height:100vh;}.footer{ display: table-footer-group; /* IE8+支持 */}。
  4. 如果footer高度固定,则实现方法就很多了,例如,绝对定位固定在底部,或者margin负值定位。
  5. grid布局也是可以实现类似效果:.container {display: grid; min-height: 100vh; align-content: space-between;}
  6. 满分回答:.container { display: flex; flex-direction: column; min-height: 100vh; }footer { margin-top: auto;}
  7. margin:auto是非常体现CSS理解深度的一个CSS声明。
  8. auto 智能的剩余宽度分配。元素如果没有高宽,尺寸会拉伸(或处在可拉伸上下文中),则此时auto会智能分配剩余空间,实现上下左右或者居中对齐效果。
  9. flex布局下的所有元素就处于一种尺寸可拉伸的上下文环境,所以此时footer设置margin-top: auto是可以顶部对齐的(margin-top自动剩余空间)。

CSS测试四

2019 07 22 10 55 33

具体实现

flex

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        /********** 主容器 **********/
        .audio-controls {   
            text-align: left;
        }

        /********** 样式容器 **********/
        .audio-controls-inner {
            font-size: 16px;      /* 控件尺寸 */
            color: #000;          /* 控件主题色 */
            background: #f1f3f4;  /* 控件背景色 */

            display: flex;
            align-items: center;
            min-width: 2.125em;
            height: 3.375em;
            padding: 0 .625em;
            border-radius: 2.125em;
        }

        /********** 组件按钮公用样式 **********/
        .audio-controls-button {
            flex: 0 0 2em;
            height: 2em;
            padding: 0;
            overflow: hidden;
            font-size: 100%;
            color: inherit;
            background: transparent;
            border: 0;
            border-radius: 2.25em;
            cursor: pointer;
            transition: background ease-in-out .2s;
        }

        .audio-controls-button:hover { 
            background: rgba(0, 0, 0, .06);
        }

        .audio-controls-button::before {
            display: inline-block;
            content: "";
        }

        /********** 播放按钮 **********/
        .audio-controls-button[aria-label="play"]::before {
            transform: translate(30%, .16em);
            border: solid transparent;
            border-width: .55em .85em;
            border-left-color: currentColor;
        }

        /********** 暂停按钮 **********/
        .audio-controls-button[aria-label="pause"]::before {
            width: .375em;
            height: 48%;
            transform: translateY(.16em);
            text-align: center;
            border: solid currentColor;
            border-width: 0 .25em;
        }

        /********** 声音按钮 **********/
        .audio-controls-button[aria-label="volume"] {
            margin-left: 1em;
            margin-right: .25em;
        }

        .audio-controls-button[aria-label="volume"]::before { 
            display: none;
        }

        /* 声音按钮图标 */
        .audio-controls-button-volume-icon {
            display: inline-block;
            padding: .3em .15em;
            margin-left: -.3em;
            transform: translate(-50%, .15em);
            border: .3em solid transparent;
            border-right-color: currentColor;
            box-shadow: inset 1em 0 0;
        }

        .audio-controls-button-volume-icon > i {
            position: relative;
            left: calc(.3125em * 2);
        }

        .audio-controls-button-volume-icon > i::before {
            content: "";
            position: absolute;
            width: .7em;
            height: 1.4em;
            transform: translateY(-50%);
            box-sizing: border-box;
            border: .16em solid;
            border-left: 0;
            border-radius: 0 .7em .7em 0;
        }

        .audio-controls-button-volume-icon > i::after {
            content: "";
            position: absolute;
            width: .3em;
            height: .6em;
            transform: translateY(-50%);
            background: currentColor;
            border-radius: 0 .3em .3em 0;
        }

        /********** 选项菜单 **********/
        .audio-controls-button[aria-label="menu"]::before  {
            width: .3125em;
            height: .3125em;
            transform: translateY(-50%);
            background: currentColor;
            border-radius: 50%;
            box-shadow: 0 .5em 0, 0 -.5em 0;
        }

        /********** 播放时间文本 **********/
        .audio-controls-time {
            font-size: .875em;
            line-height: 1;
            opacity: .85;
        }

        .audio-controls-time[aria-label="current"] {
            margin-left: .375em;
        }

        .audio-controls-time[aria-label="remaining"]::before {
            content: "/";
            margin: 0 .25em;
        }

        /********** 时间轴 **********/
        .audio-controls-timeline {
            -webkit-appearance: none;
            flex: 1;
            height: .25em;
            margin-left: 1em;
            font-size: 100%;
            color: inherit;
            background: currentColor;
            border-radius: .25em;
            mix-blend-mode: darken;
        }

        .audio-controls-timeline::-webkit-slider-thumb {
            -webkit-appearance: none;
            width: 0;
            height: 0;
            border: .375em solid;
            border-radius: 50%;
            box-shadow: 50vw 0 0 50vw rgba(255,255,255,.5);
        }
    </style>
</head>

<body>
    <div class="audio-controls">
        <div class="audio-controls-inner">
            <button class="audio-controls-button" aria-label="play">
            </button>
            <span class="audio-controls-time" aria-label="current">0:05</span>
            <span class="audio-controls-time" aria-label="remaining">0:05</span>
            <input class="audio-controls-timeline" type="range" max="5000" value="2000" />
            <button class="audio-controls-button" aria-label="volume">
                <span class="audio-controls-button-volume-icon">
                    <i></i>
                </span>
            </button>
            <button class="audio-controls-button" aria-label="menu">
            </button>
        </div>
    </div>
</body>

</html>

实现要点

  1. 自适应使用flex是比较好的方法,图标按钮尺寸固定,进度条宽度自适应;
  2. 进度条使用 input[type="range"] 是非常棒的实现与想法;
  3. 自适应不是等比例缩放,而是进度条宽度自适应;
  4. 注意视觉还原;
  5. 命名上注意上下文,例如audio-开头;
  6. CSS图标尽量使用伪元素,更好维护;
  7. CSS图标常用技巧:万能,box-shadow,linear-gradient/radial-radient,clip-path。

CSS测试五

2019 07 22 12 00 45

具体实现

grid

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    body {
      background-color: white;
    }

    /* css reset */
    html {
      font-size: 16px;
    }

    ul {
      padding: 0;
      margin: 0;
      list-style: none;
    }

    /* 布局 */
    .square-box {
      display: grid;
      grid-template-columns: repeat(5, 1fr);  /* 划分 5 个等宽片段 */
      grid-template-rows: 1fr 1fr;
      grid-gap: .5rem .375rem;
    }

    .square-item {
      padding-bottom: 100%;  /* 容器的 padding 百分比值按其宽度来计算 */
      outline: .15rem solid transparent;
    }

    .square-item.active {
      outline-color: #222;
    }

    /* 颜色 */
    .bg-dark {
      background: #424242;
    }

    .bg-gray {
      background: #8c8c8c;
    }

    .bg-sienna {
      background: #d48b69;
    }

    .bg-gold {
      background: #fecb66;
    }

    .bg-crimson {
      background: #c54941;
    }

    .bg-orchid {
      background: #591c93;
    }

    .bg-silver {
      background: #e6e6e6;
    }

    /* 响应式断点(CSS基础测试4),基于 iPhone6 尺寸 */
    @media screen and (min-width: 375px) {
      html {
        font-size: calc(100% + 2 * (100vw - 375px) / 39);
        font-size: calc(16px + 2 * (100vw - 375px) / 39);
      }
    }

    @media screen and (min-width: 414px) {
      html {
        font-size: calc(112.5% + 4 * (100vw - 414px) / 586);
        font-size: calc(18px + 4 * (100vw - 414px) / 586);
      }
    }
  </style>
</head>

<body>
  <ul class="square-box">
    <li class="square-item bg-dark"></li>
    <li class="square-item bg-gray"></li>
    <li class="square-item bg-sienna active"></li>
    <li class="square-item bg-gold"></li>
    <li class="square-item bg-crimson"></li>
    <li class="square-item bg-orchid"></li>
    <li class="square-item bg-silver"></li>
  </ul>
</body>
</html>

flex

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    body {
      background-color: white;
    }

    .layout {
      padding: 4%;
      border: 1px solid #e8e8e8;
    }

    .layout-inner {
      display: flex;
      flex-wrap: wrap;
      flex-grow: 0;
    }

    .layout-item {
      flex-basis: 20%;
    }

    .layout-item-inner {
      position: relative;
      padding: 50%;
    }

    .layout-item-content {
      position: absolute;
      top: 10%;
      bottom: 10%;
      right: 10%;
      left: 10%;
      margin: auto;
    }

    .layout-item--active .layout-item-content {
      outline: #272423 4px solid;
    }

    .layout-item:nth-child(7n+1) .layout-item-content {
      background: #424242;
    }

    .layout-item:nth-child(7n+2) .layout-item-content {
      background: #8c8c8c;
    }

    .layout-item:nth-child(7n+3) .layout-item-content {
      background: #d38b69;
    }

    .layout-item:nth-child(7n+4) .layout-item-content {
      background: #fecb66;
    }

    .layout-item:nth-child(7n+5) .layout-item-content {
      background: #c54941;
    }

    .layout-item:nth-child(7n+6) .layout-item-content {
      background: #581c93;
    }

    .layout-item:nth-child(7n) .layout-item-content {
      background: #e6e6e6;
    }
  </style>
</head>

<body>
  <div class="layout">
    <div class="layout-inner">
      <div class="layout-item">
        <div class="layout-item-inner">
          <div class="layout-item-content">
          </div>
        </div>
      </div>
      <div class="layout-item">
        <div class="layout-item-inner">
          <div class="layout-item-content">
          </div>
        </div>
      </div>
      <div class="layout-item layout-item--active">
        <div class="layout-item-inner">
          <div class="layout-item-content">
          </div>
        </div>
      </div>
      <div class="layout-item">
        <div class="layout-item-inner">
          <div class="layout-item-content">
          </div>
        </div>
      </div>
      <div class="layout-item">
        <div class="layout-item-inner">
            <div class="layout-item-content">
            </div>
        </div>
      </div>
    </div>
  </div>
</body>
</html>

inline-block

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    body {
      background-color: white;
      margin: 0;
    }

    ul {
      padding: 0;
    }

    .box {
      --margin: 1%;
      font-size: 0;
    }

    li {
      width: 0;
      height: 0;
      padding: calc((100% / var(--itemNumber)) / 2 - var(--margin));
      display: inline-block;
      position: relative;
      margin: var(--margin);
    }

    li input {
      opacity: 0;
      position: absolute;
      top: 0;
      left: 0;
      margin: 0;
      width: 100%;
      height: 100%;
      z-index: 1;
    }

    li input:checked + .item {
      outline: 4px solid #222;
    }

    .item {
      position: absolute;
      top: 0;
      right: 0;
      left: 0;
      bottom: 0;
    }

    li:nth-child(7n+1) .item {
      background-color: #424242;
    }

    li:nth-child(7n+2) .item {
      background-color: #8c8c8c;
    }

    li:nth-child(7n+3) .item {
      background-color: #d48b69;
    }

    li:nth-child(7n+4) .item {
      background-color: #fecb66;
    }

    li:nth-child(7n+5) .item {
      background-color: #c54940;
    }

    li:nth-child(7n+6) .item {
      background-color: #591c93;
    }

    li:nth-child(7n+7) .item {
      background-color: #e6e6e6;
    }
  </style>
</head>

<body>
  <ul class="box" style="--itemNumber: 3">
    <li>
      <input type="radio" name="radio">
      <div class="item"></div>
    </li>
    <li>
      <input type="radio" name="radio">
      <div class="item"></div>
    </li>
    <li>
      <input type="radio" name="radio">
      <div class="item"></div>
    </li>
    <li>
      <input type="radio" name="radio">
      <div class="item"></div>
    </li>
    <li>
      <input type="radio" name="radio">
      <div class="item"></div>
    </li>
    <li>
      <input type="radio" name="radio">
      <div class="item"></div>
    </li>
    <li>
      <input type="radio" name="radio">
      <div class="item"></div>
    </li>
  </ul>
</body>
</html>

实现要点

  1. 在grid布局中,每个子项所相对计算的宽度已经划分好了,并不是父元素的宽度;
  2. outline的优点的扩展的时候不占据额外的空间尺寸,但是缺点是强占了:focus聚焦状态样式,更推荐使用box-shadow实现;
  3. flex布局也是可以指定宽度,包括百分比;
  4. 正方形实现大家都用的是padding百分比,很好也很奇怪,如果你的宽度是使用calc计算得到(非百分比计算),设置height与之一样即可。
  5. 自适应的实现:1. grid布局;2. flex(宽度要设置);3. float;4.inline-block;都是可以的。
  6. 关于选中态实现最推荐的方法:使用radio单选。优点:1. 无需任何JS参与; 2. 语义非常好,包括对辅助设备;3. 开发也很便捷;其他类似场景:新用户注册会让选择感兴趣的标签,也可以使用类似技术。

CSS测试六

2019 07 22 15 04 33

具体实现

absolute

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        dl {
            border: 1px solid #000;
        }

        dt {
            position: absolute;
        }

        dd {
            text-align: right;
            margin-left: 5em;
            word-break: break-all;
        }

        dd:empty::before {
            content: '--';
            color: #999;
        }
        /* 
            此方法兼容性非常好,低版本IE浏览器也支持,
            但position:absolute元素的层叠顺便比较高,如果页面布局复杂,
            出现了元素层叠的场景,则此方法需要斟酌下,因为很可能会增加布局的复杂度(额外的z-index进行层级控制)。
        */
    </style>
</head>

<body>
    <dl>
        <dt>手机系统</dt>
        <dd>Android</dd>
        <dt>登录方式</dt>
        <dd>QQ互联登录</dd>
        <dt>绑定时间</dt>
        <dd></dd><!-- 内容为空的情况 -->
        <dt>绑定状态</dt>
        <dd>有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效</dd><!-- 内容溢出的情况 -->        
    </dl>
</body>

</html>

display: flex + width: calc(100% - 5em)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        dl {
            border: 1px solid #000;
            display: flex;
            flex-wrap: wrap;
        }

        dt {
            width: 5em;
        }

        dd {
            width: calc(100% - 5em);
            margin-left: 0;
            text-align: right;
            word-break: break-all;
        }

        dd:empty::before {
            content: '--';
            color: #999;
        }
    </style>
</head>

<body>
    <dl>
        <dt>手机系统</dt>
        <dd>Android</dd>
        <dt>登录方式</dt>
        <dd>QQ互联登录</dd>
        <dt>绑定时间</dt>
        <dd></dd><!-- 内容为空的情况 -->
        <dt>绑定状态</dt>
        <dd>有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效</dd><!-- 内容溢出的情况 -->
    </dl>
</body>

</html>

grid + grid-template-columns: auto 1fr

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        dl {
            border: 1px solid #000;
            display: grid;
            grid-template-columns: auto 1fr; /* auto代表分配剩余宽度,1fr代表自适应于内容*/
            grid-column-gap: 1em;
        }

        dd {
            text-align: right;
            margin-left: 0;
            word-break: break-all;
        }

        dd:empty::before {
            content: '--';
            color: #999;
        }
    </style>
</head>

<body>
    <dl>
        <dt>手机系统</dt>
        <dd>Android</dd>
        <dt>登录方式</dt>
        <dd>QQ互联登录</dd>
        <dt>绑定时间</dt>
        <dd></dd><!-- 内容为空的情况 -->
        <dt>绑定状态</dt>
        <dd>有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效</dd><!-- 内容溢出的情况 -->        
    </dl>
</body>

</html>

float: left + overflow: hidden

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        dl {
            border: 1px solid #000;
        }

        dt {
            float: left;
            width: 5em;
        }

        dd {
            text-align: right;
            word-break: break-all;
            overflow: hidden; /* 防止文字内容多的时候环绕 dt 元素 */
        }

        dd:empty::before {
            content: '--';
            color: #999;
        }
    </style>
</head>

<body>
    <dl>
        <dt>手机系统</dt>
        <dd>Android</dd>
        <dt>登录方式</dt>
        <dd>QQ互联登录</dd>
        <dt>绑定时间</dt>
        <dd></dd><!-- 内容为空的情况 -->
        <dt>绑定状态</dt>
        <dd>有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效</dd><!-- 内容溢出的情况 -->        
    </dl>
</body>

</html>

margin: -1.5em 0 0 5em

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background-color: white;
        }
        
        dl {
            border: 1px solid #000;
        }

        dd {
            margin-top: -1.5em;
            margin-left: 5em;
            text-align: right;
            word-break: break-all;
        }

        dd:empty::before {
            content: '--';
            color: #999;
        }
    </style>
</head>

<body>
    <dl>
        <dt>手机系统</dt>
        <dd>Android</dd>
        <dt>登录方式</dt>
        <dd>QQ互联登录</dd>
        <dt>绑定时间</dt>
        <dd></dd><!-- 内容为空的情况 -->
        <dt>绑定状态</dt>
        <dd>有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效有效</dd><!-- 内容溢出的情况 -->
    </dl>
</body>

</html>

CSS测试七

2019 07 29 16 00 26

具体实现

我的解答

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    body {
      background-color: white;
    }

    .icon-delete {
      position: relative;
      display: inline-block;
      cursor: default;
      margin-top: 30px;
      margin-left: 30px;
      color: #000;
    }

    .css-tips::before {
      visibility: hidden;
      opacity: 0;
      transition: all 0.5s;
      position: absolute;
      left: 50%;
      transform: translateX(-50%);
      content: attr(data-title);
      font-size: 14px;
      background: #000;
      width: max-content;
      /* white-space: nowrap; */
      color: #fff;
      top: -32px;
      border-radius: 4px;
      padding: 4px 8px;
    }

    .css-tips::after {
      visibility: hidden;
      opacity: 0;
      transition: all 0.5s;
      position: absolute;
      left: 50%;
      top: -5px;
      transform: translateX(-50%);
      content: '';
      border: 8px solid transparent;
      border-top-color: #000;
    }

    .css-tips:hover::before,
    .css-tips:hover::after {
      visibility: visible;
      opacity: 1;
    }
  </style>
</head>

<body>
  <a
    href="javascript:"
    class="icon-delete css-tips"
    data-title="删除按钮"
    role="button"
  >
    删除
  </a>
</body>

</html>

最佳解答

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    body {
      background-color: white;
    }

    .con {
      display: inline-block;
      margin: 50px 80px;
    }

    .css-tips {
      vertical-align: middle;
      cursor: pointer;
    }

    [data-title] {
      position: relative;
      overflow: visible;
    }

    .css-tips[data-title]:before,
    .css-tips[data-title]:after {
      display: block;
      position: absolute;
      z-index: 1;
      left: 50%;
      bottom: 100%;
      transform: translate(-50%, -20px);
      opacity: 0;
      transition: .15s .15s;
      color: #373c42;
      visibility: hidden;
    }

    .css-tips[data-title]:before {
      content: attr(data-title);
      border-radius: 3px;
      padding: 6px 10px;
      line-height: 18px;
      text-align: left;
      background-color: #373c42;
      color: #fff;
      font-size: 12px;
      font-style: normal;
      white-space: nowrap;
    }

    .css-tips[data-title]:after {
      content: '';
      width: 0;
      height: 0;
      margin-bottom: -12px;
      overflow: hidden;
      border: 6px solid transparent;
      border-top-color: currentColor;
    }

    .css-tips[data-title]:hover:before,
    .css-tips[data-title]:hover:after {
      visibility: visible;
      transform: translate(-50%, -10px);
      opacity: 1;
    }

    /* right */
    .css-tips[data-title][data-title-dir="right"]:before,
    .css-tips[data-title][data-title-dir="right"]:after{
      left: 100%;
      top: 50%;
      bottom: auto;
      transform: translate(20px, -50%);
    }
    .css-tips[data-title][data-title-dir="right"]:after {
      margin: 0;
      margin-left: -12px;
      border-color: transparent;
      border-right-color: currentColor;
    }
    .css-tips[data-title][data-title-dir="right"]:hover:before,
    .css-tips[data-title][data-title-dir="right"]:hover:after {
      visibility: visible;
      transform: translate(10px, -50%);
      opacity: 1;
    }

    /* bottom */
    .css-tips[data-title][data-title-dir="bottom"]:before,
    .css-tips[data-title][data-title-dir="bottom"]:after{
      left: 50%;
      top: 100%;
      bottom: auto;
      transform: translate(-50%, 20px);
    }
    .css-tips[data-title][data-title-dir="bottom"]:after {
      margin: 0;
      margin-top: -12px;
      border-color: transparent;
      border-bottom-color: currentColor;
    }
    .css-tips[data-title][data-title-dir="bottom"]:hover:before,
    .css-tips[data-title][data-title-dir="bottom"]:hover:after {
      visibility: visible;
      transform: translate(-50%, 10px);
      opacity: 1;
    }

    /* left */
    .css-tips[data-title][data-title-dir="left"]:before,
    .css-tips[data-title][data-title-dir="left"]:after{
      left: auto;
      right: 100%;
      top: 50%;
      bottom: auto;
      transform: translate(-20px, -50%);
    }
    .css-tips[data-title][data-title-dir="left"]:after {
      margin: 0;
      margin-right: -12px;
      border-color: transparent;
      border-left-color: currentColor;
    }
    .css-tips[data-title][data-title-dir="left"]:hover:before,
    .css-tips[data-title][data-title-dir="left"]:hover:after {
      visibility: visible;
      transform: translate(-10px, -50%);
      opacity: 1;
    }

    /* muti */
    .css-tips[data-title][data-title-muti]:before {
      width: 150px;
      white-space: normal;
    }

    /* success */
    .css-tips[data-title][data-title-type="success"]:before {
      background-color: #52c41a;
    }
    .css-tips[data-title][data-title-type="success"]:after {
      color:#52c41a;
    }
    /* error */
    .css-tips[data-title][data-title-type="error"]:before {
      background-color: #f5222d;
    }
    .css-tips[data-title][data-title-type="error"]:after {
      color:#f5222d;
    }
    /* warn */
    .css-tips[data-title][data-title-type="warn"]:before {
      background-color: #faad14;
    }
    .css-tips[data-title][data-title-type="warn"]:after {
      color:#faad14;
    }

  </style>
</head>

<body>
  <div class="con">
    <span class="css-tips" data-title="删除删除删除" data-title-dir="up">提示上</span>
  </div>
  <div class="con">
    <span class="css-tips" data-title="删除删除删除" data-title-dir="right">提示右</span>
  </div>
  <div class="con">
    <span class="css-tips" data-title="删除删除删除" data-title-dir="bottom">提示下</span>
  </div>
  <div class="con">
    <span class="css-tips" data-title="删除删除删除" data-title-dir="left">提示左</span>
  </div>
  <br>
  <div class="con">
    <span class="css-tips" data-title="删除删除删除删除删除删除删除删除删除" data-title-dir="right" data-title-muti>多行提示</span>
  </div>
  <br>
  <div class="con">
    <span class="css-tips" data-title="删除删除删除删除" data-title-type="success">温馨提示</span>
  </div>
  <div class="con">
    <span class="css-tips" data-title="删除删除删除" data-title-type="error">危险提示</span>
  </div>
  <div class="con">
    <span class="css-tips" data-title="删除删除删除删除" data-title-type="warn">警告提示</span>
  </div>
</body>

</html>

实现要点

  1. 考虑各种字号场景,使用bottom定位,calc()或者margin-bottom微调位置;
  2. transform增加-ms-前缀,兼容IE9;
  3. 考虑边界场景,例如在浏览器上边缘,或者侧面时候;
  4. 考虑增加延迟显示,使用visibility+transition,或者pointer-events: none(渐进增强);
  5. 考虑键盘访问,增加:focus伪类显示。

CSS测试八

2019 07 30 10 15 24

具体实现

我的解答

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    body {
      background-color: white;
    }

    .chat-list {
      padding: 4px;
    }

    .chat-item {
      position: relative;
      margin-bottom: 32px;
    }

    .chat-avatar {
      display: inline-block;
      vertical-align: top;
      margin-right: 12px;
    }

    .chat-avatar img {
      border-radius: 50%;
      width: 64px;
      height: 64px;
    }

    .chat-content {
      vertical-align: top;
      display: inline-block;
    }

    .chat-header {
      color: rgb(164, 173, 187);
      font-size: 18px;
      margin-bottom: 6px;
    }

    .chat-bubble {
      border-radius: 4px;
      padding: 12px 18px;
      background: rgb(245, 247, 250);
      position: relative;
      word-break: break-all;
    }

    .friend .chat-bubble::before {
      content: '';
      position: absolute;
      border: solid transparent;
      border-width: 6px 10px;
      border-right-color: rgb(245, 247, 250);
      left: -20px;
      top: 4px;
    }

    .self {
      text-align: right;
    }

    .self .chat-content {
      margin-right: 76px;
    }

    .self .chat-avatar{
      position: absolute;
      right: 0;
      margin: 0;
      margin-left: 12px;
    }

    .self .chat-bubble {
      background: rgb(0, 190, 255);
      color: #fff;
    }

    .self .chat-bubble::before {
      content: '';
      position: absolute;
      border: solid transparent;
      border-width: 6px 10px;
      border-left-color: rgb(0, 190, 255);
      right: -20px;
      top: 4px;
    }
  </style>
</head>

<body>
  <div class="chat-list">
    <div class="chat-item friend">
      <div class="chat-avatar">
        <img src="https://tva4.sinaimg.cn/crop.0.0.750.750.180/75f2b996jw8f6zkdm7qp7j20ku0kudgr.jpg" />
      </div>
      <div class="chat-content">
        <div class="chat-header">
          提案笙 9月30日 21:47
        </div>
        <div class="chat-bubble">
          什么秘密,我觉得你现在跟我说什么都没有意义。333333333333333333333333333333333333333333333333333333333333333333333333333333
        </div>
      </div>
    </div>
    <div class="chat-item friend">
      <div class="chat-avatar">
        <img src="https://tvax4.sinaimg.cn/crop.0.0.512.512.180/6cd7bd09ly8fsnom1e5wtj20e80e8gm7.jpg" />
      </div>
      <div class="chat-content">
        <div class="chat-header">
          淮南王铃 10月8日 10:30
        </div>
        <div class="chat-bubble">
          @蝴蝶蓝 优秀
        </div>
      </div>
    </div>
    <div class="chat-item friend">
      <div class="chat-avatar">
        <img src="https://tvax4.sinaimg.cn/crop.0.0.512.512.180/6cd7bd09ly8fsnom1e5wtj20e80e8gm7.jpg" />
      </div>
      <div class="chat-content">
        <div class="chat-header">
          蝴蝶蓝 昨天 22::13
        </div>
        <div class="chat-bubble">
          值得一听~~
        </div>
      </div>
    </div>
    <div class="chat-item self">
      <div class="chat-avatar">
        <img src="https://tvax4.sinaimg.cn/crop.0.0.512.512.180/6cd7bd09ly8fsnom1e5wtj20e80e8gm7.jpg" />
      </div>
      <div class="chat-content">
        <div class="chat-header">
          刚刚 Y优秀X
        </div>
        <div class="chat-bubble">
          围观戏精现场
        </div>
      </div>
    </div>
  </div>
</body>

</html>

有几个缺点,宽度较小时会换行,消息气泡不够还原

relative + absolute + box-shadow

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    body,
    html {
      background-color: white;
      font-size: 15px;
    }

    .chat-item {
      position: relative;
      min-height: 4rem;
      /* 预留空间给头像 */
      padding: .5rem 4rem;
    }

    .chat-item .chat-header {
      font-size: .8rem;
      color: rgb(163, 171, 184);
    }

    .chat-item .chat-avatar > img {
      height: 100%;
    }

    .chat-item .chat-avatar {
      position: absolute;
      top: .5rem;
      overflow: hidden;
      width: 3rem;
      height: 3rem;
      border-radius: 50%;
    }

    .chat-item.friend .chat-avatar {
      left: .5rem;
    }

    .chat-item.self .chat-avatar {
      right: .5rem;
    }

    .chat-item.self {
      text-align: right;
    }

    .chat-item .chat-bubble {
      line-height: 1.5;
      position: relative;
      display: inline-block;
      margin: .25rem 0;
      padding: .6rem 1rem;
      border-radius: .5rem;
    }

    .chat-item.friend .chat-bubble{
      background: rgb(245, 247, 250);
    }

    .chat-item.self .chat-bubble{
      color: #fff;
      background: rgb(82, 188, 250);
    }

    .chat-item .chat-bubble::before {
      position: absolute;
      top: .02rem;
      width: 1.2rem;
      height: 1rem;
      content: '';
      border-radius: 50% 50% 0 0;
    }

    .chat-item.friend .chat-bubble::before {
      left: -1.2rem;
      /* 阴影处作为实际的小尾巴 */
      box-shadow: .5rem 0 0 0 rgb(245, 247, 250);
    }

    .chat-item.self .chat-bubble::before {
      right: -1.2rem;
      box-shadow: -.5rem 0 0 0 rgb(82, 188, 250);
    }
  </style>
</head>

<body>
  <div class="chat-list">
    <div class="chat-item friend">
      <div class="chat-avatar">
        <img src="https://tva4.sinaimg.cn/crop.0.0.750.750.180/75f2b996jw8f6zkdm7qp7j20ku0kudgr.jpg" />
      </div>
      <div class="chat-header">
        提案笙 9月30日 21:47
      </div>
      <div class="chat-bubble">
        什么秘密,我觉得你现在跟我说什么都没有意义。333333333333333333333333333333333333333333333333333333333333333333333333333333
      </div>
    </div>
    <div class="chat-item friend">
      <div class="chat-avatar">
        <img src="https://tvax4.sinaimg.cn/crop.0.0.512.512.180/6cd7bd09ly8fsnom1e5wtj20e80e8gm7.jpg" />
      </div>
      <div class="chat-header">
        淮南王铃 10月8日 10:30
      </div>
      <div class="chat-bubble">
        @蝴蝶蓝 优秀
      </div>
    </div>
    <div class="chat-item friend">
      <div class="chat-avatar">
        <img src="https://tvax4.sinaimg.cn/crop.0.0.512.512.180/6cd7bd09ly8fsnom1e5wtj20e80e8gm7.jpg" />
      </div>
      <div class="chat-header">
        蝴蝶蓝 昨天 22::13
      </div>
      <div class="chat-bubble">
        值得一听~~
      </div>
    </div>
    <div class="chat-item self">
      <div class="chat-avatar">
        <img src="https://tvax4.sinaimg.cn/crop.0.0.512.512.180/6cd7bd09ly8fsnom1e5wtj20e80e8gm7.jpg" />
      </div>
      <div class="chat-header">
        刚刚 Y优秀X
      </div>
      <div class="chat-bubble">
        围观戏精现场
      </div>
    </div>
  </div>
</body>

</html>

flex + flex: 1 + border-radius + direction: rtl

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .msg-list {
      height: 100%;
      overflow: auto;
      list-style: none;
      margin: 0;
      padding: 0;
    }

    .msg-item {
      display: flex;
      padding: 7px;
      margin-bottom: 15px;
    }

    .msg-item::after {
      content: '';
      display: inline-block;
      width: 44px;
    }

    .msg-avator {
      width: 44px;
      height: 44px;
      border-radius: 50%;
      object-fit: cover;
    }

    .msg-info {
      flex: 1;
      text-align: start;
      padding: 0 10px;
      overflow: hidden;
    }

    .msg-user {
      margin: 0;
      font-weight: normal;
      font-size: 13px;
      color: #949ead;
    }

    .msg-user span {
      display: inline-block;
    }

    .msg-time {
      padding: 0 8px;
    }

    .msg-txt {
      position: relative;
      display: inline-flex;
      background: #f2f5f9;
      border-color: #f2f5f9;
      font-size: 14px;
      line-height: 1.5;
      color: #2c3038;
      padding: .6em 1em;
      text-align: left;
      margin: 5px 0 0;
      border-radius: 6px;
    }

    .msg-txt::before {
      content: '';
      position: absolute;
      width: 1.4em;
      height: 1.2em;
      top: 0;
      margin-inline-start: -3em;
      -webkit-margin-start: -3em; /**qq浏览器有点兼容性问题,需要加上这个**/
      border-top-right-radius: 40% 50%;
      border-top-left-radius: 40% 50%;
      border-left: 0.6em solid;
      border-right: 0.6em solid;
      border-color: inherit;
    }

    /** data-self(message from myself) **/
    .msg-item[data-self] {
      direction: rtl;/*改变css流向*/
    }

    .msg-item[data-self] .msg-txt {
      background: #00afff;
      border-color: #00afff;
      color: #fff;
    }
  </style>
</head>

<body>
  <ul class="msg-list">
    <li class="msg-item">
      <img class="msg-avator" alt="head" src="https://tva4.sinaimg.cn/crop.0.0.750.750.180/75f2b996jw8f6zkdm7qp7j20ku0kudgr.jpg" >
      <div class="msg-info">
        <h3 class="msg-user">
          <span class="msg-name">提按生</span>
          <span class="msg-time">9月30日 21:47</span>
        </h3>
        <p class="msg-txt">什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密</p>
      </div>
    </li>
    <li class="msg-item">
      <img class="msg-avator" alt="head" src="https://tvax4.sinaimg.cn/crop.0.0.512.512.180/6cd7bd09ly8fsnom1e5wtj20e80e8gm7.jpg" >
      <div class="msg-info">
        <h3 class="msg-user">
          <span class="msg-name">提按生</span>
          <span class="msg-time">9月30日 21:47</span>
        </h3>
        <p class="msg-txt">什么秘密</p>
      </div>
    </li>
    <li class="msg-item" data-self>
      <img class="msg-avator" alt="head" src="https://tvax3.sinaimg.cn/crop.135.0.810.810.180/006LO43wly8frjay2sypvj30u00mita5.jpg" >
      <div class="msg-info">
        <h3 class="msg-user">
          <span class="msg-name">提按生</span>
          <span class="msg-time">9月30日 21:47</span>
        </h3>
        <p class="msg-txt">什么秘密</p>
      </div>
    </li>
    <li class="msg-item" data-self>
      <img class="msg-avator" alt="head" src="https://tvax3.sinaimg.cn/crop.135.0.810.810.180/006LO43wly8frjay2sypvj30u00mita5.jpg" >
      <div class="msg-info">
        <h3 class="msg-user">
          <span class="msg-name">提按生</span>
          <span class="msg-time">9月30日 21:47</span>
        </h3>
        <p class="msg-txt">什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密什么秘密</p>
      </div>
    </li>
    <li class="msg-item">
      <img class="msg-avator" alt="head" src="https://tva1.sinaimg.cn/crop.0.0.750.750.180/006bQeGsjw8f1tgl7z9ncj30ku0kuq44.jpg" >
      <div class="msg-info">
        <h3 class="msg-user">
          <span class="msg-name">提按生</span>
          <span class="msg-time">9月30日 21:47</span>
        </h3>
        <p class="msg-txt">什么秘密</p>
      </div>
    </li>
  </ul>
</body>

</html>

实现要点

  1. 基准字号使用16px,不用其它像素值。也不用使用100px。
  2. media查询和vw技巧实现html基础尺寸动态化(无需JS)。
  3. 要有统一的类名命名空间,类似chat-。
  4. 遇到不同性质的命名,通常两种方式。1. 类名,但是命名上明显区分,例如chat-item__left。2. 使用属性选择器。
  5. 避免没必要的嵌套,百害无一益。
  6. 小尾巴的实现。边框+圆角,box-shadow+圆角,径向渐变
  7. 左右对称布局的实现:direction: rtl配合CSS逻辑属性
  8. 不推荐使用dl标签,可以给每个列表增加tabindex=0

CSS测试九

2019 07 31 14 12 51

具体实现

最佳解答

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }
  </style>
</head>

<body>
  <form action="">
    <h3>登录</h3>
    <div>
      <input required type="text" placeholder="账户/手机" autocomplete="off" autofocus />
    </div>
    <div>
      <input required type="password" placeholder="密码" autocomplete="off" />
      <a href="/forget">忘记密码?</a>
    </div>
    <div>
      <input required type="text" placeholder="验证码" />
      <img src="" alt="验证码" />
    </div>
    <div>
      <button type="submit">登录</button>
    </div>
    <div>
      <a href='/reg'>立即注册</a>
    </div>
  </form>
</body>

</html>

实现要点

  1. <form> + submit
  2. <fieldset> + <legend>
  3. placeholder
  4. name
  5. required验证
  6. autocomplete=“off”
  7. tabindex/autofocus
  8. type=“text”可以缺省
  9. 忘记密码,立即注册最好使用<a>

CSS测试十

2019 08 23 14 24 28

具体实现

details > summary

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    ::-webkit-details-marker {
      display: none;
    }

    ::-moz-list-bullet {
      font-size: 0;
    }

    .ui-menu-wrap {
      width: 200px;
    }

    summary {
      outline: 0;
    }

    .ui-btn {
      line-height: 40px;
      padding: 0 25px;
      font-size: 14px;
      color: #666;
      transition: .3s;
      cursor: pointer;
    }

    .ui-btn:hover {
      background: #edf9ff;
      color: #33b2ee;
    }

    .ui-menu-list .ui-btn {
      display: block;
    }

    .ui-menu-summary {
      position: relative;
      padding: 0 10px;
      line-height: 40px;
      color: #333;
      font-size: 14px;
      font-weight: bold;
      cursor: pointer;
    }

    .ui-menu-summary::after {
      content: '';
      position: absolute;
      right: 10px;
      top: 50%;
      margin-top: 3px;
      width: 6px;
      height: 6px;
      border: 2px solid;
      border-width: 2px 2px 0 0;
      transform: translateY(-8px) rotate(135deg);
      transition: .3s;
    }

    .ui-menu[open] .ui-menu-summary::after {
      transform: translateY(-8px) rotate(-45deg);
    }
  </style>
</head>

<body>
  <div class="ui-menu-wrap">
    <details class="ui-menu" open>
      <summary class="ui-menu-summary">布局</summary>
      <div class="ui-menu-list">
        <a class="ui-btn">Flex 布局</a>
        <a class="ui-btn">Grid 布局</a>
        <a class="ui-btn">Shapes 布局</a>
        <a class="ui-btn">Flex 布局</a>
        <a class="ui-btn">Flex 布局</a>
      </div>
    </details>
    <details class="ui-menu" open>
      <summary class="ui-menu-summary">组件</summary>
      <div class="ui-menu-list">
        <a class="ui-btn">按钮</a>
        <a class="ui-btn">输入框</a>
        <a class="ui-btn">下拉列表</a>
        <a class="ui-btn">单选框</a>
      </div>
    </details>
  </div>
</body>

</html>

checkbox

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .ui-menu-wrap {
      width: 200px;
    }

    .ui-btn {
      line-height: 40px;
      padding: 0 25px;
      font-size: 14px;
      color: #666;
      transition: .3s;
      cursor: pointer;
    }

    .ui-btn:hover {
      background: #edf9ff;
      color: #33b2ee;
    }

    .ui-menu-list .ui-btn {
      display: block;
    }

    .ui-menu-summary {
      display: block;
      position: relative;
      line-height: 40px;
      padding: 0 10px;
      color: #333;
      font-size: 14px;
      font-weight: bold;
      cursor: pointer;
      transition: .3s;
      user-select: none;
    }

    .ui-menu-summary:focus {
      background: #edf9ff;
    }

    .ui-menu-summary::after {
      content: '';
      position: absolute;
      right: 10px;
      top: 50%;
      margin-top: 3px;
      width: 6px;
      height: 6px;
      border: 2px solid;
      border-width: 2px 2px 0 0;
      transform: translateY(-10px) rotate(135deg);
      transition: .3s;
    }

    .ui-menu-list {
      display: none;
    }

    .ui-menu > input[type="checkbox"]:checked + .ui-menu-summary::after {
      transform: translateY(-8px) rotate(-45deg);
    }

    .ui-menu > input[type="checkbox"] {
      /* 满足视觉上的隐藏,屏幕阅读设备等辅助设备也支持得很好。*/
      position: absolute;
      clip: rect(0, 0, 0, 0);
    }

    .ui-menu > input[type="checkbox"]:checked + .ui-menu-summary + .ui-menu-list {
      display: block;
    }
  </style>
</head>

<body>
  <div class="ui-menu-wrap">
    <div class="ui-menu">
      <input type="checkbox" id="menu01" checked>
      <label class="ui-menu-summary" for="menu01">布局1</label>
      <div class="ui-menu-list">
        <a class="ui-btn">Flex 布局</a>
        <a class="ui-btn">Grid 布局</a>
        <a class="ui-btn">Shapes 布局</a>
        <a class="ui-btn">Flex 布局</a>
        <a class="ui-btn">Flex 布局</a>
      </div>
    </div>
    <div class="ui-menu">
      <input type="checkbox" id="menu02" checked>
      <label class="ui-menu-summary" for="menu02">布局2</label>
      <div class="ui-menu-list">
        <a class="ui-btn">Flex 布局</a>
        <a class="ui-btn">Grid 布局</a>
        <a class="ui-btn">Shapes 布局</a>
        <a class="ui-btn">Flex 布局</a>
        <a class="ui-btn">Flex 布局</a>
      </div>
    </div>
  </div>
</body>

</html>

target

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .ui-menu-wrap {
      width: 200px;
    }

    .ui-btn {
      line-height: 40px;
      padding: 0 25px;
      font-size: 14px;
      color: #666;
      transition: .3s;
      cursor: pointer;
    }

    .ui-btn:hover {
      background: #edf9ff;
      color: #33b2ee;
    }

    .ui-menu-list .ui-btn {
      display: block;
    }

    .ui-menu-summary {
      display: block;
      position: relative;
      line-height: 40px;
      padding: 0 10px;
      color: #333;
      font-size: 14px;
      font-weight: bold;
      cursor: pointer;
      transition: .3s;
      user-select: none;
      text-decoration: none;
    }

    .ui-menu-summary:focus {
      background: #edf9ff;
    }

    .ui-menu-summary::after {
      content: '';
      position: absolute;
      right: 10px;
      top: 50%;
      margin-top: 3px;
      width: 6px;
      height: 6px;
      border: 2px solid;
      border-width: 2px 2px 0 0;
      transform: translateY(-10px) rotate(135deg);
      transition: .3s;
    }

    .ui-menu-list {
      display: none;
    }

    .ui-menu-summary:target::after {
      transform: translateY(-8px) rotate(-45deg);
    }

    .ui-menu-summary:target + .ui-menu-list {
      display: block;
    }
  </style>
</head>

<body>
  <div class="ui-menu-wrap">
    <div class="ui-menu">
      <a class="ui-menu-summary" id="menu01" href="#menu01">布局</a>
      <div class="ui-menu-list">
        <a class="ui-btn">Flex 布局</a>
        <a class="ui-btn">Grid 布局</a>
        <a class="ui-btn">Shapes 布局</a>
        <a class="ui-btn">Flex 布局</a>
        <a class="ui-btn">Flex 布局</a>
      </div>
    </div>
    <div class="ui-menu">
      <a class="ui-menu-summary" id="menu02" href="#menu02">组件</a>
      <div class="ui-menu-list">
        <a class="ui-btn">按钮</a>
        <a class="ui-btn">输入框</a>
        <a class="ui-btn">下拉列表</a>
        <a class="ui-btn">单选框</a>
      </div>
    </div>
  </div>
</body>

</html>

focus-within

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .ui-menu-wrap {
      width: 200px;
    }

    .ui-btn {
      line-height: 40px;
      padding: 0 25px;
      font-size: 14px;
      border: 0;
      width: 100%;
      background: none;
      outline: 0;
      text-align: left;
      color: #666;
      transition: .3s;
      cursor: pointer;
    }

    .ui-btn:hover {
      background: #edf9ff;
      color: #33b2ee;
    }

    .ui-menu-list .ui-btn {
      display: block;
    }

    .ui-menu-summary {
      display: block;
      position: relative;
      line-height: 40px;
      padding: 0 10px;
      color: #333;
      font-size: 14px;
      font-weight: bold;
      border: 0;
      width: 100%;
      background: none;
      cursor: pointer;
      outline: 0;
      text-align: left;
      transition: .3s;
      user-select: none;
      text-decoration: none;
    }

    .ui-menu-summary:focus {
      /* 从可获焦元素开始一直冒泡到根元素 html,都可以接收触发 :focus-within 事件 */
      background: #edf9ff;
    }

    .ui-menu-summary::after {
      content: '';
      position: absolute;
      right: 10px;
      top: 50%;
      margin-top: 3px;
      width: 6px;
      height: 6px;
      border: 2px solid;
      border-width: 2px 2px 0 0;
      transform: translateY(-10px) rotate(135deg);
      transition: .3s;
    }

    .ui-menu-list {
      display: none;
    }

    .ui-menu:focus-within .ui-menu-summary::after {
      transform: translateY(-8px) rotate(-45deg);
    }

    .ui-menu:focus-within .ui-menu-list {
      display: block;
    }
  </style>
</head>

<body>
  <div class="ui-menu-wrap">
    <div class="ui-menu">
      <button class="ui-menu-summary">布局</button>
      <div class="ui-menu-list">
        <button class="ui-btn">Flex 布局</button>
        <button class="ui-btn">Grid 布局</button>
        <button class="ui-btn">Shapes 布局</button>
        <button class="ui-btn">Flex 布局</button>
        <button class="ui-btn">Flex 布局</button>
      </div>
    </div>
    <div class="ui-menu">
      <button class="ui-menu-summary">组件</button>
      <div class="ui-menu-list">
        <button class="ui-btn">按钮</button>
        <button class="ui-btn">输入框</button>
        <button class="ui-btn">下拉列表</button>
        <button class="ui-btn">单选框</button>
      </div>
    </div>
  </div>
</body>

</html>

实现要点

  1. 视觉还原才是重点。
  2. details > summary 是最好的实现。可以进一步注意语义化。这个方法IE/Edge是不支持。所以可以用来判断是否是IE内核浏览器,var isIE = !(‘open’ in document.createElement(‘details’))。所以如果要兼容IE,可以写个polyfill。
  3. :checked方法交互也可以实现,但语义欠佳,不是这种交互的最佳实践。注意优化选择器。
  4. :target方法有触发锚点定位的问题,可以使用一个隐藏的空div元素曲线救国。
  5. :focus-within只要子元素有focus,就能匹配。是目前最先支持的具有“父选择器”特性的伪类。最佳实践是下拉菜单。类似的选择器还有 :target-within。
  6. 元素聚焦,同时聚焦轮廓浏览器认为应该显示。:focus:not(:focus-visible) { outline: 0; }
  7. 注意不要过度无障碍设置

CSS测试十一

实现思路与CSS测试六基本一致

2019 09 04 20 50 23

具体实现

float: left + overflow: hidden(我的实现)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .article {
      background: rgb(255, 248, 220);
      border: 1px solid #eee;
      border-radius: 5px;
      width: 300px;
    }

    .title {
      padding: 14px;
      font-size: 14px;
      background: rgb(247, 241, 213);
      border-bottom: 1px solid #eee;
    }

    .item {
      padding: 12px 18px;
      overflow: hidden;
    }

    .item:not(:last-child) {
      border-bottom: 1px solid #eee;
    }

    .item .content {
      overflow: hidden;
      display: -webkit-box;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
    }

    .item a {
      text-decoration: none;
    }

    .icon {
      float: left;
      width: 16px;
      margin-right: 6px;
    }

    .icon::before {
      content: '';
      display: inline-block;
      width: 16px;
      height: 16px;
      position: relative;
      top: 3px;
    }

    .icon-book::before {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512'%3E %3Cpath fill='%23828380' d='M567.403 235.642L462.323 84.589A48 48 0 0 0 422.919 64H153.081a48 48 0 0 0-39.404 20.589L8.597 235.642A48.001 48.001 0 0 0 0 263.054V400c0 26.51 21.49 48 48 48h480c26.51 0 48-21.49 48-48V263.054c0-9.801-3-19.366-8.597-27.412zM153.081 112h269.838l77.913 112H75.168l77.913-112zM528 400H48V272h480v128zm-32-64c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32zm-96 0c0 17.673-14.327 32-32 32s-32-14.327-32-32 14.327-32 32-32 32 14.327 32 32z'%3E%3C/path%3E %3C/svg%3E");
    }

    .icon-discuss::before {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E %3Cpath fill='%232d82ce' d='M448 0H64C28.7 0 0 28.7 0 64v288c0 35.3 28.7 64 64 64h96v84c0 7.1 5.8 12 12 12 2.4 0 4.9-.7 7.1-2.4L304 416h144c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64zm16 352c0 8.8-7.2 16-16 16H288l-12.8 9.6L208 428v-60H64c-8.8 0-16-7.2-16-16V64c0-8.8 7.2-16 16-16h384c8.8 0 16 7.2 16 16v288z'%3E%3C/path%3E %3C/svg%3E");
    }
  </style>
</head>

<body>
  <div class="article">
    <div class="title">
      标题
    </div>
    <div class="body">
      <div class="item">
        <div class="icon icon-discuss"></div>
        <div class="content">
          <a href="#">
            恭喜我们29个最老的测试版网站-他们现在不再是测试版了!
          </a>
        </div>
      </div>
      <div class="item">
        <div class="icon icon-discuss"></div>
        <div class="content">
          <a href="#">
            《独角兽动物园》35;7:Nicolas访谈
          </a>
        </div>
      </div>
      <div class="item">
        <div class="icon icon-book"></div>
        <div class="content">
          <a href="#">
            减少需要重新审查的封闭问题数量的建议
          </a>
        </div>
      </div>
      <div class="item">
        <div class="icon icon-book"></div>
        <div class="content">
          <a href="#">
            实验:在接下来的30天内(直到2019-09-07),以3票为基准关闭和重新打开提出的问题
          </a>
        </div>
      </div>
    </div>
  </div>
</body>

</html>

background-position

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .ui-content {
      width: 300px;
      font-size: 12px;
      border: 1px solid #e6dfc6;
    }

    .ui-title {
      font-size: inherit;
      color: #737063;
      margin: 0;
      padding: 1em 1.2em;
      background: #f7f1d5;
    }

    .ui-list {
      list-style: none;
      margin: 0;
      padding: 0;
      background: #fff8dc;
    }

    .ui-item {
      border-top: 1px solid #ede7cd;
      padding: 1em 1.2em;
      line-height: 1.4;
    }

    .ui-link {
      display: block;
      display: -webkit-box;
      text-decoration: none;
      color: #0077cc;
      overflow: hidden;
      -webkit-box-orient: vertical;
      -webkit-line-clamp: 2;
      max-height: 2.8em;
    }

    .ui-item[type] {
      padding-left: 2.7em;
      background-position: 1em 1em;
      background-repeat: no-repeat;
      background-size: 1.2em 1.2em;
    }

    .ui-item[type="msg"] {
      background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M892.3 925.3c-15.5 0-30.5-6.5-41.4-18.6L759.7 805l-.6-.8c-2.7-3.3-6.6-5.2-10.9-5.2H232.1C146.6 799 77 729.5 77 643.9V233.6c0-85.5 69.6-155.1 155.1-155.1h559c85.5 0 155.1 69.6 155.1 155.1v453.8c0 27.7 1.4 125.3 2.2 181.1.3 23.5-13.6 44.3-35.5 52.9-6.7 2.6-13.7 3.9-20.6 3.9zm-15.9-55.8s0 .1 0 0c0 .1 0 0 0 0zm-61.9-111.2l61.3 68.3c-.8-58-1.6-117.8-1.6-139.1V233.6c0-22.1-8.7-42.9-24.4-58.7-15.8-15.8-36.6-24.4-58.7-24.4h-559c-22.1 0-42.9 8.7-58.7 24.4-15.8 15.8-24.4 36.6-24.4 58.7v410.3c0 22.1 8.7 42.9 24.4 58.7 15.8 15.8 36.6 24.4 58.7 24.4h516.1c25.8 0 49.9 11.4 66.3 31.3z' fill='%2346a2d9'/%3E%3Cpath d='M763.5 373.6H274c-19.9 0-36-16.1-36-36s16.1-36 36-36h489.4c19.9 0 36 16.1 36 36s-16.1 36-35.9 36zM590.1 550.2H274c-19.9 0-36-16.1-36-36s16.1-36 36-36h316c19.9 0 36 16.1 36 36 .1 19.8-16 36-35.9 36z' fill='%2346a2d9'/%3E%3C/svg%3E")
    }
    .ui-item[type="exp"] {
      background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M810.07 932.907V659.669h91.05V1024H78.677V659.67h90.88v273.237H810.07zm-549.334-91.051h458.197v-91.179H260.736v91.179zm11.05-207.019l447.147 93.398 19.243-88.32-447.061-93.312-19.328 88.234zm57.985-215.722l414.08 193.28 38.528-83.2-414.123-193.28-38.485 82.602v.598zm115.84-204.16l350.592 292.48 57.984-69.12-350.55-292.395-57.6 68.992-.426.043zM672.043 0l-74.496 55.21 273.28 367.105 74.496-55.211L671.957 0h.086z' fill='%2352575c'/%3E%3C/svg%3E")
    }
  </style>
</head>

<body>
  <section class="ui-content">
    <h2 class="ui-title">标题</h2>
    <ul class="ui-list">
      <li class="ui-item" type="msg">
        <a class="ui-link" href="#">恭喜我们29个最老的测试版网站-他们现在不再是测试版了!</a>
      </li>
      <li class="ui-item" type="msg">
        <a class="ui-link" href="#">《独角兽动物园》35;7:Nicolas访谈</a>
      </li>
      <li class="ui-item" type="exp">
        <a class="ui-link" href="#">减少需要重新审查的封闭问题数量的建议</a>
      </li>
      <li class="ui-item" type="exp">
        <a class="ui-link" href="#">实验:在接下来的30天内(直到2019-09-07),以3票为基准关闭和重新打开提出的问题</a>
      </li>
    </ul>
  </section>
</body>

</html>

实现要点

  1. 关于HTML语义:article用在非常大段的完整的描述内容上。header是表示非常完整的整页的头部,不是具体某一两个标题头。对于一个文字列表的标题,级别h3~h6之间,通常是h3, h4(概率更大)。链接,一定要使用元素。
  2. 还是关于HTML语义:dl>dt+dd这里也是不合适的,虽然也是列表,但是这个是“定义列表(define list)>定义标题+定义描述”,这个一般用在对特定描述的解释上。比方说JS API解释。
  3. 就是关于链接的区域,应该wrap整个列表。为了和移动端的交互体验保持一致(方便胡萝卜一样的粗的手指可以精准点击)。a元素里面是可以放置块状元素的。比较好的HTML语义结构应该是:section>h4+ul>li>a
  4. 两栏自适应布局,之前有小测,这里就不重复展开,但是,要介绍一个比较有意思的实现:liyongleihf2006,使用text-indent负值,这个场景是相当合适的。
  5. 多行打点:display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; 多行打点 overflow:hidden不是必需的,和单行ellipsis不一样。然后可能有些小伙伴不知道的是:Firefox目前也支持了-webkit-box打点。
  6. 关于固有宽度,固有比例。这个《CSS世界》有介绍,在content内容生成那里url(xxx.png)。list-style-image: url(icon.svg)也是一样的,CSS的width/height是无法控制图片的尺寸的。

CSS测试十二

2019 09 26 19 34 12

具体实现

我的实现

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .img {
      width: 120px;
    }

    .item {
      margin-bottom: 36px;
    }

    .tag {
      position: absolute;
      color: white;
    }

    .block {
      padding: 2px;
      font-size: 12px;
      background: red;
    }

    .triangle {
      width: 28px;
      height: 28px;
      font-size: 12px;
      padding: 2px 4px;
      /* 0deg对应着垂直方向即to top,默认值为to bottom即180deg,顺时针增加; */
      background: linear-gradient(135deg, red 50%, transparent 0);
    }

    .block-triangle {
      width: 60px;
      height: 18px;
      padding: 2px 4px;
      font-size: 12px;
      /* 0deg对应着垂直方向即to top,默认值为to bottom即180deg,顺时针增加; */
      background: linear-gradient(110deg, red calc(100% - 12px), transparent 0);
    }

    .circle {
      width: 20px;
      height: 20px;
      border-bottom-right-radius: 20px;
      padding-left: 4px;
      padding-top: 4px;
      font-size: 12px;
      background: red;
    }

    .ellipse {
      width: 25px;
      height: 20px;
      border-bottom-right-radius: 15px;
      font-size: 12px;
      background: red;
    }
  </style>
</head>
<body>
  <div class="item">
    <span class="tag block">No.1</span>
    <img
      src="../../images/2019-09-26-19-49-51.png"
      alt="头像"
      class="img"
    />
  </div>

  <div class="item">
    <span class="tag triangle">1</span>
    <img
      src="../../images/2019-09-26-19-49-51.png"
      alt="头像"
      class="img"
    />
  </div>

  <div class="item">
    <span class="tag block-triangle">火热连载</span>
    <img
      src="../../images/2019-09-26-19-49-51.png"
      alt="头像"
      class="img"
    />
  </div>

  <div class="item">
    <span class="tag circle">1</span>
    <img
      src="../../images/2019-09-26-19-49-51.png"
      alt="头像"
      class="img"
    />
  </div>

  <div class="item">
    <span class="tag ellipse">100</span>
    <img
      src="../../images/2019-09-26-19-49-51.png"
      alt="头像"
      class="img"
    />
  </div>
</body>

</html>

最佳实现一

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .tag {
      position: absolute;
      color: white;
      background: #cd0000;
      font-size: 12px;
    }

    .img {
      width: 120px;
      height: 160px;
    }

    .tag[type="square"] {
      padding: 0.1em .5em;
    }

    .tag[type="triangle"] {
      width: 2.5em;
      height: 2.5em;
      background: linear-gradient(to right bottom, #cd0000 50%, transparent 50%);
      text-indent: .5em;
    }

    .tag[type="trapezoidal"] {
      padding: .1em 3em .1em .5em;
      background: linear-gradient(135deg, #cd0000 calc(100% - 2em), transparent 2em);
    }

    .tag[type="circle"] {
      border-bottom-right-radius: 100%;
      padding: .1em 1.2em .6em .5em;
    }
  </style>
</head>

<body>
  <ol>
    <li>
      <h4>方形,宽度跟随内容</h4>
      <span class="tag" type="square">No.1</span>
      <img src="../../images/2019-09-26-19-49-51.png" alt="" class="img">
    </li>
    <li>
      <h4>三角,多用在top3场景,因此只需考虑一个字符</h4>
      <span class="tag" type="triangle">1</span>
      <img src="../../images/2019-09-26-19-49-51.png" alt="" class="img">
    </li>
    <li>
      <h4>方形带三角</h4>
      <span class="tag" type="trapezoidal">火热连载</span>
      <img src="../../images/2019-09-26-19-49-51.png" alt="" class="img">
    </li>
    <li>
      <h4>1/4圆 1/4椭圆</h4>
      <span class="tag" type="circle">1</span>
      <img src="../../images/2019-09-26-19-49-51.png" alt="" class="img">
    </li>
  </ol>
</body>

</html>

最佳实现二

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    img {
      width: 120px;
      height: 160px;
    }

    .tag {
      position: absolute;
      background: #cd0000;
      color: white;
      font-size: 12px;
    }

    .tag-normal {
      padding: 2px 4px;
    }

    .tag-triangle {
      width: 28px;
      height: 28px;
      text-indent: 4px;
      clip-path: polygon(0 0,100% 0,0 100%);
    }

    .tag-trapezoid {
      padding: 3px 12px 3px 4px;
      clip-path: polygon(0 0,100% 0, calc(100% - 10px) 100%,0 100%);
    }

    .tag-ellipse {
      line-height: 1em;
      min-width: 1em;
      padding: 4px 10px 8px 2px;
      clip-path: ellipse(100% 100% at 0 0);
    }
  </style>
</head>

<body>
  <span class="tag tag-normal">No.1</span>
  <img src="../../images/2019-09-26-19-49-51.png">
  <span class="tag tag-triangle">1</span>
  <img src="../../images/2019-09-26-19-49-51.png">
  <span class="tag tag-trapezoid">火热连载</span>
  <img src="../../images/2019-09-26-19-49-51.png">
  <span class="tag tag-ellipse">1</span>
  <img src="../../images/2019-09-26-19-49-51.png">
  <span class="tag tag-ellipse">100</span>
  <img src="../../images/2019-09-26-19-49-51.png">
</body>

</html>

实现要点

  1. border三角(IE8+),渐变(IE10+),clip-path 裁剪(非 IE),border-radius 圆角(IE9+)。
  2. 左上角定位时候,不需要父元素 relative,也不需要 top, left 指定。
  3. clip-path: polygon 配合百分比定位以及 calc 非常强,很多图形(图标,字母,文字)都可以使用这样的方式实现,尺寸任意适配。唯一需要注意的就是兼容性。1/4 圆裁剪:clip-path: ellipse(100% 100% at 0% 0%);
  4. 其他实现:border 三角,问题,虽然兼容性好,但是不支持百分比宽度,这就导致无法自动适配尺寸(要么无法适应内容,要么无法使用其他图形-例如文字的色块背景)。
  5. skewX 模拟三角是很棒的实现,因为可以高度自适应。
  6. 渐变是万能图形绘制方法,理论上,任意的图形都可以使用渐变见绘制,因为 background-size 和多背景。例如彩色照片,每一个像素点(例如红色)可以background-size:1px 1px; background-image: liner-gradient(red, red),本题实现的优点:

    1. CSS简介,不需要伪元素;
    2. 兼容性足够,IE10+;
    3. 方便灵活,包括圆弧也是可以使用渐变的,径向渐变。
  7. border-radius 实现1/4圆:border-bottom-right-radius: 100%;

CSS测试十三

2019 11 18 17 55 16

具体实现

我的实现

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .button {
      border: 1px solid rgb(204, 208, 211);
      border-radius: 3px;
      display: inline-block;
      font-size: 16px;
    }

    .left {
      background: rgb(241, 244, 247);
      border-right: 1px solid rgb(204, 208, 211);
      display: inline-block;
      padding: 10px 14px;
      font-weight: bold;
    }

    .text {
      padding: 10px 14px;
      font-weight: bold;
      display: inline-block;
      vertical-align: middle;
    }

    .icon {
      display: inline-block;
      width: 24px;
      height: 24px;
      vertical-align: middle;
    }

    .label {
      vertical-align: middle;
    }

    .eye {
      background: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' width='16' height='16' xmlns='http://www.w3.org/2000/svg' fill='%2324292e' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z'/%3E%3C/svg%3E") no-repeat center/100%;
    }

    .star {
      background: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' width='16' height='16' xmlns='http://www.w3.org/2000/svg' fill='%2324292e' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z'/%3E%3C/svg%3E") no-repeat center/100%;
    }

   .fork {
      background: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' width='16' height='16' xmlns='http://www.w3.org/2000/svg' fill='%2324292e' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M8 1a1.993 1.993 0 00-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 002 1a1.993 1.993 0 00-1 3.72V6.5l3 3v1.78A1.993 1.993 0 005 15a1.993 1.993 0 001-3.72V9.5l3-3V4.72A1.993 1.993 0 008 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z'%3E%3C/path%3E%3C/svg%3E") no-repeat center/100%;
    }

    .triangle {
      display: inline-block;
      border: 6px solid transparent;
      border-top-color: #000;
      vertical-align: -5px;
    }
  </style>
</head>

<body>
  <span class="button">
    <span class="left">
      <span class="icon eye"></span>
      <span class="label">Unwatch</span>
      <span class="triangle"></span>
    </span>
    <span class="text">
      63
    </span>
  </span>
  <span class="button">
    <span class="left">
      <span class="icon star"></span>
      <span class="label">Star</span>
    </span>
    <span class="text">
      445
    </span>
  </span>
  <span class="button">
    <span class="left">
      <span class="icon fork"></span>
      <span class="label">Fork</span>
    </span>
    <span class="text">
      25
    </span>
  </span>
</body>

</html>

最佳实现一

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    /* zxx: 视觉还原OK,布局也很稳健,就算低头皇冠也不会掉 */
    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
    }

    /** 主容器 **/
    .btn-group-container {
      display: flex;
    }

    /** 按钮组 **/
    .btn-group {
      display: flex;
      align-items: center;
    }

    .btn-group + .btn-group {
      margin-left: 10px;
    }

    .btn-group .btn {
      border-radius: 0;
    }

    .btn-group > .btn:not(:first-child),
    .btn-group > .details-menu:not(:first-child) {
      margin-left: -1px;
    }

    .btn-group > .btn:first-child,
    .btn-group > .details-menu:first-child > .btn {
      border-top-left-radius: .25em;
      border-bottom-left-radius: .25em;
    }

    .btn-group > .btn:last-child,
    .btn-group > .details-menu:last-child > .btn {
      border-top-right-radius: .25em;
      border-bottom-right-radius: .25em;
    }

    /** 按钮 **/
    .btn {
      position: relative;
      display: inline-flex;
      align-items: center;
      padding: 3px 9px;
      font-size: 12px;
      font-weight: 600;
      line-height: 20px;
      white-space: nowrap;
      vertical-align: middle;
      cursor: pointer;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
      font-family: inherit;
      background-repeat: repeat-x;
      background-position: -1px -1px;
      background-size: 110% 110%;
      border: 1px solid #ccced0;
      border-radius: .25em;
      text-decoration: none;
      -webkit-appearance: none;
      -moz-appearance: none;
      appearance: none;
    }

    .btn:hover {
      z-index: 1;
    }

    .btn > .svg-icon {
      width: 20px;
      height: 20px;
      margin-right: 2px;
      fill: currentColor;
      speak: none;
    }

    /** 按钮主题定义 **/
    .btn-default {
      color: #24292e;
      background-color: #eff3f6;
      background-image: linear-gradient(-180deg, #fafbfc, #eff3f6 90%);
    }

    .btn-default:hover {
      background-color: #e6ebf1;
      background-image: linear-gradient(-180deg, #f0f3f6, #e6ebf1 90%);
      background-position: -.5em;
      border-color: #a5a8ac;
    }

    .btn-link {
      color: #24292e;
      background-color: #fff;
    }

    .btn-link:hover {
      color: #0366d6;
    }

    /** 按钮下拉菜单 **/
    .details-menu {
      position: relative;
      display: block;
    }

    .details-menu-btn::-webkit-details-marker {
      display: none;
    }

    .details-menu-btn::after {
      content: "";
      display: inline-block;
      width: 0;
      height: 0;
      margin-left: 3px;
      transform: translateY(25%);
      border: 4px solid transparent;
      border-top-color: currentColor;
    }

    .details-menu-modal {
      position: absolute;
    }
  </style>
</head>

<body>
  <div class="btn-group-container">
    <div class="btn-group">
      <details class="details-menu">
        <summary class="details-menu-btn btn btn-default" role="button" aria-label="watch">
          <svg class="svg-icon">
            <use xlink:href="#icon-watch"></use>
          </svg>
          Unwatch
        </summary>
        <div class="details-menu-modal">
          菜单(略)
        </div>
      </details>
      <a class="btn btn-link" href="#" aria-label="63 users are watching this repository">
        63
      </a>
    </div>
    <div class="btn-group">
      <button class="btn btn-default" aria-label="star">
        <svg class="svg-icon">
          <use xlink:href="#icon-star"></use>
        </svg>
        Star
      </button>
      <a class="btn btn-link" href="#" aria-label="445 users starred this repository">
        445
      </a>
    </div>
    <div class="btn-group">
      <button class="btn btn-default" aria-label="fork">
        <svg class="svg-icon">
          <use xlink:href="#icon-fork"></use>
        </svg>
        Fork
      </button>
      <a class="btn btn-link" href="#" aria-label="25 users forked this repository">
        25
      </a>
    </div>
  </div>

  <!-- svg sprite -->
  <svg style="display:none">
    <symbol id="icon-star" viewBox="0 0 1024 1024">
      <path
        d="M897.02475785 421.36072708q0 10.18094348-12.0320238 22.21296648l-167.98556122 163.82063007 39.7982321 231.38507126q0.46277048 3.23939099 0.46277049 9.25540249 0 9.71817297-4.8590865 16.42833981t-14.11448899 6.71016683q-8.79263282 0-18.51080579-5.55324181l-207.78379414-109.21375365-207.78379414 109.21375365q-10.18094348 5.55324181-18.51080579 5.55324181-9.71817297 0-14.57725948-6.71016683t-4.8590865-16.42833981q0-2.77662051 0.92554019-9.25540249l39.79823209-231.38507126-168.44833171-163.82063007q-11.56925333-12.49479349-11.56925333-22.21296648 0-17.12249514 25.91512796-21.2874263l232.31061143-33.7822206 104.12328232-210.56041464q8.79263282-18.97357548 22.67573696-18.97357548t22.67573696 18.97357548l104.12328232 210.56041464 232.31061143 33.7822206q25.91512795 4.16493117 25.91512797 21.2874263z">
      </path>
    </symbol>
    <symbol id="icon-fork" viewBox="0 0 1024 1024">
      <path
        d="M689.1875 94.2366333a117.7115625 117.7115625 0 0 0-59.06250001 219.7125V389.54913331L512 507.6741333 393.87500001 389.54913331V313.9491333A117.7115625 117.7115625 0 0 0 334.8125 94.2366333a117.7115625 117.7115625 0 0 0-59.0625 219.7125V419.0803833l177.1875 177.18750001v105.13124999A117.7115625 117.7115625 0 0 0 512 921.11163331a117.7115625 117.7115625 0 0 0 59.0625-219.71250001V596.26788331l177.1875-177.18750001V313.9491333A117.7115625 117.7115625 0 0 0 689.1875 94.2366333zM334.8125 283.23663331C295.83124999 283.23663331 263.9375 250.75225831 263.9375 212.3616333c0-38.39062499 32.484375-70.875 70.875-70.87499999 38.39062499 0 70.875 32.484375 70.875 70.87499999 0 38.39062499-32.484375 70.875-70.875 70.87500001z m177.1875 590.62499999c-38.98125001 0-70.875-32.484375-70.875-70.875 0-38.39062499 32.484375-70.875 70.875-70.875 38.39062499 0 70.875 32.484375 70.875 70.875 0 38.39062499-32.484375 70.875-70.875 70.875z m177.1875-590.62499999c-38.98125001 0-70.875-32.484375-70.875-70.87500001 0-38.39062499 32.484375-70.875 70.875-70.87499999 38.39062499 0 70.875 32.484375 70.875 70.87499999 0 38.39062499-32.484375 70.875-70.875 70.87500001z">
      </path>
    </symbol>
    <symbol id="icon-watch" viewBox="0 0 1024 1024">
      <path
        d="M512 209.408c-201.728 0-374.016 125.44-443.8016 302.592C137.984 689.152 310.272 814.592 512 814.592c201.9328 0 374.016-125.44 443.8016-302.592C886.016 334.848 713.9328 209.408 512 209.408z m0 504.32A201.8304 201.8304 0 0 1 310.272 512 201.7792 201.7792 0 0 1 512 310.272 201.7792 201.7792 0 0 1 713.728 512 201.8304 201.8304 0 0 1 512 713.728z m0-322.7648A121.1392 121.1392 0 0 0 390.9632 512 121.1392 121.1392 0 0 0 512 633.0368 121.1392 121.1392 0 0 0 633.0368 512 121.1392 121.1392 0 0 0 512 390.9632z">
      </path>
    </symbol>
  </svg>
</body>

</html>

最佳实现二

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .icon-container {
      padding: 0;
      font-size: 0;
    }

    .icon-group {
      display: inline-block;
      margin-left: 10px;
      list-style-type: none;
    }

    .icon-group a {
      display: inline-block;
      line-height: 26px;
      font-size: 12px;
      font-weight: bold;
      text-decoration: none;
      color: #24292e;
    }

    .icon-description {
      padding: 0 10px 0 30px;
      border: 1px solid rgba(27, 31, 35, .2);
      border-radius: 3px 0 0 3px;
      background-image: linear-gradient(to bottom,#fafbfc,#eff3f6);
    }

    .icon-description:hover {
      border-color: rgba(27, 31, 35, .35);
      background-image: linear-gradient(to bottom,#f0f3f6,#e6ebf1 90%);
    }

    .icon-number {
      padding: 0 10px;
      border: 1px solid rgba(27, 31, 35, .2);
      border-left: 0;
      border-radius: 0 3px 3px 0px;
    }

    .icon-number:hover {
      color: #0366d6;
    }

    .icon-description::before {
      content: '';
      position: absolute;
      width: 16px;
      height: 16px;
      margin: 5px 0 0 -20px;
    }

    .icon-description[icon-watch]::before {
      background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' width='16' height='16' xmlns='http://www.w3.org/2000/svg' fill='%2324292e' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z'/%3E%3C/svg%3E");
    }

    .icon-description[icon-star]::before {
      background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' width='16' height='16' xmlns='http://www.w3.org/2000/svg' fill='%2324292e' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74L14 6z'/%3E%3C/svg%3E");
    }

    .icon-description[icon-fork]::before {
      background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' width='16' height='16' xmlns='http://www.w3.org/2000/svg' fill='%2324292e' aria-hidden='true'%3E%3Cpath fill-rule='evenodd' d='M8 1a1.993 1.993 0 00-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 002 1a1.993 1.993 0 00-1 3.72V6.5l3 3v1.78A1.993 1.993 0 005 15a1.993 1.993 0 001-3.72V9.5l3-3V4.72A1.993 1.993 0 008 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z'%3E%3C/path%3E%3C/svg%3E")
    }
  </style>
</head>

<body>
  <ul class="icon-container">
    <li class="icon-group">
      <a class="icon-description" href="javascript:void;" role="button" icon-watch>
        Unwatch
      </a>
      <a class="icon-number" href="javascript:void;" role="button" aria-label="63 users are watching this repository">63</a>
    </li>
    <li class="icon-group">
      <a class="icon-description" href="javascript:void;" role="button" icon-star>
        Star
      </a>
      <a class="icon-number" href="javascript:void;" role="button" aria-label="445 users starred this repository">445</a>
    </li>
    <li class="icon-group">
      <a class="icon-description" href="javascript:void;" role="button" icon-fork>
        Fork
      </a>
      <a class="icon-number" href="javascript:void;" role="button" aria-label="25 users forked this repository">25</a>
    </li>
  </ul>
</body>

</html>

实现要点

  1. 按钮我们没有任何理由使用 <a> 标签,除非你要兼容 IE7,所以标签使用应该是 button + a。
  2. 可以考虑多按钮,多链接时候的样式表现,会更健壮,扩展性更强。
  3. 每个按钮组是不能换行的,按钮组可以使用 flex 布局,如果考虑兼容,可以里面内联 + white-space: nowrap;
  4. 按钮组的实现方法,大家实现有 3 种(inline-block,float,inline-flex),如果考虑要点 3,float 布局是不推荐的,因为当下是无法阻止 float 内容不换行的。table 布局其实是上上之选,天然一行显示,兼容到IE8。
  5. 每个按钮控制不要使用标签选择器,而是树结构伪类,例如 :first-child,:last-child,例如圆角::first-child{border-radius: 3px 0 0 3px;}:last-child{border-radius: 0 3px 3px 0;}。此时就非常强,不要使用标签以及类名进行判断。
  6. 同样的,中间的线要走合并,每一个元素都要有完整的边框(如margin负值合并),而不是根据标签类型进行缺省。

CSS测试十四

2019 11 18 21 06 48

具体实现

我的实现

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .nav {
      font-size: 16px;
      line-height: 1;
    }

    .menu {
      list-style: none;
      counter-reset: count;
    }

    .item {
      display: inline-block;
      padding: 1em;
      position: relative;
      color: rgb(64, 183, 239);
      border-color: rgb(237, 249, 255);
      background: rgb(237, 249, 255);
      cursor: pointer;
    }

    .item + .item {
      margin-left: 1.5em;
    }

    .item:first-child {
      padding-left: 2em;
    }

    .item a::before {
      content: counter(count) "-";
      counter-increment: count;
    }

    a {
      text-decoration: none;
    }

    a:visited {
      color: currentColor;
    }

    .active {
      background: rgb(0, 159, 233);
      color: #fff;
      border-color: rgb(0, 159, 233);
    }

    .active ~ .item {
      background: rgb(235, 237, 240);
      color: rgb(183, 184, 185);
      border-color: rgb(235, 237, 240);
    }

    .item:not(:first-child)::before {
      content: '';
      position: absolute;
      right: 100%;
      bottom: 0;
      border: 1.5em solid;
      border-color: inherit;
      border-right: none;
      border-left: 1em solid transparent;
    }

    .item:after {
      content: '';
      position: absolute;
      left: 100%;
      bottom: 0;
      border: 1.5em solid transparent;
      border-left: 1em solid;
      border-left-color: inherit;
    }
  </style>
</head>

<body>
  <nav class="nav">
    <ol class="menu">
      <li class="item">
        <a href="">
          规则说明
        </a>
      </li>
      <li class="item">
        <a href="">
          参与活动
        </a>
      </li>
      <li class="item active">
        <a href="">
          参与抽奖
        </a>
      </li>
      <li class="item">
        <a href="">
          奖品发放
        </a>
      </li>
      <li class="item">
        <a href="">
          查看结果
        </a>
      </li>
    </ol>
  </nav>
</body>

</html>

最佳实现一

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    /* zxx: 计数器的使用加分 */
    .navigation {
      display: flex;
      list-style: none;
      counter-reset: listCounter;
      font-size: 16px;
      line-height: 1;
    }

    a {
      text-decoration: none;
    }

    a:visited {
      color: currentColor;
    }

    .navigation-item a::before {
      content: counter(listCounter) "-";
    }

    .navigation-item {
      position: relative;
      counter-increment: listCounter;
      color: #499fe9;
      border-color: #edf9fe;
      background: #edf9fe;
      padding: 1em;
      white-space: nowrap;
      cursor: pointer;
    }

    .navigation-item:first-child {
      padding-left: 2.3em;
    }

    .navigation-item:not(:first-child)::before {
      border: 1.5em solid;
      border-color: inherit;
      border-left: 1.3em solid transparent;
      border-right: none;
      position: absolute;
      /* 父容器的左边界之外 */
      right: 100%;
      top: 0;
      content: '';
    }

    .navigation-item::after {
      border: 1.5em solid transparent;
      border-left: 1.3em solid;
      border-left-color: inherit;
      position: absolute;
      /* 父容器的右边界之外 */
      left: 100%;
      top: 0;
      content: '';
    }

    .navigation-item + .navigation-item {
      margin-left: 1.5em;
    }

    [aria-current] {
      background: #499fe9;
      border-color: #499fe9;
      color: #edf9fe;
    }

    [aria-current] ~ .navigation-item {
      background: #eee;
      border-color: #eee;
      color: #999;
    }
  </style>
</head>

<body>
  <nav role="navigation">
    <ol class="navigation">
      <li class="navigation-item"><a href="">规则说明</a></li>
      <li class="navigation-item"><a href="">参与活动</a></li>
      <li class="navigation-item" aria-current="true"><a href="">参与抽奖</a></li>
      <li class="navigation-item"><a href="">奖品发放</a></li>
      <li class="navigation-item"><a href="">查看结果</a></li>
    </ol>
  </nav>
</body>

</html>

实现要点

  1. 就本题实际开发而言,反序是没有必要的。因为会常驻选中类名,DOM 顺序是 1-5 也是可以实现样式控制的。所有列表淡蓝, .active 高亮深天空蓝,~ 后面的灰色。给前面的状态添加一个独立的类名是会增加实际开发的复杂度,是不推荐的,应该活用选择器的一些技术降低我们的维护成本。
  2. 应该是 1/2 尺寸图,考虑下不要掉下来。
  3. 三角的实现,三类方法:

    1. clip-path:最容易理解,比较符合现实认知,推荐百分比控制(无论尺寸大小形状都OK),最大的问题:兼容性,IE全军覆没,移动端可以使用。
    2. border: 切图前端必备技能。https://www.zhangxinxu.com/wordpress/?p=794 问题:定位比较啰嗦(占据尺寸,需要具体定位),border 不支持百分比(据说新的规范在考虑支持),尺寸变化有额外成本。优点:兼容性非常好,IE7+ 支持。border-color: transparent; IE7+支持,IE6需要使用 dashed 实现。background: transparent; IE6+ 支持。 color: transparent; IE9+ 支持,原生 IE8 不支持。
    3. transform: skewX()。最佳实现,兼顾尺寸控制,定位与兼容性,理解也非常好理解。兼容性 IE9+ 都支持,-ms-。现在 2019 年了,对于 transform 属性,-webkit-, -moz- 私有前缀没有必要再写了。
  4. 前面的数值显示。使用计数器,前面的 1-, 2-, 3-, … 没有必要写在 HTML 中,以后调整(增减),HTML还需要同时维护。counter 计数器优化我们的实现。https://www.zhangxinxu.com/wordpress/?p=4303 IE8+支持。
  5. 语义,更接近 ol > li。还有一点nav的语义。

CSS测试十五

2019 12 19 21 50 45

具体实现

最佳实现一

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
      height: 100%;
    }

    .list {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
      color: #524940;
      border: 15px solid;
      background-color: currentColor;
      grid-gap: 1px;
      overflow: hidden;
    }

    .list-item {
      position: relative;
      text-align: center;
      color: #e9e3e1;
      padding: 30px 15px;
      text-decoration: none;
      /* 外边距向外覆盖1px,注意和.list下的overflow: hidden;的配合,屏蔽掉最外层的边框 */
      margin: -1px;
      /* overflow: hidden; 与 border-radius: 15px; 的配合形成内圆间距 */
      overflow: hidden;
      border-radius: 15px;
      transition: .2s;
      outline: 0;
    }

    .list-item:hover,
    .list-item:focus {
      z-index: 1;
      color: #ffdd40;
    }

    .list-item::before {
      /* 生成 1px 外边框 */
      content: '';
      position: absolute;
      left: 1px;
      top: 1px;
      right: 1px;
      bottom: 1px;
      pointer-events: none;
      box-shadow: 0 0 0 1px currentColor;
    }

    .list-item-icon {
      font-size: 30px;
    }

    .list-item-title {
      font-size: 16px;
      display: block;
      margin-top: 15px;
    }

    css-icon {
      display: inline-block;
      height: 1em;
      width: 1em;
      font-size: 20px;
      box-sizing: border-box;
      text-indent: -9999px;
      vertical-align: middle;
      position: relative;
    }

    css-icon::before,
    css-icon::after {
      content: '';
      box-sizing: inherit;
      position: absolute;
      left: 50%;
      top: 50%;
      -ms-transform: translate(-50%, -50%);
      transform: translate(-50%, -50%);
    }

    .icon-mail::before {
      width: .9em;
      height: .75em;
      border: 2px solid;
      border-radius: 2px;
    }

    .icon-mail::after {
      width: .4em;
      height: .4em;
      border-style: solid;
      border-width: 0 0 2px 2px;
      -ms-transform: translate(-50%, -.35em) rotate(-45deg) skew(10deg, 10deg);
      transform: translate(-50%, -.35em) rotate(-45deg) skew(10deg, 10deg);
    }
  </style>
</head>
<body>
  <nav class="list">
    <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
    <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
    <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
    <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
    <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
    <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
      <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
      <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
        <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
      <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
        <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
      <a class="list-item" href="#">
      <css-icon class="list-item-icon icon-mail"></css-icon>
      <span class="list-item-title">商品秒杀</span>
    </a>
  </nav>
</body>
</html>

最佳实现二

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
    }

    nav {
      overflow: hidden;
    }

    a {
      text-decoration: none;
      color: currentColor;
    }

    .server_list {
      display: flex;
      flex-wrap: wrap;
      justify-content: space-between;
      /* 遮住顶部、左边的线 */
      margin: -2px 0 0 -2px;
      padding: 0;
      list-style: none;
      font-size: 24px;
      background-color: #524840;
    }

    .server_item {
      position: relative;
      flex: 1 1 33%;
      min-width: 140px;
      text-align: center;
      padding: 40px 0;
      color: #ece5e4;
    }

    .server_item::before,
    .server_item::after {
      content: '';
      position: absolute;
      background-color: #8f8a85;
    }

    .server_item::before {
      top: 0;
      right: 12px;
      left: 12px;
      height: 2px;
    }

    .server_item::after {
      top: 12px;
      bottom: 12px;
      left: 0;
      width: 2px;
    }

    .server_icon {
      display: block;
      width: 50px;
      height: 50px;
      background-size: 50px 50px;
      margin: 0 auto 15px;
    }

    .server_icon_clock {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E %3Cpath fill='%23ece5e4' d='M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm0 448c-110.5 0-200-89.5-200-200S145.5 56 256 56s200 89.5 200 200-89.5 200-200 200zm61.8-104.4l-84.9-61.7c-3.1-2.3-4.9-5.9-4.9-9.7V116c0-6.6 5.4-12 12-12h32c6.6 0 12 5.4 12 12v141.7l66.8 48.6c5.4 3.9 6.5 11.4 2.6 16.8L334.6 349c-3.9 5.3-11.4 6.5-16.8 2.6z'%3E%3C/path%3E %3C/svg%3E");
    }

    .server_icon_enterprise {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 512'%3E %3Cpath fill='%23ece5e4' d='M504 352H136.4c-4.4 0-8 3.6-8 8l-.1 48c0 4.4 3.6 8 8 8H504c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm0 96H136.1c-4.4 0-8 3.6-8 8l-.1 48c0 4.4 3.6 8 8 8h368c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm0-192H136.6c-4.4 0-8 3.6-8 8l-.1 48c0 4.4 3.6 8 8 8H504c4.4 0 8-3.6 8-8v-48c0-4.4-3.6-8-8-8zm106.5-139L338.4 3.7a48.15 48.15 0 0 0-36.9 0L29.5 117C11.7 124.5 0 141.9 0 161.3V504c0 4.4 3.6 8 8 8h80c4.4 0 8-3.6 8-8V256c0-17.6 14.6-32 32.6-32h382.8c18 0 32.6 14.4 32.6 32v248c0 4.4 3.6 8 8 8h80c4.4 0 8-3.6 8-8V161.3c0-19.4-11.7-36.8-29.5-44.3z'%3E%3C/path%3E %3C/svg%3E");
    }

    .server_icon_aisle {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 496 512'%3E %3Cpath fill='%23ece5e4' d='M248 8.8c-137 0-248 111-248 248s111 248 248 248 248-111 248-248-111-248-248-248zm0 482.8c-129.7 0-234.8-105.1-234.8-234.8S118.3 22 248 22s234.8 105.1 234.8 234.8S377.7 491.6 248 491.6zm155.1-328.5v-46.8H209.3V198H54.2l36.7 46h117.7v196.8h48.8V245h83.3v-47h-83.3v-34.8h145.7zm-73.3 45.1v23.9h-82.9v197.4h-26.8V232.1H96.3l-20.1-23.9h143.9v-80.6h171.8V152h-145v56.2zm-161.3-69l-12.4-20.7 2.1 23.8-23.5 5.4 23.3 5.4-2.1 24 12.3-20.5 22.2 9.5-15.7-18.1 15.8-18.1zm-29.6-19.7l9.3-11.5-12.7 5.9-8-12.4 1.7 13.9-14.3 3.8 13.7 2.7-.8 14.7 6.8-12.2 13.8 5.3zm165.4 145.2l-13.1 5.6-7.3-12.2 1.3 14.2-13.9 3.2 13.9 3.2-1.2 14.2 7.3-12.2 13.1 5.5-9.4-10.7zm106.9-77.2l-20.9 9.1-12-19.6 2.2 22.7-22.3 5.4 22.2 4.9-1.8 22.9 11.5-19.6 21.2 8.8-15.1-17zM248 29.9c-125.3 0-226.9 101.6-226.9 226.9S122.7 483.7 248 483.7s226.9-101.6 226.9-226.9S373.3 29.9 248 29.9zM342.6 196v51h-83.3v195.7h-52.7V245.9H89.9l-40-49.9h157.4v-81.6h197.8v50.7H259.4V196zM248 43.2c60.3 0 114.8 25 153.6 65.2H202.5V190H45.1C73.1 104.8 153.4 43.2 248 43.2zm0 427.1c-117.9 0-213.6-95.6-213.6-213.5 0-21.2 3.1-41.8 8.9-61.1L87.1 252h114.7v196.8h64.6V253h83.3v-62.7h-83.2v-19.2h145.6v-50.8c30.8 37 49.3 84.6 49.3 136.5.1 117.9-95.5 213.5-213.4 213.5zM178.8 275l-11-21.4 1.7 24.5-23.7 3.9 23.8 5.9-3.7 23.8 13-20.9 21.5 10.8-15.8-18.8 16.9-17.1z'%3E%3C/path%3E %3C/svg%3E");
    }

    .server_icon_fans {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512'%3E %3Cpath fill='%23ece5e4' d='M320 0H128L0 128v320c0 35.3 28.7 64 64 64h256c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64zM160 160h-48V64h48v96zm80 0h-48V64h48v96zm80 0h-48V64h48v96z'%3E%3C/path%3E %3C/svg%3E");
    }

    .server_icon_change {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 640 512'%3E %3Cpath fill='%23ece5e4' d='M629.657 343.598L528.971 444.284c-9.373 9.372-24.568 9.372-33.941 0L394.343 343.598c-9.373-9.373-9.373-24.569 0-33.941l10.823-10.823c9.562-9.562 25.133-9.34 34.419.492L480 342.118V160H292.451a24.005 24.005 0 0 1-16.971-7.029l-16-16C244.361 121.851 255.069 96 276.451 96H520c13.255 0 24 10.745 24 24v222.118l40.416-42.792c9.285-9.831 24.856-10.054 34.419-.492l10.823 10.823c9.372 9.372 9.372 24.569-.001 33.941zm-265.138 15.431A23.999 23.999 0 0 0 347.548 352H160V169.881l40.416 42.792c9.286 9.831 24.856 10.054 34.419.491l10.822-10.822c9.373-9.373 9.373-24.569 0-33.941L144.971 67.716c-9.373-9.373-24.569-9.373-33.941 0L10.343 168.402c-9.373 9.373-9.373 24.569 0 33.941l10.822 10.822c9.562 9.562 25.133 9.34 34.419-.491L96 169.881V392c0 13.255 10.745 24 24 24h243.549c21.382 0 32.09-25.851 16.971-40.971l-16.001-16z'%3E%3C/path%3E %3C/svg%3E");
    }

    .server_icon_charge {
      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512'%3E %3Cpath fill='%23ece5e4' d='M351.2 32h-65.3c-4.6 0-8.8 2.6-10.8 6.7l-55.4 113.2c-14.5 34.7-27.1 71.9-27.1 71.9h-1.3s-12.6-37.2-27.1-71.9L108.8 38.7c-2-4.1-6.2-6.7-10.8-6.7H32.8c-9.1 0-14.8 9.7-10.6 17.6L102.3 200H44c-6.6 0-12 5.4-12 12v32c0 6.6 5.4 12 12 12h88.2l19.8 37.2V320H44c-6.6 0-12 5.4-12 12v32c0 6.6 5.4 12 12 12h108v92c0 6.6 5.4 12 12 12h56c6.6 0 12-5.4 12-12v-92h108c6.6 0 12-5.4 12-12v-32c0-6.6-5.4-12-12-12H232v-26.8l19.8-37.2H340c6.6 0 12-5.4 12-12v-32c0-6.6-5.4-12-12-12h-58.3l80.1-150.4c4.3-7.9-1.5-17.6-10.6-17.6z'%3E%3C/path%3E %3C/svg%3E");
    }

    @media (min-width: 560px) {
      .server_item {
        flex-basis: 25%;
      }
    }
  </style>
</head>
<body>
  <nav>
    <ul class="server_list">
      <li class="server_item">
        <a href="#" aria-label="商品秒杀">
          <i class="server_icon server_icon_clock"></i>商品秒杀
        </a>
      </li>
      <li class="server_item">
        <a href="#" aria-label="企业团购">
          <i class="server_icon server_icon_enterprise"></i>企业团购
        </a>
      </li>
      <li class="server_item">
        <a href="#" aria-label="私码通道">
          <i class="server_icon server_icon_aisle"></i>私码通道
        </a>
      </li>
      <li class="server_item">
        <a href="#" aria-label="铁粉卡">
          <i class="server_icon server_icon_fans"></i>铁粉卡
        </a>
      </li>
      <li class="server_item">
        <a href="#" aria-label="以旧换新">
          <i class="server_icon server_icon_change"></i>以旧换新
        </a>
      </li>
      <li class="server_item">
        <a href="#" aria-label="话费充值">
          <i class="server_icon server_icon_charge"></i>话费充值
        </a>
      </li>

    </ul>
  </nav>
</body>
</html>

最佳实现三

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    html,
    body {
      background-color: white;
      margin: 0;
    }

    .nav {
      padding: 0.5em;
      background-color: #52484