#css #css-grid
#css #css-сетка
Вопрос:
Я пытаюсь обеспечить несколько динамичное поведение в CSS-сетке, при этом базовые правила сетки должны быть статичными.
Я создал изолированную среду, чтобы лучше проиллюстрировать, что я хочу, чтобы произошло. Когда ЗЕЛЕНОЕ поле удаляется из DOM, я хочу, чтобы КРАСНОЕ покрывало всю первую строку, а когда будет видно ЗЕЛЕНОЕ, я хочу, чтобы у 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. Честно говоря, это звучит так, как будто flexbox мог бы это исправить,
Ответ №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
в зеленый раздел, — flex-basis: 100%
в желтый раздел и — flex: 2
в красный раздел.
Смотрите демонстрацию ниже:
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>