如何设置基于flex或grid的动态网格

问题描述 投票:0回答:1

我正在摸索如何使用 CSS 创建这个特定的动态网格。我一直在尝试使用 CSS 网格,但我很好奇是否应该使用 Flexbox。

我将所需的可调整布局附加到我创建的模型中。

我正在 VueJS 中尝试这样做,这是我到目前为止的代码:

<script setup lang="ts">
const gridStyle = computed(() => {
  const base = 'grid-auto-rows: minmax(0, 1fr); grid-auto-flow: column;'
  if (visibleItems.value.length === 1) {
    return 'grid-template-columns: 1fr; ' + base
  } else if (visibleItems.value.length === 3) {
    return 'grid-template-columns: 4fr 1fr; ' + base
  } else {
    return 'grid-template-columns: 3fr 1fr 1fr; ' + base
  }
})

const itemStyle = (item: iFrame, index: number) => {
  const remainingItems = visibleItems.value.length - 2

  if (index === 0 && !itemIsVisible(items.value[1])) {
    return 'grid-row: span 4; grid-column: span 2; height: 100vh;'
  } else if (index < 2 && items.value.indexOf(item) < 2) {
    return 'grid-row: span 4; height: 100vh;'
  } else if (remainingItems === 1) {
    if (index === 1) {
      return `grid-row: span 1; `
    }
    if (index === 2) {
      return `grid-row: span 3; `
    }
  } else {
    const rowsToSpan = Math.min(4, Math.floor(4 / Math.max(1, remainingItems)))
    return `grid-row: span ${rowsToSpan};`
  }
}
</script>

<div class="grid h-screen gap-0" :style="gridStyle">
    <div
      v-for="(item, index) in visibleItems"
      :key="item.id"
      class="h-full w-full"
      :style="itemStyle(item, index)"
    >
</div>
</div>

这段代码已经帮我解决了大部分问题,但是当我有两个、三个、四个和五个我想整理的项目时,会出现一些小的视觉问题。

css vue.js flexbox css-grid
1个回答
0
投票

另一种设置方法是使用 CSS grid-template-areas。

这样您就可以简单地控制每个项目的布局。

此代码片段使用 JS 查找项目数量,CSS 完成其余工作:

<style>
  .grid {
    display: grid;
    width: 100vmin;
    aspect-ratio: 16/ 9;
    gap: 1vw;
  }
  
  .grid.n1 {
    grid-template-areas: 'A';
  }
  
  .grid.n2 {
    grid-template-areas: 'A A A A A B B';
  }
  
  .grid.n3 {
    grid-template-areas: 'A A A A A B B' 'A A A A A C C' 'A A A A A C C' 'A A A A A C C';
  }
  
  .grid.n4 {
    grid-template-areas: 'A A A B B C' 'A A A B B D' 'A A A B B D' 'A A A B B D';
  }
  
  .grid.n5 {
    grid-template-areas: 'A A A B B C' 'A A A B B D' 'A A A B B E' 'A A A B B E';
  }
  
  .grid.n6 {
    grid-template-areas: 'A A A B B C' 'A A A B B D' 'A A A B B E' 'A A A B B F';
  }
  
  .grid.n7 {
    grid-template-areas: 'A A B B C C G' 'A A B B D D G' 'A A B B E E G' 'A A B B F F G';
  }
  
  .grid.n8 {
    grid-template-areas: 'A A B B C C G' 'A A B B D D H' 'A A B B E E H' 'A A B B F F H';
  }
  
  .grid>* {
    width: 100%;
    height: 100%;
    background: gray;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  
  .grid :nth-child(1) {
    grid-area: A;
  }
  
  .grid :nth-child(2) {
    grid-area: B;
  }
  
  .grid :nth-child(3) {
    grid-area: C;
  }
  
  .grid :nth-child(4) {
    grid-area: D;
  }
  
  .grid :nth-child(5) {
    grid-area: E;
  }
  
  .grid :nth-child(6) {
    grid-area: F;
  }
  
  .grid :nth-child(7) {
    grid-area: G;
  }
  
  .grid :nth-child(8) {
    grid-area: H;
  }
</style>
<div class="grid">
  <div>1</div>
  <div>2</div>
  <div>3</div>
  <div>4</div>
  <div>5</div>
  <div>6</div>
  <div>7</div>
  <div>8</div>
</div>
<script>
  const grid = document.querySelector('.grid');
  const n = document.querySelectorAll('.grid > *').length;
  grid.classList.add('n' + n);
</script>

© www.soinside.com 2019 - 2024. All rights reserved.