使用类名,高效快捷的进行flex布局

背景

如今前端开发,使用flex进行布局已经非常普遍了。就我本身举例,除了特别的定位,不论整体还是细节的布局,基本上都使用flex来实现,不仅高效而且简洁
但是使用flex布局,重复的场景非常多,都是常用的几个属性和属性值:

  1. 定义flex布局:display: flex;
  2. 定义主轴:flex-direction: row | column;
  3. 定义主轴对齐方式:justify-content: flex-start | center;
  4. 需要的话,再定义交叉轴对齐方式:align-items: flex-start | center;

饱受折磨之后,于是想到可以开始使用类名封装样式集,类似于clearfix的使用方法,想要清除浮动的话,直接给标签加上一个类名即可:想要实现某种flex布局,加上一个特定类名即可

使用类名封装flex样式:

把flex的相关属性值映射到类名上,如下:

类名规则:flex-主轴方向-主轴对齐方式-交叉轴对齐方式(默认center)

.flex-x-start {
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
}

.flex-y-start {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
}

.flex-y-end {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
}


.flex-y-end-start {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
}
  1. 第一项flex,为类名固定前缀;
  2. 第二项表示主轴的方向,即justify-content
    • 并且把常用的row、column简化为x、y
  3. 第三项表示主轴的对齐方式,即justify-content
    • 并且把flex-start, flex-end, space-between, space-between简化为start、end、between、between
  4. 第四项表示交叉轴的对齐方式,即justify-content
    • 并且把flex-start, flex-end简化为start、end
    • 并且第四项可以省略,默认为center

当然上述类名规则以及简化规则,可以根据自己的喜好任意修改。

使用效果

当然最开始的时候,需要一个适应过程,但是养成习惯以后,大多数布局,一个类名就搞定了,很大的提高了效率:

  1. 避免了很多的没必要的标签类名定义
    • 很多时候仅仅为了定义样式,就得为标签加一个类名,现在不需要了;
    • 众所周知,起名字是一件非常苦恼、并且浪费时间的事情。
  2. 避免了html、css的环境切换的时间成本:写完类名,还要找到css文件或者style标签的位置去写样式,找对应位置也是很浪费时间。

使用scss编程生成代码

最开始使用的时候,只手动实现了几个类名来实现简单的布局,比如没有涉及交叉轴的设置、没有涉及column-reverserow-reverse等不常用的属性值。

但是在使用普及之后,其余的一些属性也开始涉及到,所以想到了覆盖常用属性的所有属性值:主轴方向、主轴对齐方式、交叉轴对齐方式。

但是所有属性值组合起来代码太多了(5 * 5 * 5),所以使用scss的编程生成代码:

// 主轴方向 属性值
$directionList: row , row-reverse , column , column-reverse;
// 主轴对齐方式 属性值
$justifyContentList: flex-start , flex-end , center , space-between , space-around;
// 交叉轴对齐方式 属性值
$alignItemsList: flex-start , flex-end , center , baseline , stretch;

// 三层遍历,组合所有属性值
@each $direction in $directionList {
  
  // 简化一些属性值
  $dir: $direction;
  @if $direction == 'row' {
    $dir: 'x';
  }
  @if $direction == 'column' {
    $dir: 'y';
  }
  @each $justifyContent in $justifyContentList {

    // 简化一些属性值
    $JC: $justifyContent;
    @if $justifyContent == 'flex-start' {
      $JC: 'start';
    }
    @if $justifyContent == 'flex-end' {
      $JC: 'end';
    }
    @if $justifyContent == 'space-between' {
      $JC: 'between';
    }
    @if $justifyContent == 'space-around' {
      $JC: 'around';
    }
    @each $alignItems in $alignItemsList {

      // 简化一些属性值
      $AI: $alignItems;
      @if $alignItems == 'flex-start' {
        $AI: 'start';
      }
      @if $alignItems == 'flex-end' {
        $AI: 'end';
      }
      
      // 根据变量,组合为css代码
      @if $AI == 'center' {
        .flex-#{$dir}-#{$JC} {
          display: flex;
          flex-direction: $direction;
          justify-content: $justifyContent;
          align-items: center;
        }
      }
      @else {
        .flex-#{$dir}-#{$JC}-#{$AI} {
          display: flex;
          flex-direction: $direction;
          justify-content: $justifyContent;
          align-items: $alignItems;
        }
      }
    }
  }
}

推荐阅读更多精彩内容