【CSS】 Grid布局:现代网页设计的基石

引言

最近接到一个网页布局比较复杂的页面,看了半天还是决定用grid布局来写,记录一下

布局是构建用户界面的关键部分。CSS Grid布局提供了一种简单而强大的方式来创建复杂的网格布局,它让设计师和开发者能够更直观、更灵活地控制网页的结构。本文将深入探讨CSS Grid布局的核心概念、优势以及如何在实际项目中应用它。

CSS Grid布局基础

什么是CSS Grid布局?

CSS Grid布局是一种基于网格的布局系统,允许你将页面分割成多个行和列。它提供了一种在二维空间内布局元素的方法,可以轻松地创建复杂的布局结构。

Grid容器和Grid项

  • Grid容器 :通过设置 display: griddisplay: inline-grid 属性,一个元素就变成了Grid容器。
  • Grid项:Grid容器的直接子元素自动成为Grid项。

Grid轨道

  • Grid列和行 :通过 grid-template-columnsgrid-template-rows 属性定义网格的列和行。
  • Grid间隙 :使用 grid-column-gapgrid-row-gap(或简写为 grid-gap)来设置网格项之间的间隙。

Grid线

  • 命名网格线:可以给网格线命名,以便更精确地定位Grid项。
  • 网格线编号:网格线从1开始编号,可以使用这些编号来指定Grid项的位置。

CSS Grid布局的优势

灵活性

CSS Grid布局提供了前所未有的灵活性,可以轻松地创建响应式设计,适应不同屏幕尺寸和设备。

简洁性

与传统的浮动布局相比,Grid布局的语法更加简洁明了,减少了需要的CSS代码量。

对齐控制

CSS Grid布局提供了强大的对齐控制功能,包括对齐网格项和对齐整个网格。

CSS Grid布局的实用技巧

创建复杂布局

介绍如何使用Grid布局创建复杂的页面布局,包括多列布局、不规则网格等。

响应式设计

探讨如何利用CSS Grid布局实现响应式设计,包括使用媒体查询和网格模板区域。

与Flexbox的对比

简要比较CSS Grid布局与Flexbox布局,帮助读者理解何时使用Grid布局,何时使用Flexbox布局。

实际案例分析

通过分析几个实际的网页设计案例,展示CSS Grid布局在实际项目中的应用。

结语

CSS Grid布局是现代网页设计不可或缺的一部分。掌握它将为你的网页设计带来无限可能,让你能够创建出既美观又功能强大的用户界面。

文章最后推荐一下:CSS Grid Generator

它可以帮你快速实现grid布局

文章开头布局,完整代码:

javascript 复制代码
<!-- 懒得简化了,先实现页面再说,时间紧任务重,哈哈哈 -->
<template>
  <div class="InvCurrTons">
    <div class="InvCurrTons-left">
      <div class="InvCurrTons-left-box1">
        <div class="toTitle">
          <h3>
            碎浆站
          </h3>
          <div class="fTitle">
            <div>短纤: 23323</div>
            <div>长纤: 42332</div>
            <div>机械浆: 432</div>
            <div>总计: 66087</div>
          </div>
        </div>
        <div class="InvCurrTons-left-box1-content">
          <div class="parent" style="width: 12%;">
            <div v-for="(item, index) in PulpData.items" :key="index">
              <!-- kd: item.type === 0, -->
              <div
                class="kd"
                :class="{
                  bd: item.type === 1,
                  md: item.type === 2
                }"
              >
                {{ item.name }}
              </div>
            </div>
          </div>
          <div class="vertical-dashed-line"></div>
          <div class="vertical-dashed-line2"></div>
          <div class="parent-right" style="width: 85%;">
            <div class="parent-right-item1">
              <div class="parent5">
                <div
                  class="box1 kd"
                  :class="{
                    bd: PulpData.items1[0].type === 1,
                    md: PulpData.items1[0].type === 2,
                    bd2: PulpData.items1[0].type === 3
                  }"
                >
                  {{ PulpData.items1[0].name }}
                </div>
              </div>
            </div>
            <div class="parent-right-item2">
              <div class="parent2" style="width: 45%;">
                <div
                  v-for="(item, index) in PulpData.items2"
                  :key="index"
                  :class="'LBDiv' + (index + 1)"
                >
                  <!-- kd: item.type === 0, -->
                  <div
                    class="kd"
                    :class="{
                      bd: item.type === 1,
                      md: item.type === 2,
                      bd2: item.type === 3
                    }"
                  >
                    {{ item.name }}
                  </div>
                </div>
              </div>

              <div
                class="vertical-dashed-line2"
                style="margin-left: 4px;"
              ></div>
              <div class="vertical-dashed-line2"></div>
              <div class="vertical-dashed-line3"></div>
              <div
                class="vertical-dashed-line3"
                style="width: 22%;left: 48%;"
              ></div>

              <div class="parent3" style="width: 20%;">
                <div
                  v-for="(item, index) in PulpData.items3"
                  :key="index"
                  :class="'CBDiv' + (index + 1)"
                >
                  <!-- kd: item.type === 0, -->
                  <div
                    class="kd"
                    :class="{
                      bd: item.type === 1,
                      md: item.type === 2,
                      bd2: item.type === 3
                    }"
                  >
                    {{ item.name }}
                  </div>
                </div>
              </div>

              <div class="vertical-dashed-line4"></div>
              <div class="vertical-dashed-line2"></div>
              <div class="vertical-dashed-line2"></div>

              <div class="parent4" style="width: 25%;">
                <div
                  v-for="(item, index) in PulpData.items4"
                  :key="index"
                  :class="'RBDiv' + (index + 1)"
                >
                  <!-- kd: item.type === 0, -->
                  <div
                    class="kd"
                    :class="{
                      bd: item.type === 1,
                      md: item.type === 2,
                      bd2: item.type === 3
                    }"
                  >
                    {{ item.name }}
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="InvCurrTons-left-box2">
        <div class="toTitle" style="height: 20%;">
          <h3>
            旧堆场
          </h3>
          <div class="fTitle">
            <div>短纤: 23323</div>
            <div>长纤: 42332</div>
            <div>机械浆: 432</div>
            <div>总计: 66087</div>
          </div>
        </div>
        <div class="InvCurrTons-left-box2-content">
          <div
            v-for="(item, index) in OldDump.items"
            :key="index"
            class="jdcBox"
          >
            <!-- kd: item.type === 0, -->
            <div
              class="kd"
              :class="{
                bd: item.type === 1,
                md: item.type === 2,
                bd2: item.type === 3
              }"
            >
              {{ item.name }}
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="InvCurrTons-right">
      <div class="toTitle">
        <h3>
          一万方堆场
        </h3>
        <div class="fTitle">
          <div>短纤: 23323</div>
          <div>长纤: 42332</div>
          <div>机械浆: 432</div>
          <div>总计: 66087</div>
        </div>
      </div>
      <div class="InvCurrTons-right-content">
        <div class="box"></div>
        <div class="grid1">
          <div class="grid1-l">
            <div
              v-for="(item, index) in tenKHeapData.items"
              :key="index"
              class="grid1-l-piece"
              :class="'grid1L' + (index + 1)"
            >
              <div
                class="kd"
                :class="{
                  bd: item.type === 1,
                  md: item.type === 2,
                  bd2: item.type === 3
                }"
              >
                {{ item.name }}
              </div>
            </div>
          </div>
          <div style="display: flex;align-items: flex-end;">
            <div
              class="vertical-dashed-line2"
              style="height: 42%;background-size: 2rem 1.4rem;"
            ></div>
            <div
              class="vertical-dashed-line2"
              style="height: 42%;background-size: 2rem 1.4rem;"
            ></div>
          </div>
          <div class="grid1-c">
            <div
              v-for="(item, index) in tenKHeapData.items2"
              :key="index"
              :class="'grid1C' + (index + 1)"
            >
              <div
                class="kd"
                :class="{
                  bd: item.type === 1,
                  md: item.type === 2,
                  bd2: item.type === 3
                }"
              >
                {{ item.name }}
              </div>
            </div>
          </div>
          <div class="vertical-dashed-line"></div>
          <div class="vertical-dashed-line2"></div>
          <div class="grid1-r">
            <div
              v-for="(item, index) in tenKHeapData.items3"
              :key="index"
              class="grid1-r-piece"
            >
              <div
                class="kd"
                :class="{
                  bd: item.type === 1,
                  md: item.type === 2,
                  bd2: item.type === 3
                }"
              >
                {{ item.name }}
              </div>
            </div>
          </div>
        </div>
        <div class="box" style="position: relative;">
          <div
            class="vertical-dashed-line3"
            style="width: 20%;top: 0;left: 1rem;"
          ></div>
          <div
            class="vertical-dashed-line3"
            style="width: 44%;top: 0;left: 8.8rem;"
          ></div>
          <div
            class="vertical-dashed-line3"
            style="width: 22%;top: 0;left: 24.4rem;"
          ></div>

          <div
            class="vertical-dashed-line3"
            style="width: 20%;top: 100%;left: 1rem;"
          ></div>
          <div
            class="vertical-dashed-line3"
            style="width: 44%;top: 100%;left: 8.8rem;"
          ></div>
          <div
            class="vertical-dashed-line3"
            style="width: 22%;top: 100%;left: 24.4rem;"
          ></div>
        </div>
        <div class="grid2">
          <div class="grid2-l">
            <div
              v-for="(item, index) in tenKHeapData.items4"
              :key="index"
              class="grid1-r-piece"
            >
              <div
                class="kd"
                :class="{
                  bd: item.type === 1,
                  md: item.type === 2,
                  bd2: item.type === 3
                }"
              >
                {{ item.name }}
              </div>
            </div>
          </div>
          <div class="vertical-dashed-line"></div>
          <div class="vertical-dashed-line2"></div>
          <div class="grid2-c">
            <div
              v-for="(item, index) in tenKHeapData.items5"
              :key="index"
              class="grid1-r-piece"
            >
              <div
                class="kd"
                :class="{
                  bd: item.type === 1,
                  md: item.type === 2,
                  bd2: item.type === 3
                }"
              >
                {{ item.name }}
              </div>
            </div>
          </div>
          <div class="vertical-dashed-line"></div>
          <div class="vertical-dashed-line2"></div>
          <div class="grid2-l">
            <div
              v-for="(item, index) in tenKHeapData.items6"
              :key="index"
              class="grid1-r-piece"
            >
              <div
                class="kd"
                :class="{
                  bd: item.type === 1,
                  md: item.type === 2,
                  bd2: item.type === 3
                }"
              >
                {{ item.name }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {
      PulpData: {
        items: [
          { name: 111, type: 2 },
          { name: 110 },
          { name: 109 },
          { name: 108, type: 2 },
          { name: 107, type: 1 },
          { name: 106, type: 1 },
          { name: 105, type: 0 },
          { name: 104, type: 1 },
          { name: 103, type: 2 },
          { name: 102 },
          { name: 101, type: 2 }
        ],
        items1: [{ name: "2-3", type: 2 }],
        items2: [
          { name: 201, type: 2 },
          { name: 112, type: 2 },
          { name: 113, type: 1 },
          { name: 202, type: 1 },
          { name: 114 },
          { name: 203 },
          { name: "1-1", type: 2 },
          { name: "1-2" },
          { name: 204, type: 1 },
          { name: "1-3", type: 3 }
        ],
        items3: [
          { name: 205, type: 1 },
          { name: 206, type: 2 },
          { name: "2-1", type: 3 },
          { name: "2-2", type: 3 }
        ],
        items4: [
          { name: 301, type: 0 },
          { name: 302, type: 1 },
          { name: "3-1", type: 2 },
          { name: "3-2", type: 3 },
          { name: "3-3", type: 2 }
        ]
      },
      OldDump: {
        items: [
          { name: 601, type: 2 },
          { name: 602, type: 3 },
          { name: 603, type: 0 },
          { name: 604, type: 2 },
          { name: 605, type: 0 }
        ]
      },
      tenKHeapData: {
        items: [
          { name: 718, type: 2 },
          { name: 719, type: 1 },
          { name: 720, type: 0 }
        ],
        items2: [
          { name: 715, type: 2 },
          { name: 716, type: 2 },
          { name: 717, type: 1 },
          { name: 708, type: 2 },
          { name: 709, type: 0 },
          { name: 710, type: 1 },
          { name: 711, type: 1 },
          { name: 712, type: 1 },
          { name: 713, type: 2 },
          { name: 714, type: 2 }
        ],
        items3: [
          { name: 707, type: 0 },
          { name: 706, type: 2 },
          { name: 705, type: 1 },
          { name: 704, type: 2 },
          { name: 703, type: 1 },
          { name: 702, type: 2 },
          { name: 701, type: 1 }
        ],
        items4: [
          { name: 816, type: 2 },
          { name: 817, type: 2 },
          { name: 818, type: 1 },
          { name: 819, type: 1 },
          { name: 820, type: 1 }
        ],

        items5: [
          { name: 811, type: 2 },
          { name: 806, type: 2 },
          { name: 812, type: 5 },
          { name: 807, type: 1 },
          { name: 813, type: 1 },
          { name: 808, type: 0 },
          { name: 814, type: 2 },
          { name: 809, type: 2 },
          { name: 815, type: 1 },
          { name: 810, type: 0 }
        ],
        items6: [
          { name: 801, type: 2 },
          { name: 802, type: 1 },
          { name: 803, type: 2 },
          { name: 804, type: 0 },
          { name: 805, type: 0 }
        ]
      }

      //type说明: 空堆0 横半堆1 满堆2 竖半堆3
    };
  },
  //监听属性 类似于data概念
  computed: {},
  //监控data中的数据变化
  watch: {},
  //方法集合
  methods: {},
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {},
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {},
  beforeCreate() {}, //生命周期 - 创建之前
  beforeMount() {}, //生命周期 - 挂载之前
  beforeUpdate() {}, //生命周期 - 更新之前
  updated() {}, //生命周期 - 更新之后
  beforeDestroy() {}, //生命周期 - 销毁之前
  destroyed() {}, //生命周期 - 销毁完成
  activated() {} //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>

<style lang="less" scoped>
//@import url(); 引入公共css类
.kd {
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  border: 1px solid #065178;
}
.bd {
  border: 1px solid #065178;
  background: linear-gradient(to right, #0073a7 70%, #e9e9e900 0);
}
.md {
  border: 0px solid;
  background: #0073a7;
}
.bd2 {
  border: 1px solid #065178;
  background: linear-gradient(to bottom, #0073a7 70%, #e9e9e900 0);
}

.toTitle {
  height: 10%;
  text-align: center;
  color: #0184cf;
  .fTitle {
    color: #71c5e5;
    display: flex;
    justify-content: center;
    div {
      margin-right: 0.6rem;
    }
  }
}
.InvCurrTons {
  display: flex;
  height: 100%;
  &-left {
    width: 60%;
    margin: 1rem 0rem 2rem;

    &-box1 {
      height: 70%;
      background: url("../../img/New/cardB.svg") no-repeat;
      background-size: 100% 100%;
      background-position: center top;
      margin: 0 0.5rem;
      padding: 0.5rem;

      &-content {
        display: flex;
        flex-direction: row;
        position: relative;
        height: 90%;
        padding: 0.4rem 0;
        .parent {
          text-align: center;
          display: flex;
          flex-direction: column;
          justify-content: space-between;
        }

        .parent-right {
          .parent-right-item1 {
            height: 50%;
          }
          .parent-right-item2 {
            position: relative;
            height: 50%;
            display: flex;
          }
        }
      }
    }
    &-box2 {
      height: 30%;
      background: url("../../img/New/cardB.svg") no-repeat;
      background-size: 100% 100%;
      background-position: center top;
      margin: 0.5rem 0.5rem 0;
      &-content {
        display: flex;
        flex-direction: row;
        position: relative;
        height: 80%;
        padding: 0.4rem 0;
        justify-content: center;
        .jdcBox {
          padding: 1rem;
          width: 7rem;
        }
      }
    }
  }
  &-right {
    width: 45%;
    background: url("../../img/New/cardB.svg") no-repeat;
    background-size: 100% 100%;
    background-position: center top;
    margin: 1rem 0rem 1.5rem;
    &-content {
      height: 90%;
      position: relative;
      .box {
        height: 10%;
      }
      .grid1 {
        height: 45%;
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        padding: 0 1rem;
        &-l {
          width: 23%;
          padding-right: 0.3rem;
          display: grid;
          grid-template-columns: 1fr;
          grid-template-rows: repeat(7, 1fr);
          grid-column-gap: 0;
          grid-row-gap: 0.4rem;
          padding-bottom: 0.3rem;
        }
        &-c {
          height: 100%;
          width: 46%;
          display: grid;
          grid-template-columns: repeat(2, 1fr);
          grid-template-rows: repeat(7, 1fr);
          grid-column-gap: 0.4rem;
          grid-row-gap: 4px;
          padding-bottom: 0.3rem;
        }
        &-r {
          height: 100%;
          width: 23%;
          display: grid;
          grid-template-columns: 1fr;
          grid-template-rows: repeat(7, 1fr);
          grid-column-gap: 0px;
          grid-row-gap: 4px;
          padding-bottom: 0.3rem;
        }
      }
      .grid2 {
        height: 35%;
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        padding: 0 1rem;
        &-l {
          height: 100%;
          width: 23%;
          display: grid;
          grid-template-columns: 1fr;
          grid-template-rows: repeat(5, 1fr);
          grid-column-gap: 0px;
          grid-row-gap: 4px;
          padding: 0.3rem 0 0.5rem;
        }
        &-c {
          width: 46%;
          display: grid;
          grid-template-columns: repeat(2, 1fr);
          grid-template-rows: repeat(5, 1fr);
          grid-column-gap: 0.4rem;
          grid-row-gap: 4px;
          padding: 0.3rem 0 0.5rem;
        }
      }
    }
  }
}

.vertical-dashed-line {
  width: 2px;
  height: 97%;

  background-image: linear-gradient(
    to bottom,
    rgba(78, 83, 88, 1) 0%,
    rgba(78, 83, 88, 1) 50%,
    transparent 80%
  );
  background-size: 2rem 2rem; //第一个值(20px)越大线条越长间隙越大
  margin: 0 0.5rem 0.5rem;
}
.vertical-dashed-line2 {
  width: 2px;
  height: 97%;
  background-image: linear-gradient(
    to bottom,
    rgba(40, 51, 63, 1) 0%,
    rgba(40, 51, 63, 1) 50%,
    transparent 80%
  );
  background-size: 2rem 2rem; //第一个值(20px)越大线条越长间隙越大
  margin-right: 0.5rem;
}
.vertical-dashed-line3 {
  width: 35%;
  height: 2px;
  background-image: linear-gradient(
    to right,
    rgba(78, 83, 88, 1) 0%,
    rgba(78, 83, 88, 1) 50%,
    transparent 80%
  );
  background-size: 2rem 2rem; //第一个值(20px)越大线条越长间隙越大
  margin-right: 0.5rem;
  position: absolute;
  top: -8px;
  left: 11%;
}
.vertical-dashed-line4 {
  width: 3px;
  height: 97%;
  background-image: linear-gradient(to bottom, rgba(78, 83, 88, 1));
  background-size: 2rem 2rem; //第一个值(20px)越大线条越长间隙越大
  margin-right: 0.2rem;
}
</style>

<style>
.parent2 {
  width: 100%;
  text-align: center;
  display: grid;
  grid-template-columns: repeat(2, 1.3fr) 0.8fr repeat(2, 1fr);
  grid-template-rows: repeat(16, 1fr);
  grid-column-gap: 2px;
  grid-row-gap: 2px;
}
.LBDiv1 {
  grid-area: 13/4/17/6;
}
.LBDiv2 {
  grid-area: 14 / 2 / 17 / 4;
}
.LBDiv3 {
  grid-area: 11 / 2 / 14 / 4;
}
.LBDiv4 {
  grid-area: 9 / 4 / 13 / 6;
}
.LBDiv5 {
  grid-area: 8 / 2 / 11 / 4;
}
.LBDiv6 {
  grid-area: 5 / 4 / 9 / 6;
}
.LBDiv7 {
  grid-area: 1 / 2 / 8 / 3;
}
.LBDiv8 {
  grid-area: 1 / 3 / 8 / 4;
}
.LBDiv9 {
  grid-area: 1 / 4 / 5 / 6;
}
.LBDiv10 {
  grid-area: 1 / 1 / 14 / 2;
  margin-right: 0.5rem;
}

.parent3 {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(5, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 5px;
}

.CBDiv1 {
  grid-area: 5 / 1 / 6 / 5;
}
.CBDiv2 {
  grid-area: 4 / 1 / 5 / 5;
}
.CBDiv3 {
  grid-area: 1 / 1 / 4 / 3;
}
.CBDiv4 {
  grid-area: 1 / 3 / 4 / 5;
}

.parent4 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(5, 1fr);
  grid-column-gap: 10px;
  grid-row-gap: 5px;
}

.RBDiv1 {
  grid-area: 5 / 1 / 6 / 4;
}
.RBDiv2 {
  grid-area: 4 / 1 / 5 / 4;
}
.RBDiv3 {
  grid-area: 1 / 1 / 4 / 2;
}
.RBDiv4 {
  grid-area: 1 / 2 / 4 / 3;
}
.RBDiv5 {
  grid-area: 1 / 3 / 4 / 4;
}

.parent5 {
  height: 91%;
  display: grid;
  grid-template-columns: repeat(6, 1fr) 0.9fr repeat(3, 1fr);
  grid-template-rows: repeat(5, 1fr);
  grid-column-gap: 0px;
  grid-row-gap: 0px;
}

.box1 {
  grid-area: 3 / 7 / 6 / 8;
}

.grid1L1 {
  grid-area: 7 / 1 / 8 / 2;
}
.grid1L2 {
  grid-area: 6 / 1 / 7 / 2;
}
.grid1L3 {
  grid-area: 5 / 1 / 6 / 2;
}

.grid1C1 {
  grid-area: 7 / 1 / 8 / 2;
}
.grid1C2 {
  grid-area: 6 / 1 / 7 / 2;
}
.grid1C3 {
  grid-area: 5 / 1 / 6 / 2;
}
.grid1C4 {
  grid-area: 7 / 2 / 8 / 3;
}
.grid1C5 {
  grid-area: 6 / 2 / 7 / 3;
}
.grid1C6 {
  grid-area: 5 / 2 / 6 / 3;
}
.grid1C7 {
  grid-area: 4 / 2 / 5 / 3;
}
.grid1C8 {
  grid-area: 3 / 2 / 4 / 3;
}
.grid1C9 {
  grid-area: 2 / 2 / 3 / 3;
}
.grid1C10 {
  grid-area: 1 / 2 / 2 / 3;
}
</style>
相关推荐
崔庆才丨静觅1 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60612 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了2 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅2 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅2 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅3 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment3 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅3 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊3 小时前
jwt介绍
前端
爱敲代码的小鱼3 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax