在网格中对齐具有不同高度的项目,并使它们与对齐线匹配

时间:2017-08-16 18:00:04

标签: html css layout grid-layout

我想创建一个页面,其中我的元素显示在网格中。我想逐行对齐项目。 我希望直观地获得以下结果,但我不知道如何:https://codepen.io/shirkit/pen/KvZKOE/

我现在有这个:



var back = ["red","blue","gray","black","green","cyan","brown","magenta"];
var i = 0;

$('#container .card').children().each(function() {
 $(this).css('background-color',back[i++]);
 if (i == back.length) i = 0;
});

#container {
 display: flex;
 flex-direction: row;
}

.card {
 max-width: 200px;
  width: 100%;
}

.card .image {
 height: 150px;
}

.card .text {
 height: 100px;
}

.card .list {
 height: 50px;
}

#z1 .image {
  height: 175px;
}

#z2 .text {
  height: 120px;
}

#z3 .list {
  height: 60px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
 <div id="z1" class="card">
  <div class="image"></div>
  <div class="text"></div>
  <div class="list"></div>
 </div>
 <div id="z2" class="card">
  <div class="image"></div>
  <div class="text"></div>
  <div class="list"></div>
 </div>
 <div id="z3" class="card">
  <div class="image"></div>
  <div class="text"></div>
  <div class="list"></div>
 </div>
</div>
&#13;
&#13;
&#13;

澄清:ID选择器#z1 .image, #z2.text #z3 .list的高度仅用于模拟组件的高度。因此,它不是更改这些值的选项。另请注意,这些元素/容器的高度值不是预先知道的,因此设置边距也不是一种选择。

显示的当前代码不是当前的代码,它只是用于显示目前的视觉效果,但它应遵循该结构,container用于所有内容,{{1对于元素和卡内的项目。

如果我不将这些项目放在card元素中,然后使用.card中的CSS display: grid,我现在知道如何执行此操作。我会将#container元素作为来自.image/.text/.list的直接孩子,但这是最后的手段,我想要一个替代方案。

我目前正在寻找一种解决方案,允许我保留#container元素,并可能有后备。

编辑:标记为重复的建议答案并不能解决我在此处提出的问题,或者我找不到任何其他相关内容。

4 个答案:

答案 0 :(得分:3)

使用您当前的HTML结构,我不熟悉任何纯CSS方法来实现您的最终结果。关键问题是每个相邻列中的各个元素无法将自己与周围环境联系起来。如果您的单元格是水平的,我们可以使用像table-row这样的CSS - 因为“单元格是行的后代,而不是列的后代”。 (W3

话虽如此,你没有提到你正在寻找一个纯CSS解决方案,而且你已经在使用jQuery,我认为这将是一个很好的解决方案,可以在实现所需的布局时保持HTML结构。

在下面的代码中,我正在遍历每组组件(图像,文本,列表),以确定哪张卡片各有一张最高的卡片,然后在每张卡片上使用margin-bottom隔开其他卡片。更短的组件,使它们相等。

var back = ["red", "blue", "gray", "black", "green", "cyan", "brown", "magenta"];
var i = 0;

$('#container .card').children().each(function() {
  $(this).css('background-color', back[i++]);
  if (i == back.length) i = 0;
});

var components = ['image', 'text', 'list'];
$.each(components, function(i, j) {
  var $elements = $('.card .' + j);
  var heights = [];
  var tallest = 0;

  $elements.each(function(i) {
    var height = $(this).height();
    heights[i] = height;
    if (height > tallest) {
      tallest = height;
    }
  });

  $.each(heights, function(i, j) {
    var diff = tallest - j;
    if (diff) {
      $elements.eq(i).css('margin-bottom', diff);
    }
  });
});
#container {
  display: flex;
}

.card {
  max-width: 200px;
  width: 100%;
}

.card .image {
  height: 150px;
}

.card .text {
  height: 100px;
}

.card .list {
  height: 50px;
}

#z1 .image {
  height: 175px;
}

#z2 .text {
  height: 120px;
}

#z3 .list {
  height: 60px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
  <div id="z1" class="card">
    <div class="image"></div>
    <div class="text"></div>
    <div class="list"></div>
  </div>
  <div id="z2" class="card">
    <div class="image"></div>
    <div class="text"></div>
    <div class="list"></div>
  </div>
  <div id="z3" class="card">
    <div class="image"></div>
    <div class="text"></div>
    <div class="list"></div>
  </div>
</div>

答案 1 :(得分:0)

1,2

这是您所需输出的CSS。 但是你应该使用它的推荐的jquery 你想要纯粹的CSS这就是它。

答案 2 :(得分:0)

而不是代码

<style type="text/css">
#z1 .image {
  height: 175px; 
}
#z2 .text {
  height: 120px;
}
#z3 .list {
  height: 60px;
}
</style>

使用此代码

<style type="text/css">
#z1 .image {
  height: auto; 
}
#z2 .text {
  height: auto;
}
#z3 .list {
  height: auto;
}
</style>

答案 3 :(得分:0)

为此使用砌体布局,例如https://masonry.desandro.com/。它将通过一些JS帮助实现下面的布局。使用纯CSS可能无法实现完全跨浏览器的解决方案,尤其是当您尝试使用flexbox

Masonry layout sample