Как реализовать развёртывание div на всю ширину со смещением соседних блоков?

Ребят, есть такая вот вёрстка (см. изображение) реализовал при помощи grid. Идея реализации постов, когда пользователь нажимает по посту, то тот разворачивается на всю ширину в том месте, где был изначально, а блоки что рядом, смещаются.

вот так это выглядит на примере

до нажатия до нажатия

после нажатия после нажатия

нажимаем по 5 блоку и тот растягивается на всю ширину. блоки, что рядом смещаются относительно 5 блока.

на другом ресурсе мне помогли и слепили такой вот код (codepen), но он не очень хорошо функционирует. отказывается работать на jquery 2.x.x, похоже, что он нормально робит только на v3.4.1+, что странно, непонятно почему не хочет. скорее всего, это связано с псевдоэлементом before...

если есть идеи, то прошу помощи, спасибо.

и вариант кода на чистом js.

let block = document.querySelector(".block");
let number;

for (let i = 0; i < items.length; i++) {


  items[i].addEventListener('click', (e) => {
    items.forEach(item => item.classList.remove('active'));
    e.target.classList.add('active');
    number = i + 1;

    if (number % 3 == 2) {
      block.style.setProperty('--column', '1/3');
      block.style.setProperty('--display', 'block');
    } else if (number % 3 == 1) {
      block.style.setProperty('--display', 'none');
    } else if (number % 3 == 0) {
      block.style.setProperty('--column', '1/2');
      block.style.setProperty('--display', 'block');
    }

  })

}

если использовать код на чистом js, то всё бы хорошо, но, при нажатии на .item, класс .active привязывается к любому элементу внутри .item. на какой нажал к тому и привяжется)

p.s. ссори, спойлеры тут странно работают, поэтому - полотно.


Ответы (1 шт):

Автор решения: UModeL

Всё-таки JS, лично мне, более понятен. Теперь можете указывать любое количество колонок - логика останется прежней:

let block = document.querySelector(".block");
let items = [...block.querySelectorAll("div.item")];
let cols = getComputedStyle(block).gridTemplateColumns.split(' ').length;
block.addEventListener('click', (ev) => {
  let target = ev.target.closest('.item');
  if (!target) return;
  items.forEach((item) => { item.classList.remove('active'); });
  target.classList.add('active');
  let index = items.indexOf(target);
  block.style.setProperty('--display', (index % cols == 0 ? 'none' : 'block'));
  block.style.setProperty('--column', `1/${(index + 1 == cols) ? 0 : cols - (index % cols) + 1}`);
})
body { margin: 0; }

.block {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 20px;
}
.block::before {
  content: '**'; /* стереть звездочки и фон, сейчас для наглядности */
  background: #f003;
  display: var(--display, none);
  grid-column: var(--column, 1/1);
}

.item {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: #000;
  color: #fff;
  font-size: 30px;
}
.active { grid-column: 1/-1; }
<div class="block">

  <div class="item item-1">1</div>
  <div class="item item-2">2</div>
  <div class="item item-3">3</div>
  <div class="item item-4">4</div>
  <div class="item item-5">5</div>
  <div class="item item-6"><span><em><b>6</b></em></span></div>
  <div class="item item-7">7</div>
  <div class="item item-8">8</div>
  <div class="item item-9"><span>9</span></div>
  <div class="item item-10">10</div>
  <div class="item item-11">11</div>
  <div class="item item-12">12</div>
  <div class="item item-13">13</div>
  <div class="item item-14">14</div>
  <div class="item item-15">15</div>

</div>

→ Ссылка