元素网格排列CSS

时间:2018-12-06 15:18:09

标签: javascript html css flexbox

我正在尝试实现一种方案:单击一个框时,它在下一行中显示一个“长框”(全宽)。问题是单击的对象后面有缝隙。

是否可以在下一行显示“长框”而不用CSS更改小框的结构? 链接到jsfiddle:jsfiddle.net/mhLv7zj1/

$(document).ready(function(){ 
    $(".box").click(function(){
      $(this).next('.open').toggleClass('toggled');
    });
    $(".open").click(function(){
      $(this).toggleClass('toggled');
    });
})

visual example of the final grid state after clicking on a box

3 个答案:

答案 0 :(得分:0)

使用flexflex-basis属性。

$(document).ready(function() {
  $(".box").click(function() {
    $(this).next('.open').toggleClass('toggled');
  });
  $(".open").click(function() {
    $(this).toggleClass('toggled');
  });
})
ul {
  display: flex;
  list-style: none;
  flex-direction: row;
  flex-wrap: wrap;
}

.box {
  background: blue;
  height: 80px;
  flex: 1 1 32%;
  margin-right: 2px;
  margin-bottom: 2px;
}

.open {
  display: none;
  background: red;
  width: 100%;
  height: 80px;
}

.toggled {
  display: flex;
  flex-basis: 66.5%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<ul>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
  <li class="box"></li>
  <li class="open"></li>
</ul>

答案 1 :(得分:0)

这是一种选择。您可以从HTML中删除所有li class="open",而每次点击时都使用此算法:

  • 隐藏/删除任何已经open的项目
  • calculate the number of items in the flex row被点击的项目所在的位置及其位置
  • 然后,您将知道在哪里进行插入,因此:在此行的末尾,动态插入一个open项目(预先设置样式,以便占据整个行({{1} })

答案 2 :(得分:0)

问题在于,红色框是蓝色框的兄弟姐妹,因此当您将它们变成display:block时,它们会推挤其他内容。您需要使红色框成为蓝色框的子元素,并使用相对位置来获得所需的结果。

let boxes = document.querySelectorAll('ul > li');

boxes.forEach(b => {
  b.addEventListener('click', expand.bind(b));
});

function expand() {
  this.querySelector('.open').classList.toggle('visible');
}
ul {
  width: 100%;
  display: flex;
  flex-flow: row wrap;
  list-style-type: none;
  margin: 0;
  padding: 0;
}

li {
  position: relative;
  flex-basis: 33%;
  height: 150px;
  background: blue;
  border: 1px solid white;
}

div.open {
  display: none;
  position: relative;
  top: calc(100% + 1px);
  left: -1px;
  width: calc(300% + 4px);
  height: 150px;
  border: 1px solid white;
  background: red;
  z-index: 1;
}

.visible {
  display: block!important;
}
<ul>
  <li> <div class="open"></div> </li>
  <li> <div class="open"></div> </li>
  <li> <div class="open"></div> </li>
  <li> <div class="open"></div> </li>
  <li> <div class="open"></div> </li>
  <li> <div class="open"></div> </li>
  <li> <div class="open"></div> </li>
  <li> <div class="open"></div> </li>
</ul>

PS。此示例不是完美的代码固定副本,但可以使您走上正确的轨道。