CSS 之 Flex布局

1、Flex布局 vs 网格布局 (1D vs 2D)

个人理解Flex是一维的布局(弹性框),栅格布局是二维布局(网格);两者相比,Flex布局通过定义了一些排版规则,来弥补一维布局存在的不足,可以用来实现网格二维布局同样的效果,实现起来较为灵活

1、CSS3之新特性grid栅格布局:【行row和列column】都自己控制,完全基于CSS控制(未来的主流趋势,最新的浏览器才兼容)

2、float模拟栅格布局:核心控制【列】的一维布局【使用整体:目前市面上最流行的模拟栅格布局,大部分框架都是基于此】

2、flex布局:核心是控制【行的内部布局】形成的一维布局【适合局部:目前市面上最流行的局部布局,大部分框架都开始支持】

参考:https://blog.csdn.net/weixin_43343144/article/details/89046779;flex实现网格效果_网格还是Flex?

2、Flex属性

1)flex-direction属性 & 排列方向

flex的flex-direction属性,通过row,column可以调整排列方向,如果不设置每个元素的width,height,则自适应调整。

这里举个简单例子

先对flex的css样式进行二次封装

// flex 横向排列
.flex_row {
 display: flex !important;
 flex-direction: row !important;
 // flex: 1;
}

//flex 纵向排列
.flex_column {
 display: flex !important;
 flex-direction: column !important;
}

// 均为分布
.flex_between {
 justify-content: space-between !important;
}

下面是简单的flex布局

<!-- 培训管理详情内容 -->
<div class="card_bg1 flex_row">   //下面第一级div均为按行排列
   <div class="flex_column">   //下面的第一级div均为按列排列
       <div class="card_bg1">
         xxxxxxxxxxxxxxxxxx
       </div>
       <div class="card_bg1">
         xxxxxxxxxxxxxxxxxx
       </div>
       <div class="card_bg1">
         xxxxxxxxxxxxxxxxxx
       </div>
   </div>

   <div class="card_bg1">
         xxxxxxxxxxxxxxxxxx
   </div>

   <div class="card_bg1">
         xxxxxxxxxxxxxxxxxx
   </div>
</div>

效果图如下

在这里插入图片描述

2)flex控制横纵轴 & 排列顺序(单/双项目)
a)理解justify-content & align-items

在这里插入图片描述

对于单项目(可以遍历循环按照某个顺序进行排列绘制多个单项目

单项目:
justify-content: flex-start/center/flex-end;  //控制x轴
align-items: flex-start/center/flex-end;  //控制y轴

对于双项目

双项目:
justify-content: space-between   //均匀分布(分别左右对齐)

为了方便css的flex样式的使用,可以将其进行二次封装成class

//二次封装成类
// 从左排列
.flex_j_start {
 justify-content: flex-start !important;
}
// 从右排列
.flex_j_end {
 justify-content: flex-end !important;
}

//处于x轴上方方向位置
.flex_a_start {
 align-items: flex-start !important;
}

//处于x轴下方方向位置
.flex_a_end {
 align-items: flex-end !important;
}
b)理解justify-content :space-between

该属性的作用是使得所有元素均匀分布,且各元素间距相同

参考Flex 布局教程:实例篇

.box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}
.box {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}

接下来看看space-between在实际中是怎么使用的

例子1:

<!-- 培训详情主题栏 -->
   <div class="card_bg flex_row">
     <!-- 培训详情按钮组 -->
     <el-form :inline="true" class="wrap_form">
         <!-- 按钮组 -->
         <div class="Button_group">
           <el-form-item>
             <el-button class="btn_style icon-short-btn" @click="pageBack()">
               <svg-icon
                 icon-class="arrow-left"
               />
               返回
             </el-button>
           </el-form-item>
         </div>
         <div class="font_style"> 培训详情 </div>
         <!-- 搜索组 -->
         <div class="Search_group">
           <el-form-item>
             <el-button class="icon-short-btn">
               <svg-icon
                 icon-class="edit"
                 @click="editBtn(scope.row)"
                 style="color:white;"
               />
               编辑
             </el-button>
           </el-form-item>
         </div>
     </el-form>
   </div>

其中wrap_form封装了justify-content: space-between;属性,效果如下:

在这里插入图片描述

如果不使用flex_between,则效果如下:

在这里插入图片描述

例子2:

如果不止两个元素,如下面这个页面:4个元素在盒子内均匀分布

在这里插入图片描述

如果去掉flex_between,则紧贴在一起了

在这里插入图片描述

c)for循环排列卡片

该例子通过for循环绘制卡片(会循环输出v-for所在的div),主要用到的flex样式flex_row 按行排列,flex_warp满行换行,flex_j_start从左排列。

        <!-- 卡片视图 -->
          <div class="wrap_card_person flex_row flex_warp flex_j_start">
            <div
              v-for="item in trainManage_obj.trainingManagePersonals"
              :key="item.id"
              class="dir_car"
            >
              <div class="car_name flex_row">
                <img :src="item.photo" @error="handleError($event)" />
                <div class="car_name_div flex_column">
                  <h3>{{item.user_name}}</h3>
                  <p class="serviceLife flex_column">
                    <span>职位:</span>
                    {{item.position}}
                  </p>
                </div>
              </div>
              <ul class="car_information flex_row flex_between">
                  <li class="flex_column">
                    <span>联系方式:</span>
                    {{item.contact}}
                  </li>
              </ul>
              <div class="car_remark">
                <h3>备注</h3>
                <p>
                  {{item.remark}}
                </p>
              </div>
              <div class="car_type">
                <span></span>
              </div>
            </div>
          </div>

其中flex_row flex_warp flex_a_content flex_j_start flex_between是对css的flex布局样式的二次封装类,而wrap_card_person是自定义卡片的css样式,主要设置每张图片的width,height

// 多列布局防止换行
.flex_a_content {
  align-content: flex-start !important;
}

// 从左排列
.flex_j_start {
  justify-content: flex-start !important;  //!important表示样式优先级最高
}

// 当width,height达到100%时,会自动换行,而不是去压缩div的width,height
.flex_warp {
  flex-wrap: wrap !important;
}

// flex 横向排列
.flex_row {
  display: flex !important;
  flex-direction: row !important;
  // flex: 1;
}

// 均为分布
.flex_between {
    justify-content: space-between !important;
}

.wrap_card_person {
  height: 100%;
  width: 100%;
  overflow-y: auto;

  .dir_car {
    border: 2px solid #131415;
    width: calc(100% / 4);  //每行4个卡片,相比于设置px,css的calc()可以自适应调整布局
    height: calc(100% / 3);
      ...
    }
}

效果图如下

在这里插入图片描述

参考

3、Flex响应式布局

非响应式布局存在的问题:

Flex由于是一维的布局(横坐标,纵坐标且单方向),如果要实现非均分布局(没办法使用justify-content: space-between),则可以用padding/margin来撑开,参考 解决flex布局中 space-between方法的排版问题。但是这会存在问题,当笔记本屏幕分辨率不同时,页面的布局会有所不同;当使用缩放时,页面布局也会跟着变化

在这里插入图片描述

要想实现Flex响应式布局,就要用到css的**width: calc(100% / 2)**来实现,页面效果如下:

在这里插入图片描述

参考

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐