根据子元素数量显示不同样式-纯css解决方案

0. 知识储备

css3元素选择器

  • :only-child 匹配属于其父元素的唯一子元素的每个元素。
  • :last-child 选择属于其父元素最后一个匹配子元素。
  • :first-child 选择属于其父元素最后一个匹配子元素。
  • :nth-child(n) 选择属于其父元素的第n个子元素。
  • :nth-last-child(n) 同上,从最后一个子元素开始计数。
  • :nth-last-child(an+b) 匹配文档树中在其之后具有 an+b-1 个兄弟节点的元素,其中 n 为正值或零值。
  • ~ 是与所选元素同级,位于所选元素之后的所有兄弟元素。
  • 参考文档

1. 问题提出:

有一个展示最多4个元素的页面(图A),设计要求根据元素数量不同展示不同的样式(图B1、B2、B3)。

我的原则是能用css实现的就不用js实现,虽然各种框架可以很容易根据子元素数量去设定class,但是我想从css入手解决问题。

原始代码

<style>
    ul {
      border: 1px solid #ccc;
      box-sizing: border-box;
      padding: 0 10px 0 0;
      margin: 0 auto;
      width: 232px;
    }
    ul:after {
        content: '';
        display: table;
        clear:both;
    }
    ul>li {
        list-style: none;
        float: left;
        margin: 10px 0 10px 10px;
        padding: 0;
        height: 80px;
        width: 100px;
        background: #f00;
        font-size: 30px;
        font-weight: 700;
        color: #000;
        text-align: center;
        line-height: 80px;
    }
</style>
复制代码
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>
复制代码

图A↑
图B1↑
图B2↑
图B3↑

2. 纯css解决方案

得以纯css解决的原因是无需考虑不兼容css3的浏览器。

css3的元素选择器中,:only-child 匹配属于其父元素的唯一子元素的每个元素,图B1的问题就可以马上解决。**:only-child实质上等同于:first-cihld:last-child。**按照这个思路,图B2的第一个元素可以用li:first-child:nth-last-child(2)表示、第二个元素可以用li:nth-child(2):nth-last-child(1)表示。同理可以处理图B3。

代码如下

<style>
    ul {
      border: 1px solid #ccc;
      box-sizing: border-box;
      padding: 0 10px 0 0;
      margin: 0 auto;
      width: 232px;
    }
    ul:after {
        content: '';
        display: table;
        clear:both;
    }
    ul>li {
        list-style: none;
        float: left;
        padding: 0;
        height: 80px;
        background: #f00;
        font-size: 30px;
        font-weight: 700;
        color: #000;
        text-align: center;
        line-height: 80px;
    }
    
    /* 只有一个li元素 */
    ul>li:only-child {
        width: 180px;
        margin: 10px 25px;
    }

    /* 有两个li元素 */
    ul>li:first-child:nth-last-child(2),
    ul>li:first-child:nth-last-child(2) ~ li {
        width: 100px;
        margin: 10px 0 10px 10px;
    }

    /* 有三个li元素的第1个元素 */
    ul>li:first-child:nth-last-child(3) {
        width: 180px;
        margin: 10px 25px;
    }

    /* 有三个li元素的第2个及以后元素 */
    ul>li:nth-child(2):nth-last-child(2),
    ul>li:nth-child(2):nth-last-child(2) ~ li {
        width: 100px;
        margin: 10px 0 10px 10px;
    }

    /* 有四个及四个以上的li元素 */
    ul>li:first-child:nth-last-child(n+4),
    ul>li:first-child:nth-last-child(n+4) ~ li {
        width: 100px;
        margin: 10px 0 10px 10px;
    }
</style>
复制代码
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>
复制代码

3. 问题拓展

目前页面只有4个元素,如果再追加元素,大于等于4个时想继续按照图A往下排列(图B4),可以这样写:

li:first-child:nth-last-child(n+4),
li:first-child:nth-last-child(n+4) ~ li {
......
}
复制代码

图B4↑

运用到实际项目中也可以根据情况选择css预处理器实现以上思路的代码使代码更简洁,从而达到用纯css实现根据子元素数量显示不同样式。

转载于:https://juejin.im/post/5c4372186fb9a049c232bbdd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值