如果同级列不存在,则使列跨度为全宽

时间:2019-03-20 17:19:35

标签: css css-grid

我正在尝试使CSS网格具有某种动态行为,同时使基本网格规则为静态。

我创建了一个sandbox,以更好地说明我想发生的事情。从DOM中删除GREEN框后,我希望RED覆盖整个第一行,而当GREEN可见时,我希望RED / GREEN在第一行分配2fr / 1fr。

我已经搜索了文档以尝试找到一种方法来执行此操作,但是我发现的唯一解决方案是在“运行时”操作CSS。只能使用CSS来实现吗?

const toggleBtn = document.querySelector("button.toggle-green");
const grid = document.querySelector(".grid");
const yellow = document.querySelector(".yellow");

const getGreen = () => document.querySelector(".green");
const createGreen = () => {
  const div = document.createElement("div");
  div.className = "green";
  div.innerText = "GREEN";
  return div;
};

toggleBtn.addEventListener("click", () => {
  const green = getGreen();
  if (!green) {
    grid.insertBefore(createGreen(), yellow);
  } else {
    green.remove();
  }
});
body {
  font-family: sans-serif;
}

.grid {
  display: grid;
  grid-template-columns: 2fr 1fr;
  grid-gap: 2px 2px;
}

.yellow {
  background: yellow;
  grid-column: span 2;
}

.red {
  background: red;
}

.green {
  background: green;
}
<div class="grid">
  <div class="red">RED</div>
  <div class="green">GREEN</div>
  <div class="yellow">YELLOW</div>
</div>
<button class="toggle-green">Toggle green</button>

1 个答案:

答案 0 :(得分:1)

可以使其与 CSS网格一起使用,但是您必须仔细设置宽度才能进行设置:

  • 使用grid-template-columns: repeat(auto-fit, minmax(66.66vw, 1fr))创建包装网格-请注意,此处的最小宽度视口单位表示。
  • 现在将绿色部分设置为min-width: 33.33vw

在下面的代码中-请注意calc的使用-这会grid-gap 水平调整。参见下面的演示:

const toggleBtn = document.querySelector("button.toggle-green");
const grid = document.querySelector(".grid");
const yellow = document.querySelector(".yellow");

const getGreen = () => document.querySelector(".green");
const createGreen = () => {
  const div = document.createElement("div");
  div.className = "green";
  div.innerText = "GREEN";
  return div;
};

toggleBtn.addEventListener("click", () => {
  const green = getGreen();
  if (!green) {
    grid.insertBefore(createGreen(), yellow);
  } else {
    green.remove();
  }
});
body {
  font-family: sans-serif;
  margin: 0;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(calc(66.66vw - 2px), 1fr));
  grid-gap: 2px 2px;
  width: 100vw;
}

.yellow {
  background: yellow;
  grid-column: span 2;
}

.red {
  background: red;
}

.green {
  background: green;
  min-width: 33.33vw;
}
<div class="grid">
  <div class="red">RED</div>
  <div class="green">GREEN</div>
  <div class="yellow">YELLOW</div>
</div>

<button class="toggle-green">Toggle green</button>


Flexbox解决方案

但是我建议您已经熟悉的 flexbox方法-使用包装flexbox 并设置: -flex: 1 green div, -flex-basis: 100% yellow 部分,然后 -flex: 2 red 部分。

请参见下面的演示

const toggleBtn = document.querySelector("button.toggle-green");
const grid = document.querySelector(".grid");
const yellow = document.querySelector(".yellow");

const getGreen = () => document.querySelector(".green");
const createGreen = () => {
  const div = document.createElement("div");
  div.className = "green";
  div.innerText = "GREEN";
  return div;
};

toggleBtn.addEventListener("click", () => {
  const green = getGreen();
  if (!green) {
    grid.insertBefore(createGreen(), yellow);
  } else {
    green.remove();
  }
});
body {
  font-family: sans-serif;
  margin: 0;
}

.grid {
  display: flex;
  flex-wrap: wrap;
  width: 100vw;
}

.yellow {
  background: yellow;
  flex-basis: 100%;
}

.red {
  background: red;
  flex: 2;
}

.green {
  background: green;
  flex: 1;
}
<div class="grid">
  <div class="red">RED</div>
  <div class="green">GREEN</div>
  <div class="yellow">YELLOW</div>
</div>

<button class="toggle-green">Toggle green</button>