移动端重构实战系列3——各种等分

2022-06-29 17:03:35 浏览数 (2)

”本系列教程为实战教程,是本人移动端重构经验及思想的一次总结,也是对sandal及sheral UI的一次全方位剖析,首发在imweb和w3cplus两大站点及“前端Talk”微信公众号,其余所有标注或没有标注来源的均为转载。“

——imweb 结一

单行,不考虑间距等分

以sheral的nav list为例:

代码语言:javascript复制
.nav-list{
    @include equal-flex(nav-item);
}

equal-flex的mixin定义在sandal中,代码如下:

代码语言:javascript复制
// flex等分
@mixin equal-flex($children: li) {
    display: flex;
    $childrenEle: li div p a span strong;
    @if index($childrenEle, $children) { // 常用元素
        #{$children} {
            flex: 1;
            width: 1%;
        }
    }
    @else {
        .#{$children} { // 自动加.成class
            flex: 1;
            width: 1%;
        }
    }
}

参数部分可以是常用的li div p a span strong几个元素,也可以是class,会自动加.

除了使用flex等分之外,我们还可以使用table办法来等分,同样sandal里面也定义了一个equal-table的mixin,代码如下:

代码语言:javascript复制
// table 等分
@mixin equal-table($children: li) {
    display: table;
    table-layout: fixed;
    width: 100%;
    $childrenEle: li div p a span strong;
    @if index($childrenEle, $children) {
        #{$children} {
            display: table-cell;
        }
    }
    @else {
        .#{$children} {
            display: table-cell;
        }
    }
}

间距相等,剩余item平分

分为单行及多行情况,单行直接flex就好,而多行的flex老版本兼容不是很好,所以不建议使用,直接用原始的float。

先说单行的,以sheral的line equal的第一个为例:

代码语言:javascript复制
.equal--gap{
    @include line-equal-gap($children: line-equal-item);
}

line-equal-gap的mixin同样定义在sandal中,代码如下:

代码语言:javascript复制
// line equal
@mixin line-equal-gap($gap: 10px, $lr: true, $children: li) {
    display: flex;
    @if $lr { // 左右边缘是否有gap
        padding-left: $gap;
        padding-right: $gap;
    }
    @if $children == li { // 默认使用li元素
        #{$children} {
            flex: 1;
            width: 1%;
            &:not(:first-of-type){
                margin-left: $gap;
            }
        }
    }
    @else { // 否则使用class
        .#{$children} {
            flex: 1;
            width: 1%;
            &:not(:first-of-type){
                margin-left: $gap;
            }
        }
    }
}

通过flex来实现,如果左右边缘也有间隙,则设置左右padding,然后设置子元素的非第一个元素的margin-left

关于多行的可以参考sheral的card实现,这里以卡片2为例,关键代码如下:

代码语言:javascript复制
$cardFlexSwitch:       false !default; // 默认使用float
$cardGap:              10px !default; // 默认间距为10px
$carLineNum:           2 !default; // 目前只支持2 或 3 等分

.card-list {
    @if $cardFlexSwitch {
        display: flex;
        flex-wrap: wrap;
    } @else {
        overflow: hidden;
    }

    .card-item {
        position: relative;
        width: 100% / $carLineNum;

        @if not $cardFlexSwitch {
            float: left;
        }

        .item-img {
            width: 100%;
        }
        .item-tt {
            line-height: 30px;
        }
    }
}
.card-list--gap{
  padding-left: $cardGap / 2;
  padding-right: $cardGap / 2;

 .card-item{
      margin-bottom: $cardGap;
      padding-left: $cardGap / 2;
      padding-right: $cardGap / 2;
  }
}

float的主要思路为设置宽度n等分,然后间距由padding或嵌套的inner元素margin来实现。

PS:这里考虑到flex与float的无缝切换,所以flex思路同样设置宽度的n等分,而不是单行的那种margin方法。

item相等,剩余间距平分

单行的demo为line equal的第二个。这里使用的另一个mixin: line-equal-item,其实现思路是通过flexjustify-content: space-between;进行变化使用。

代码语言:javascript复制
@mixin line-equal-item($lr: true, $children: li) {
    display: flex;
    justify-content: space-between;
    @if $lr {
        &::before,
        &::after {
            content: "";
        }
    }
}

多行的话,跟上面的card实现差不多,具体的间隙计算公式可以参考item宽度固定,剩余间距等分实现方案探讨

本篇文章主要是对sandal中几个等分mixin的具体实践,简直是分分钟实现等分的节奏,当然这背后的mixin的定义是几经磨难,花费了大量心血的,感兴趣的可以开始试试了(如果你要兼容的安卓机很古老,连最老版本的flex box都不支持,那就只好干巴巴的看着了,转头去写float吧)。

0 人点赞