建立可调节的css网格

时间:2015-08-19 20:22:07

标签: html css grid

我正在努力建立"可调节" css网格。我正在制作我的博客,我希望我的新闻能够显示在" blocks"而他们我这样放置: http://pokit.org/get/img/1dfa7b74c6be5bee6c92b886e0b8270b.jpg

而不是像我做的那样here

这是我的代码。
HTML

<div id="wrapper">
    <div class="d_1">1</div>
    <div class="d_2">2</div>
    <div class="d_3">3</div>
    <div class="d_4">4</div>
    <div class="d_5">5</div>
    <div class="d_6">6</div>

</div>

CSS

#wrapper{
    width:200px;

}
#wrapper div{
    background-color:lightgray;
    width:50px;

    float:left;
    margin:0px 5px 5px 0px;
}
.d_1{
    height:60px;
}
.d_2{
    height:30px;
}
.d_3{
    height:33px;
}
.d_4{
    height:70px;
}
.d_5{
    height:60px;
}
.d_6{
    height:40px;
}

5 个答案:

答案 0 :(得分:2)

我认为仅使用一种已知的布局模式(flexbox,grid-layout,inline,...)或使用CSS列,无法获得所需的结果。每个解决方案都会导致不必要的结果。

但是你可以使用CSS网格布局和Javascipt代码的组合来获得结果。

这是包装CSS样式块:

#wrapper{
    width: 200px; /* CSS grid-layout will expand contained divs to cover this size */
    display: grid;
    grid-template-columns: 1fr 1fr 1fr; /* "1fr" for each column */
    grid-column-gap: 10px;
    grid-row-gap: 5px;
}

这是Javascript代码(在#wrapper关闭后添加):

"strict mode";
Array.prototype.max = function() {
    return Math.max.apply(null, this);
};
function compute_gaps(a) {
    let max = a.max();
    return a.map(function(el) {
        return el - max;
    });
}
function compose_gaps(a, b) {
    return b.map(function(el, i) {
        return a[i] + el;
    });
}
var counter = 0;
var columns = 3; // number of columns
var gaps = [];
var heights = [];
for (let el of document.querySelectorAll("#wrapper > div")) {
    let colIdx = counter % columns;
    if (counter % columns === 0) {
        //compute gaps
        if (counter) gaps.push(compute_gaps(heights));
        if (gaps.length > 1) {
        gaps[gaps.length - 1] = compose_gaps(
            gaps[gaps.length - 1],
            gaps[gaps.length - 2]
        );
        }
        heights = [];
    }
    if (gaps.length) {
        el.style.marginTop = gaps[Math.floor(counter / columns - 1)][colIdx];
    }
    heights.push(el.offsetHeight); // apply gap as margin
    counter++;
}

little more complex situationworked in this way中测试代码。

代码在每一行中计算最高块与行中其他行之间的间隙(compute_gaps);之后,将差距应用为CSS margin-top。差距与之前的差距(compose_gaps)相加。

我希望这能回答你的问题。

答案 1 :(得分:0)

如果您不关心旧的浏览器支持(不能使用IE9或更高版本),那么您可以使用CSS3 column-count Property并垂直重新排序div。将其设置为3列:

将此添加到#wrapper

-webkit-column-count: 3;
-webkit-column-fill: auto;
-moz-column-count: 3;
-moz-column-fill: auto;
column-count: 3;
column-fill: auto;

然后将float:left;中的#wrapper div替换为display: inline-block;

这是CODEPEN DEMO

注意:如果浏览器支持和div顺序很重要,那么可以在此StackOverFlow帖子中找到一个优雅的解决方案:how to replicate pinterest.com's absolute div stacking layout

答案 2 :(得分:0)

警告:

我现在不是CSS和JS的佼佼者。在他们工作之前我倾向于暴力。我很确定这不是最好的解决方案,但是,我想发布它以便其他人可以改进它。一旦所有内容都被放入或者可能没有响应,或者可能没有足够动态来解决问题,这可能不起作用,我不知道。我知道,问题的理想外观是通过这种方法实现的,现在没有内容等。

我欢迎任何和所有反馈,为什么这不是最好和/或有什么问题,所以我可以学习。

话虽如此,这里是小提琴:

http://jsfiddle.net/jz4p4Lzk/13/

HTML

<div id="wrapper">
<div class="d_1" id="d1">1</div>
<div class="d_2" id="d2">2</div>
<div class="d_3" id="d3">3</div>
<div class="d_4" id="d4">4</div>
<div class="d_5" id="d5">5</div>
<div class="d_6" id="d6">6</div>

CSS

#wrapper{
    width:200px;
}
#wrapper div{
    background-color:lightgray;
    width:50px;
    position:relative;
    margin:0px 5px 5px 0px;
}
.d_1{
    height:60px;
}
.d_2{
    height:30px;
}
.d_3{
    height:33px;  
} 
.d_4{
    height:70px;
}
.d_5{
    height:60px;
}
.d_6{
    height:40px;
}

JS

var d1 = document.getElementById('d1');
var d1Loc = d1.getBoundingClientRect();
var d2 = document.getElementById('d2');
var d2Loc = d2.getBoundingClientRect();
var d3 = document.getElementById('d3');
var d3Loc = d3.getBoundingClientRect();
var d4 = document.getElementById('d4');
var d4Loc = d4.getBoundingClientRect();
var d5 = document.getElementById('d5'); 
var d5Loc = d5.getBoundingClientRect();
var d6 = document.getElementById('d6');
d2.style.left = d1Loc.right -5+ "px";
d2.style.top = - d1.offsetHeight - 5 + "px";
d3.style.left = d2Loc.right + d1Loc.right -10 +"px";
d3.style.top = - d1.offsetHeight - d2.offsetHeight - 10 + "px";
d4.style.top = - d1.offsetHeight - d2.offsetHeight - d3.offsetHeight + 50 + "px";
d5.style.top =  - d1.offsetHeight - d2.offsetHeight - d3.offsetHeight - d4.offsetHeight + 15 + "px";
d6.style.top = - d1.offsetHeight - d2.offsetHeight - d3.offsetHeight - d4.offsetHeight - d5.offsetHeight +12.5 + "px";
d5.style.left = d4Loc.right  -5+ "px";
d6.style.left = d5Loc.right + d4Loc.right -10 + "px"; 

答案 3 :(得分:0)

你知道有一个真正的&#34; css网格&#34;你可以用吗?它在IE中还没有完成工作(确实如此,但只是在某种程度上),但在所有其他相关的浏览器中它运行良好。基本上,您指定网格线,然后将所需的框放在其中。 我做了一个codepen,所以你可以看到它在行动。 (哦,不需要javascript)

https://codepen.io/quibble/pen/NaKdMo

YML

我很确定这正是你想要的。你甚至可以搞乱数字的顺序(如果你想重新安排你的博客文章或图片),你可以轻松添加更多。你甚至有&#34;网格模板区域:&#34;它允许您准确指定每个项目的去向。没有更多的职位空缺

祝你好运!如果这有帮助,请标记正确。 (P.S.,如果你需要关于网格的更多信息,其中一个非常重视的人(Rachel Andrew)做了一个教程:https://gridbyexample.com/

答案 4 :(得分:0)

这似乎与另一个主题相似:how-create-grid-out-of-images-of-different-sizes

我完全同意@Quibble的观点。 他基本上使用了你想要的布局。我做了一个不同的,它只是有一个不同的方法,虽然区域是更优雅的方式。需要注意的是,您可以通过多种方式实现,其中没有一种涉及基于JS的编码。我的JSfiddle example

.container {
  display: grid;
  padding: 60pt;
  grid-template-columns: 2fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 2fr;
  /* there are five values for five columns, each column gets a relative 
           width in relation to the grid*/
  grid-template-rows: 10% 45% 35% 10%;
  grid-column-gap: 10px;
  grid-row-gap: 5px;
  /*this means there are three rows*/
}

.container div img {
  width: 100%;
  height: 100%;
}

.main_1 {
  grid-column: 2/5;
  grid-row: 2/3;
}

.main_2 {
  grid-column: 5/8;
  grid-row: 2/3;
}

.main_3 {
  grid-column: 8/11;
  grid-row: 2/3;
}

.main_4 {
  grid-column: 2/4;
  grid-row: 3/4;
}

.main_5 {
  grid-column: 4/7;
  grid-row: 3/4;
}

.main_6 {
  grid-column: 7/11;
  grid-row: 3/4;
}

.footer {
  grid-row: 4/5;
  grid-column: 1/6;
}