在元素的居中网格中左对齐的最后一行

时间:2013-10-22 19:55:04

标签: css3 grid-layout css text-align

我在div中设置了一堆相同大小的块,display:inline-block设置text-align:center以对齐块。

|        _____   _____   _____   _____       |
|       |     | |     | |     | |     |      |
|       |  1  | |  2  | |  3  | |  4  |      |
|       |_____| |_____| |_____| |_____|      |
|        _____   _____   _____   _____       |
|       |     | |     | |     | |     |      |
|       |  5  | |  6  | |  7  | |  8  |      |
|       |_____| |_____| |_____| |_____|      |
|                                            |

块水平填充div,随着浏览器窗口缩小,一些块会断开新行,创建更多行和更少列。我希望所有内容仍然保持居中,最后一行与左侧齐平,如下所示:

|        _____   _____   _____        |
|       |     | |     | |     |       |
|       |  1  | |  2  | |  3  |       |
|       |_____| |_____| |_____|       |
|        _____   _____   _____        |
|       |     | |     | |     |       |
|       |  4  | |  5  | |  6  |       |
|       |_____| |_____| |_____|       |
|        _____   _____                |
|       |     | |     |               |
|       |  7  | |  8  |               |
|       |_____| |_____|               |
|                                     |

目前发生的是:

|        _____   _____   _____        |
|       |     | |     | |     |       |
|       |  1  | |  2  | |  3  |       |
|       |_____| |_____| |_____|       |
|        _____   _____   _____        |
|       |     | |     | |     |       |
|       |  4  | |  5  | |  6  |       |
|       |_____| |_____| |_____|       |
|            _____   _____            |
|           |     | |     |           |
|           |  7  | |  8  |           |
|           |_____| |_____|           |
|                                     |

我不能像一个建议那样添加额外的填充div,因为可能有任意数量的块,行数和列数将根据浏览器宽度而有所不同。出于同样的原因,我也不能直接设置块#7。无论有多少列,块必须始终保持居中

这是一支更好地展示的笔:

http://codepen.io/anon/pen/IDsxn

这可能吗?我觉得应该是。我宁愿不使用flexbox,因为它只是ie10 +,我想ie9 +。我真的很喜欢纯CSS解决方案,但如果你告诉我JS是唯一的方法,我很乐意看到它的实际应用。

供参考 - 类似的问题,但没有一个被彻底解释:

How to align left last row/line in multiple line flexbox

CSS - Left align the last row of images in a centered div

Fix centering last line of elements in fluid container grid to be left aligned while container stays centered

Center multiple inline blocks with CSS and align the last row to the left

8 个答案:

答案 0 :(得分:16)

带有显示内联块的解决方案

自适应网格更简单:标记更少,CSS更少,因此在生产网站中实施更容易,并能够适应您的确切需求。

<强> = GT;&GT; DEMO&lt;&lt; = (调整结果窗口大小以查看效果)

&#13;
&#13;
html, body {
    margin:0;
    padding:0;
}
#container{
    font-size:0;
    margin:0 auto;
    width:1000px;
}
.block {
    font-size:20px;
    width: 150px;
    height: 150px;
    margin:25px;
    background: gold;
    display:inline-block;
}

@media screen and (max-width: 430px) {
    #container{
        width:200px;
    }
}

@media screen and (min-width: 431px) and (max-width: 630px) {
   #container{
        width:400px;
    }
}
@media screen and (min-width: 631px) and (max-width: 830px) {
   #container{
        width:600px;
    }
}
@media screen and (min-width: 831px) and (max-width: 1030px) {
   #container{
        width:800px;
    }
}
&#13;
<div id="container">
    <div class="block">1</div>
    <div class="block">2</div>
    <div class="block">3</div>
    <div class="block">4</div>
    <div class="block">5</div>
    <div class="block">6</div>
    <div class="block">7</div>
    <div class="block">8</div>
    <div class="block">9</div>
    <div class="block">10</div>
    <div class="block">11</div>
    <div class="block">12</div>
    <div class="block">13</div>
</div>
&#13;
&#13;
&#13;

涉及:

  1. 4个媒体查询,用于200px宽的块和一个可扩展到1000px的容器。根据网格元素的宽度和容器的总宽度,您可能需要更少或更多

  2. 删除内联块元素之间的空格(在下面的演示中,我使用了字体大小技术,但您可以使用其他技术(请参阅How to remove the space between inline-block elements?了解其他技巧) )

  3. 块之间
  4. 固定边距

  5. 一行中的块数适应容器的大小。 text-align属性保留默认值left,因此最后一项与左侧对齐。


    在块和容器之间具有自适应边距的浮动

    <强> =&GT;&GT; DEMO&lt;&lt; = (您需要在750px下调整结果窗口的大小以查看其运行情况)

    &#13;
    &#13;
    html, body {
        margin:0;
        padding:0;
        min-width:150px;
    }
    .wrap {
        float:left;
        position:relative;
    }
    .foto {
        width: 150px;
        height: 150px;
        background: gold;
        position:absolute;
    }
    
    #warning{display:none;}
    @media screen and (min-width: 631px) {
        .wrap {
            width:20%;
            padding-bottom:25%;
        }
        .wrap:nth-child(4n+2), .wrap:nth-child(4n+3){
            
        }
        .wrap .foto {
            top:-75px;
            margin-top:100%;
            right:-30px;
        }
        .wrap:nth-child(4n+2){
            margin:0 5% 0 7.5%;
        }
        .wrap:nth-child(4n+3){
         margin-right:7.5%;
        }
        .wrap:nth-child(4n+2) .foto{
            left:50%;
            margin-left:-75px;
        }
        .wrap:nth-child(4n+3) .foto{
            right:50%;
            margin-right:-75px;
        }
        .wrap:nth-child(4n) .foto{
            left:-30px;
        }   
        #container{
            margin-top:-45px;
        }
    }
    
    @media screen and (min-width: 481px) and (max-width: 631px) {
        .wrap {
            width:25%;
            padding-bottom:33.3%;
        }
        .wrap:nth-child(3n+2){
            margin:0 12.5%;        
        }
        .wrap .foto {
            top:-75px;
            margin-top:100%;
            right:-37px;
        }
         .wrap:nth-child(3n+2) .foto{
            left:50%;
            margin-left:-75px;
        }
         .wrap:nth-child(3n) .foto{
            left:-37px;
        }
        #container{
            margin-top:-37px;
        }
    }
    
    
    @media screen and (min-width: 331px) and (max-width: 480px) {
        .wrap {
            width:33.3%;
            padding-bottom:50%;
            clear:left;
        }
        .wrap:nth-child(even) {
            float:right;
            clear:right;
        }
        .wrap .foto {
            top:-75px;
            margin-top:100%;
            right:-50px;
        }
        .wrap:nth-child(even) .foto {
            left:-50px;
        }
        .wrap:nth-child(4n+3) .foto, .wrap:nth-child(4n+4) .foto {
            bottom:-75px;
            margin-bottom:100%;
        }
        #container{
            margin-top:-25px;
        }
    }
    
    
    @media screen and (max-width: 330px) {
        .wrap {
            width:50%;
            padding-bottom:100%;
            clear:left;
        }
        .wrap:nth-child(odd) .foto {
            right:-75px;
            bottom:0;
            bottom:-75px;
            margin-bottom:100%;
        }
        .wrap:nth-child(even) .foto {
            top:0px;
            right:-75px;
            top:-75px;
            margin-top:100%;
        }
    }
    
    @media screen and (min-width: 751px) {
        #warning{
            color:#fff;
            display:block;
            position:fixed;
            width:100%;
            height:50%;
            top:25%;
            left:0;
            background:#000;
            text-align:center;
            font-size:30px;
    }
    &#13;
    <div id="container">
        <div class="wrap"><div class="foto">1</div></div>
        <div class="wrap"><div class="foto">2</div></div>
        <div class="wrap"><div class="foto">3</div></div>
        <div class="wrap"><div class="foto">4</div></div>
        <div class="wrap"><div class="foto">5</div></div>
        <div class="wrap"><div class="foto">6</div></div>
        <div class="wrap"><div class="foto">7</div></div>
        <div class="wrap"><div class="foto">8</div></div>
        <div class="wrap"><div class="foto">9</div></div>
        <div class="wrap"><div class="foto">10</div></div>
        <div class="wrap"><div class="foto">11</div></div>
        <div class="wrap"><div class="foto">12</div></div>
        <div class="wrap"><div class="foto">13</div></div>
        <div class="wrap"><div class="foto">14</div></div>
        <div class="wrap"><div class="foto">15</div></div>
    </div>
    
    <!-- FOLLOWING JUST FOR THE DEMO -->
    <div id="warning">I haven't written the code for windows bigger than 751px.<br/>
        You must resize this window under 751px.</div>
    &#13;
    &#13;
    &#13;

    这项技术涉及:

    1. position:absolute;
    2. :nt-child() css选择器
    3. 媒体查询
    4. 它将块放在容器中心,并在容器的所有块+侧面的顶部/左侧/紧/底部给出相同的边距。由于此解决方案使用浮点数,因此最后一行与左侧对齐。

      一行中的块数适应窗口的宽度。

答案 1 :(得分:12)

这是一个非常简单的JavaScript(以及CSS中的一些小变化)解决方案:

http://jsfiddle.net/ha68t/

这对我来说很好。

<强> CSS:

.container {
  margin: 0 auto;
  max-width:960px;
  background-color: gold;
}

.block {
  background-color: #ddd;
  border:1px solid #999;
  display: block;
  float: left;
  height: 100px;
  margin: 4px 2px;
  width: 100px;
}

<强> JavaScript的:

$(document).ready(function(){
    setContainerWidth();
});

$(window).resize(function(){
   setContainerWidth();
});

function setContainerWidth()
{
    $('.container').css('width', 'auto'); //reset
    var windowWidth = $(document).width();
    var blockWidth = $('.block').outerWidth(true);
    var maxBoxPerRow = Math.floor(windowWidth / blockWidth);
    $('.container').width(maxBoxPerRow * blockWidth);
}

需要jQuery:)

答案 2 :(得分:9)

它的价值是什么:它现在是2017年而grid layout module开箱即用

&#13;
&#13;
* {
    margin:0;
    padding:0;
}

.container {
  display: grid;
  grid-template-columns: repeat(auto-fill, 100px);
  grid-gap: 10px;
  justify-content: center;
  align-content: flex-start;
  margin: 0 auto;
  text-align: center;
  margin-top: 10px;
}
.block {
  background-color: #ddd;
  border: 1px solid #999;
  height: 100px;
  width: 100px;
}
&#13;
<div class="container">
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
  <div class="block">Foo</div>
</div>
&#13;
&#13;
&#13;

(Codepen demo)

如果browser support适合你 - 那么使用网格。如果没有,请继续阅读......


正如在@Web-tiki的回答中所提到的,使用CSS可以做的最好的事情是使用一系列媒体查询。

话虽如此,如果您使用的是LESS之类的预处理器 - 这不是一个如此困难或容易出错的任务。 (虽然,是的,CSS仍然会很长很难看)

UPDATED CODEPEN (调整窗口大小以查看结果)

以下是如何利用LESS设置媒体查询:

首先根据您需要的设计设置一些较少的变量:

@item-width:100px;
@item-height:100px;
@marginV: 4px;
@marginH: 2px;
@min-cols:2;
@max-cols:9; //set an upper limit of how may columns you want to write the media queries for

然后:

设置这样的迭代混合:(您可以将此代码粘贴到http://less2css.org

.loopingClass (@index-width) when (@index-width <= @item-width * @max-cols) {
    @media (min-width:@index-width) {
        .container{
            width: @index-width;
        }
    }

    .loopingClass(@index-width + @item-width + 2*@marginH);
}

.loopingClass (@item-width * @min-cols + @min-cols*@marginH*2);

上述mixin将以以下形式吐出一系列媒体查询:

@media (min-width: 208px) {
  .container {
    width: 208px;
  }
}
@media (min-width: 312px) {
  .container {
    width: 312px;
  }
}
@media (min-width: 416px) {
  .container {
    width: 416px;
  }
}
@media (min-width: 520px) {
  .container {
    width: 520px;
  }
}
@media (min-width: 624px) {
  .container {
    width: 624px;
  }
}
@media (min-width: 728px) {
  .container {
    width: 728px;
  }
}
@media (min-width: 832px) {
  .container {
    width: 832px;
  }
}

剩下的CSS(LESS):

.container {
  margin: 0 auto;
  text-align: center;
  overflow: auto;
    min-width: @min-cols * @item-width;
    max-width: @max-cols * @item-width;
    display: block;
    list-style:none;
}
.block {
  background-color: #ddd;
  border:1px solid #999;
  box-sizing:border-box;
  float: left;
  height: @item-height;
  width: @item-width;
  margin:@marginV @marginH;
}

...你得到了理想的结果。

...它可以非常轻松地自定义布局:

我需要做的就是根据我的需要更改我在LESS mixin中使用的变量 - 我得到了我之后的确切布局。

答案 3 :(得分:2)

使用flexbox,一些伪元素,一个额外的div,经过很多挫折,我能够在没有媒体查询的情况下实现这一点(因为我需要将网格放在许多不同大小的元素中,媒体查询不会真的为我工作)。

一个警告:物品之间的排水沟是流动的。

演示:http://codepen.io/anon/pen/OXvxEW

CSS:

.wrapper {
    display: flex;
    flex-wrap: wrap;
    border: 2px solid #ffc0cb;
    max-width: 1100px;
    margin: 0.5rem auto;
    justify-content: center;
}

.wrapper:after {
    content: ' ';
    flex: 1;
    height: 100%;
    border: 1px solid #00f;
    margin: 0.5rem;
}

.child {
    flex: 1;
    border: 2px solid #ffa500;
    min-width: 300px;
    margin: 0.5rem;
    text-align: center;
}

.child-contents {
    width: 300px;
    border: 2px solid #008000;
    height: 100px;
    margin: 0 auto;
}

HTML:

<div class='wrapper'>
    <div class='child'>
        <div class='child-contents'></div>
    </div>
    <div class='child'>
        <div class='child-contents'></div>
    </div>
    <div class='child'>
        <div class='child-contents'></div>
    </div>

    ...etc., more .child's...

</div>

最终结果是这样的,绿色矩形是div。粉色/橙色边框仅供参考,因此您可以看到正在发生的事情。如果你删除粉红色/橙色边框,你应该得到你正在寻找的网格(但是再次注意,排水沟是流动的)。

enter image description here

答案 4 :(得分:1)

使用flexbox:

.container {
  display: -webkit-flex;
   display: flex;
   -webkit-flex-direction: row; 
   flex-direction: row;
   -webkit-justify-content: flex-start;
   justify-content: flex-start;
   flex-wrap:wrap;
}

.block {
  background-color: #ddd;
  border:1px solid #999;
  display: inline-block;
  height: 100px;
  margin: 4px 2px;
  width: 100px;
}

完成。

答案 5 :(得分:1)

尝试使用简单的css:

CSS:

.row {文本对齐:中心;字体大小:0;} .block {文本对齐:中心;显示:内联块;宽度:150像素;高度:15像素;边缘:5像素; border:1px solid #dddddd; font-size:13px;}

HTML:

<div class="row">
  <div class="block"></div> 
</div>

.row{text-align:center;font-size:0;}
    .block{text-align:center;display:inline-block;width:150px;height:150px;margin:5px; border:1px solid #dddddd;font-size:13px;line-height:150px;}
<div class="row">
      <div class="block">1</div> 
      <div class="block">2</div> 
      <div class="block">3</div> 
      <div class="block">4</div> 
      <div class="block">5</div> 
      <div class="block">6</div> 
      <div class="block">7</div> 
      <div class="block">8</div> 
    </div>

答案 6 :(得分:1)

到目前为止,唯一干净的解决方案是使用

CSS Grid Layout ModuleCodepen demo

基本上相关的代码必须归结为:

ul {
  display: grid; /* (1) */
  grid-template-columns: repeat(auto-fill, 120px); /* (2) */
  grid-gap: 1rem; /* (3) */
  justify-content: center; /* (4) */
  align-content: flex-start; /* (5) */
}

1)使容器元素成为网格容器

2)使用宽度为120px的“自动”列数设置网格。 (自动填充值用于响应式布局)。

3)设置网格行和列的间隙/沟槽。

4)和5) - 与flexbox类似。

body {
  margin: 0;
}
ul {
  display: grid;
  grid-template-columns: repeat(auto-fill, 120px);
  grid-gap: 1rem;
  justify-content: center;
  align-content: flex-start;
  
  /* boring properties: */
  list-style: none;
  width: 90vw;
  height: 90vh;
  margin: 2vh auto;
  border: 5px solid green;
  padding: 0;
  overflow: auto;
}
li {
  background: tomato;
  height: 120px;
}
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
  <li>5</li>
  <li>6</li>
  <li>7</li>
  <li>8</li>
  <li>9</li>
  <li>10</li>
</ul>

Codepen demo(调整大小以查看效果)

<小时/>

浏览器支持 - Caniuse

目前受Chrome(Blink)和Firefox的支持,得到IE和Edge的部分支持(见Rachel Andrew的this post

进一步阅读CSS网格:

答案 7 :(得分:0)

没有&#34;正常&#34;解决您的问题,但只提到了#34;解决方法&#34;。

情况是,您的容器块将填充可用空间,直到最大可用/设置,然后将所有内部块拆分到下一行,这将导致容器溢出。还有其他配置,如浮动,它将是相同的行为。这就是渲染的工作方式 - 每次贪婪地计算内部元素的行为。

也许未来Flexboxes会使这成为可能 - 但我没有阅读完整的规格。只是一个猜测...