likes
comments
collection
share

table表格自适应浏览器窗口变化解决方案

作者站长头像
站长
· 阅读数 29

前言

大家好,本文聊一下在做后台管理系统项目时,表格高度自适应的css解决方案,使表格能根据浏览器窗口变化自适应调节高度、自动适应内容高度来显示表格滚动条。本文基于vue3+element-plus组件库进行开发,主要涉及到flex布局、以及BFC特性

BFC简要介绍

BFC,即块格式化上下文(Block Formatting Context),是CSS中的一个概念,用于描述Web页面中块级元素布局的一种规则。BFC是一种独立的渲染区域,具有一套渲染规则,决定了其中元素如何布局、相互影响以及与外部元素的关系。

BFC的主要特性包括:

  1. 包含块:BFC会创建一个包含块,它决定了BFC内部元素的布局。通常情况下,包含块是指最近的块级祖先元素,但也可以通过设置某些CSS属性(如float、position等)将其改变。
  2. 垂直方向上的布局:在BFC中,垂直方向的边距(margin)会发生折叠(合并),这意味着相邻的块级元素的上下边距可能会变得较小,从而影响它们的布局。
  3. 清除浮动:当一个元素浮动时,它会脱离正常的文档流,可能导致父元素的高度塌陷。而在BFC中,浮动元素会被包含在内部,从而解决了这个问题。
  4. 阻止外部元素的影响:BFC会创建一个隔离的环境,使得BFC内部元素与外部元素相互独立,不会相互影响。

布局设计

layout.vue文件

<template>
  <el-container>
    <el-aside width="200px">Aside</el-aside>
    <el-container>
      <el-header>Header</el-header>
      <el-main>Main</el-main>
    </el-container>
  </el-container>
</template>

<script setup lang="ts">

</script>

<style scoped>
.el-aside {
  background-color: #D9ECFF;
}
.el-header {
  background-color: #C6E2FF;
}
.el-main {
  background-color: #ECF5FF;
}
</style>

布局如下图所示:

table表格自适应浏览器窗口变化解决方案

接下来把el-container容器设置为height: 100vh;vh是一个相对单位,表示视口高度的百分比。 这里即把容器高度设置为相对于浏览器窗口显示网页内容的部分视图的100%。

.el-container {
  height: 100vh;
}

现在已经使铺满屏幕了,如下图所示:

table表格自适应浏览器窗口变化解决方案

我们的路由一般展示在main区域,下面开始创建一个表格数据展示页面,页面支持筛选查询以及分页。

page.vue

<template>
  <div class="flex-box">
    <!-- 封装的筛选表单 -->
    <FilterForm />
    <!-- 封装的表格组件 -->
    <Table class="flex-1" :data="tableData">
      <el-table-column prop="date" label="Date" width="180" />
      <el-table-column prop="name" label="Name" width="180" />
      <el-table-column prop="address" label="Address" />
      <el-table-column label="操作">
        <el-button @click="to">查看</el-button>
      </el-table-column>
    </Table>
  </div>
</template>

<script setup lang="ts">
import { useRouter } from 'vue-router'
import FilterForm from '@/components/FilterForm/FilterForm.vue'
import Table from '@/components/Table/Table.vue'

const router = useRouter()

const tableData: any[] = []
for(let i = 0; i < 100; i++) {
  tableData.push({
    date: '2016-05-03',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  })
}

const to = () => {
  router.push('/user/1')
}
</script>

Table.vue组件

<template>
  <div class="table-box">
    <el-table :data="data" border style="width: 100%">
      <slot></slot>
    </el-table>
    <!-- 封装的页码组件 -->
    <Pagination :total="data.length"/>
  </div>
</template>

页面效果如下:

table表格自适应浏览器窗口变化解决方案

这里可以看到在main区域出现了滚动条,而我们想要的效果外部布局容器不显示滚动条,只在表格内容区域出现滚动条,并且固定表头。

首先查看如何实现固定表头,查阅element-plus官方文档固定表头只需设置height高度即可:

table表格自适应浏览器窗口变化解决方案

但是,我们现在想要实现的是根据浏览器窗口大小自动计算出表格高度,实现方法之一可以通过js动态计算视口高度,但这也存在一定的性能消耗,所以这里介绍另一种解决方案,即使用CSS3引入的flex自适应布局来实现动态计算高度。

回到刚刚创建的page.vue页面,在页面根标签divTable组件分别添加flex-boxhidden类及样式:

<template>
  <div class="flex-box">
    <!-- 封装的筛选表单 -->
    <FilterForm />
    <!-- 封装的表格组件 -->
    <Table class="hidden" :data="tableData">
      <el-table-column prop="date" label="Date" width="180" />
      <el-table-column prop="name" label="Name" width="180" />
      <el-table-column prop="address" label="Address" />
      <el-table-column label="操作">
        <el-button @click="to">查看</el-button>
      </el-table-column>
    </Table>
  </div>
</template>
.flex-box {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.hidden {
  overflow: hidden;
}

.flex-box继承main的高度,并且开启column方向的flex布局,再给包裹el-table组件的div标签设置overflow: hidden;触发BFC特性,隐藏子元素高度溢出部分,并使其高度不会被子元素的高度影响,使其高度能够自适应flex-box容器下的剩余空间。这里不选择增加flex:1;样式的目的是,考虑到表格数据较少不足以铺满剩余空间时,出现的白边情况。

增加flex: 1;效果如下图所示:

table表格自适应浏览器窗口变化解决方案

没有flex: 1;效果如下图所示:

table表格自适应浏览器窗口变化解决方案

table表格自适应浏览器窗口变化解决方案

目前,包裹表格和页码容器高度已经可以自适应,但是el-table表格高度还没做自适应,所以表格高度溢出也导致页码被挤出容器被隐藏了,所以进来Table.vue表格组件设置一下样式

.table-box {
  display: flex;
  flex-direction: column;
}
.el-table {
  flex: 1;
  overflow: hidden;
}

这里主要也是为el-table表格设置overflow: hidden;使其能够自适应table-box的剩余空间,即减去页码组件高度所剩空间,如何不设置表格将占满父容器高度,页码将被溢出而被隐藏。

最终效果图,如下所示

table表格自适应浏览器窗口变化解决方案

总结

以上表格自适应高度主要考察flex布局,以及通过为父元素设置overflow: hidden;触发BFC的特性,使得BFC内部元素(即子元素)与外部元素相互独立,不会相互影响,防止子元素高度溢出时撑开父容器,影响flex布局无法正常自适应问题。

往期文章回顾