”本系列教程为实战教程,是本人移动端重构经验及思想的一次总结,也是对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;
进行变化使用。
@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吧)。