【问题标题】:Building adjustable css grid构建可调整的 CSS 网格
【发布时间】:2017-10-08 20:26:11
【问题描述】:

我正在尝试构建“可调整”的 CSS 网格。我正在制作我的博客,我希望我的新闻以“块”的形式显示,并且它们是这样放置的: 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;
}

【问题讨论】:

  • "一个左浮动的盒子会向左移动,直到它最左边的边距边缘(如果没有边距,或者是边框边缘)接触到包含块的边缘,或者 另一个的边缘浮动框" - smashingmagazine.com/2009/10/the-mystery-of-css-float-property 框 4 在到达左边距之前与框 1 发生碰撞。如果您翻转 2 和 3 的高度,您会看到框 4 停在框 2 而不是框 1。它从框 3 的底部开始并开始向左滑动,直到碰到什么东西。我希望看到解决此问题的解决方案。
  • 是否有网站显示您分享的演示照片的工作版本?如果是这样,请分享,我们可以查看该代码并复制。
  • 我没有演示给你看,我正在自己构建博客。对不起
  • @Riki 你在其他地方见过这种做法吗?
  • @hopkins-matt 我不这么认为,我只是想出了这个主意,我不知道怎么做,所以我想你们中的一些人有一些想法可以帮助我

标签: html css grid


【解决方案1】:

我认为仅仅使用一种已知的布局模式(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 边距顶部。差距与之前的差距相加 (compose_gaps)。

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

【讨论】:

    【解决方案2】:

    警告:

    我现在不是最擅长 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"; 
    

    【讨论】:

    • 这很好,但问题就在这里。在我的博客上,我会有很多这样的“块”,不仅仅是 6 个或 4 个。此外,我添加类只是因为我想为每个 div 分配不同的高度,但在我的页面上,div 的高度将等于图像in. 可以这样制作,使其不仅适用于 6,而且适用于无限 div?非常感谢
    【解决方案3】:

    如果您不关心旧浏览器的支持(不适用于 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;
    

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

    这是CODEPEN DEMO


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

    【讨论】:

    【解决方案4】:

    您知道您可以使用一个实际的“css 网格”吗?它在 IE 中还不能很好地工作(它可以,但只是在某种程度上),但在所有其他相关的浏览器中它工作得很好。基本上,您指定网格线,然后在其中放置您想要的框。 我做了一个codepen,所以你可以看到它的实际效果。 (哦,不需要 javascript)

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

    #wrapper{
      display:grid;
      grid-gap:10px;
      grid-template-columns:50px 50px 50px;
      grid-template-rows: 30px 3px 27px 13px 17px 40px; /*the pixels add up to the corresponding bottoms of each grid container. There are a few ways to do this but I like this one.*/
      grid-template-areas:
        /*This allows you to specify which grid blocks go where. Notice that some are repeated, this just means they span two or more grid areas. For example, box 3 is 33 px so must span one column and two rows (the 30 and 3px one)*/
        "one two three"
        "one five three"
        "one five six"
        "four five six"
        "four five ."
        "four . .";/* the . is for a blank gridspace */
    }
    #wrapper>div{
      background-color:gray;
    }
    .d_1{
      grid-area:one;
    }
    .d_2{
      grid-area:two;
    }
    .d_3{
      grid-area:three;
    }
    .d_4{
      grid-area:four;
    }
    .d_5{
      grid-area:five;
    }
    .d_6{
      grid-area:six;
    }
    

    我很确定这正是您想要的。您甚至可以随意调整数字的顺序(以防您想重新排列博客文章或图片),并且可以更轻松地添加。您甚至还有“grid-template-areas:”,它允许您准确指定每个项目的去向。没有更多针对位置的黑客攻击

    祝你好运!如果这有帮助,请标记正确。 (P.S.,如果您需要有关网格的更多信息,其中一位大力推动它的人(Rachel Andrew)制作了一个教程:https://gridbyexample.com/

    【讨论】:

      【解决方案5】:

      这似乎与另一个主题相似: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;
      }
      

      【讨论】:

        猜你喜欢
        • 2022-01-18
        • 2021-05-30
        • 1970-01-01
        • 1970-01-01
        • 2021-02-07
        • 1970-01-01
        • 1970-01-01
        • 2021-04-05
        • 1970-01-01
        相关资源
        最近更新 更多