首页 文章

弹性框:将最后一行与网格对齐

提问于
浏览
267

我有一个简单的flex-box布局,其容器如下:

.grid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

现在我希望最后一行中的项目与另一行对齐 . 应使用 justify-content: space-between; ,因为可以调整网格的宽度和高度 .

目前它看起来像

The item in the bottom right should be in the middle

在这里,我希望右下角的项目位于"middle column"中 . 实现这一目标的最简单方法是什么?这是一个显示此行为的小jsfiddle .

.exposegrid {
  display: flex;
  flex-flow: row wrap;
  justify-content: space-between;
}

.exposetab {
  width: 100px;
  height: 66px;
  background-color: rgba(255, 255, 255, 0.2);
  border: 1px solid rgba(0, 0, 0, 0.4);
  border-radius: 5px;
  box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.2);
  margin-bottom: 10px;
}
<div class="exposegrid">
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
  <div class="exposetab"></div>
</div>

23 回答

  • 22

    添加自动填充空间的::after . 无需污染您的HTML . 这是一个显示它的codepen:http://codepen.io/DanAndreasson/pen/ZQXLXj

    .grid {
      display: flex;
      flex-flow: row wrap;
      justify-content: space-between;
    }
    
    .grid::after {
      content: "";
      flex: auto;
    }
    
  • 43

    一种技术是插入一些给定零高度的额外元素(与您预期的最大元素数一样多) . 空间仍然存在分歧,但多余的行崩溃为空:

    http://codepen.io/dalgard/pen/Dbnus

    body {
      padding: 5%;
    }
    
    div {
      overflow: hidden;
      background-color: yellow;
    }
    
    ul {
      display: flex;
      flex-wrap: wrap;
      margin: 0 -4px -4px 0;
      list-style: none;
      padding: 0;
    }
    
    li {
      flex: 1 0 200px;
      height: 200px;
      border-right: 4px solid black;
      border-bottom: 4px solid black;
      background-color: deeppink;
    }
    li:empty {
      height: 0;
      border: none;
    }
    
    *,
    :before,
    :after {
      box-sizing: border-box;
    }
    
    <div>
      <ul>
        <li>a</li>
        <li>b</li>
        <li>c</li>
        <li>d</li>
        <li>e</li>
        <li>f</li>
        <li>g</li>
        <li>h</li>
        <li>i</li>
        <li>j</li>
        <li>k</li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
      </ul>
    </div>
    

    将来,通过使用多个::after(n)可以实现这一点 .

  • 13

    正如其他海报所提到的那样 - 没有干净的方法将最后一行与flexbox对齐(至少根据当前规范)

    然而,对于它的 Value :使用CSS Grid Layout Module这非常容易 生产环境 :

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

    ul {
      display: grid; /* 1 */
      grid-template-columns: repeat(auto-fill, 100px); /* 2 */
      grid-gap: 1rem; /* 3 */
      justify-content: space-between; /* 4 */
    }
    

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

    2)使用宽度为100px的自动列设置网格 . (注意使用auto-fill(与 auto-fit 一起使用 - 对于1行布局)将空轨道折叠为0 - 导致项目展开以占用剩余空间 . 这将导致网格具有合理的'space-between'布局只有一行在我们的情况下不是我们想要的 . (查看this demo以查看它们之间的区别)) .

    3)设置网格行和列的间隙/檐槽 - 这里,因为需要'间隔'布局 - 间隙实际上是最小间隙,因为它将根据需要增长 .

    4)类似于flexbox .

    ul {
      display: grid;
      grid-template-columns: repeat(auto-fill, 100px);
      grid-gap: 1rem;
      justify-content: space-between;
      
      /* boring properties */
      list-style: none;
      background: wheat;
      padding: 2rem;
      width: 80vw;
      margin: 0 auto;
    }
    
    li {
      height: 50px;
      border: 1px solid green;
    }
    
    <ul>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
    

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

  • 0

    没有任何额外的标记,只需添加 ::after 为我指定列的宽度 .

    .grid {
      display:flex;
      justify-content:space-between;
      flex-wrap:wrap;
    }
    .grid::after{
      content: '';
      width: 10em // Same width of .grid__element
    }
    .grid__element{
      width:10em;
    }
    

    使用这样的HTML:

    <div class=grid">
       <div class="grid__element"></div>
       <div class="grid__element"></div>
       <div class="grid__element"></div>
    </div>
    
  • 135

    你可以't. Flexbox is not a grid system. It does not have the language constructs to do what you'要求,至少不是你正在使用 justify-content: space-between . 使用Flexbox最接近的是使用列方向,这需要设置显式高度:

    http://cssdeck.com/labs/pvsn6t4z(注意:前缀不包括在内)

    ul {
      display: flex;
      flex-flow: column wrap;
      align-content: space-between;
      height: 4em;
    }
    

    但是,使用具有更好支撑但不需要设置特定高度的列会更简单:

    http://cssdeck.com/labs/dwq3x6vr(注意:前缀不包括在内)

    ul {
      columns: 15em;
    }
    
  • 2

    如果你想要一个网格,在项目和项目之间有一些空间而没有任何初始空间,那么这个简单的解决方案就可以了:

    .grid {
        display: flex;
        flex-flow: row wrap;
        margin: 0 -5px; // remove the inital 5px space
        width: auto;
    }
    .grid__item {
        width: 25%;
        padding: 0 5px; // should be same as the negative margin above.
    }
    

    如果你想要最初的5px空间,那么只需删除负边距:)简单 .

    接受的答案虽然很好,但却导致第二排元素之间没有空格 .

  • 1

    一种可能的解决方案是在 .grid 容器上使用 justify-content: flex-start; ,对其子项使用大小限制,并在相应的子元素上使用边距 - 具体取决于所需的列数 .

    对于3列网格,基本CSS将如下所示:

    .grid {
        display: flex;
        flex-flow: row wrap;
        justify-content: flex-start;
    }
    
    .grid > * {
        flex: 0 0 32%;
        margin: 1% 0;
    }
    
    .grid > :nth-child(3n-1) {
        margin-left: 2%;
        margin-right: 2%;
    }
    

    这是另一个不完美的解决方案,但它确实有效 .

    http://codepen.io/tuxsudo/pen/VYERQJ

  • 0

    如果要将最后一项与网格对齐,请使用以下代码:

    Grid container

    .card-grid {
      box-sizing: border-box;
      max-height: 100%;
      display: flex;
      flex-direction: row;
      -webkit-box-orient: horizontal;
      -webkit-box-direction: normal;
      justify-content: space-between;
      align-items: stretch;
      align-content: stretch;
      -webkit-box-align: stretch;
      -webkit-box-orient: horizontal;
      -webkit-box-direction: normal;
      -ms-flex-flow: row wrap;
      flex-flow: row wrap;
    }
    
    .card-grid:after {
      content: "";
      flex: 1 1 100%;
      max-width: 32%;
    }
    

    Item in the grid

    .card {
      flex: 1 1 100%;
      box-sizing: border-box;
      -webkit-box-flex: 1;
      max-width: 32%;
      display: block;
      position: relative;
    
    }
    

    诀窍是将项目的最大宽度设置为等于.card-grid的最大宽度:after .

    Live demo on Codepen

  • 1

    可以使用“flex-start”并手动添加边距 . 它需要一些数学黑客攻击,但是很容易做到,并且很容易使用像LESS这样的CSS预处理器 .

    例如,请参阅此LESS mixin:

    .flexboxGridMixin(@columnNumber,@spacingPercent) {
      @contentPercent: 100% - @spacingPercent;
      @sideMargin: @spacingPercent/(@columnNumber*2);
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      justify-content: flex-start;
      > * {
        box-sizing: border-box;
        width: @contentPercent/@columnNumber;
        margin-left: @sideMargin;
        margin-right: @sideMargin;
      }
    }
    

    然后它可以很容易地用于显示响应式网格布局:

    ul {
      list-style: none;
      padding: 0;
      @spacing: 10%;
      @media only screen and (max-width: 499px) { .flexboxGridMixin(1,@spacing); }
      @media only screen and (min-width: 500px) { .flexboxGridMixin(2,@spacing); }
      @media only screen and (min-width: 700px) { .flexboxGridMixin(3,@spacing); }
      @media only screen and (min-width: 900px) { .flexboxGridMixin(4,@spacing); }
      @media only screen and (min-width: 1100px) { .flexboxGridMixin(5,@spacing); }
    }
    
    li {
      background: pink;
      height: 100px;
      margin-top: 20px;
    }
    

    这是一个例子

    http://codepen.io/anon/pen/YyLqVB?editors=110

  • -5

    是 . !我们可以通过一些媒体查询和 Maximum no of columns are predefined .

    这里使用4列 . 检查我的代码:

    .container {
      display: flex;
      display: -webkit-flex;
      display: -moz-flex;
      flex-flow: row wrap;
      -webkit-flex-flow: row wrap;
      -moz-flex-flow: row wrap;
    }
    
    .container .item {
      display: flex;
      display: -webkit-flex;
      display: -moz-flex;
      justify-content: center;
      -webkit-justify-content: center;
      -moz-justify-content: center;
      flex-basis: 25%; //max no of columns in %, 25% = 4 Columns
    }
    
    .container .item .item-child {
      width: 130px;
      height: 180px;
      background: red;
      margin: 10px;
    }
    
    @media (max-width: 360px) {
      .container .item {
        flex-basis: 100%;
      }
    }
    
    @media (min-width:360px) and (max-width: 520px) {
      .container .item {
        flex-basis: 50%;
      }
    }
    
    @media (min-width:520px) and (max-width: 680px) {
      .container .item {
        flex-basis: 33.33%;
      }
    }
    
    <div class="container">
    
      <div class="item">
        <div class="item-child">1</div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
      <div class="item">
        <div class="item-child"></div>
      </div>
    
    </div>
    

    NOTE
    1)无需创建子div . 它可能是任何其他标签,如'img' r,无论你想要什么..
    2)如果您想要更多列,请调整媒体查询和最大列数 .

  • 7

    此版本是具有固定宽度的块的最佳方式:

    http://codepen.io/7iomka/pen/oxxeNE

    在其他情况下 - 版本的dalgard

    http://codepen.io/dalgard/pen/Dbnus

    body {
      padding: 5%;
    }
    
    div {
      overflow: hidden;
      background-color: yellow;
    }
    
    ul {
      display: flex;
      flex-wrap: wrap;
    justify-content:center;
      margin: 0 -4px -4px 0;
      list-style: none;
      padding: 0;
    }
    
    li {
      flex: 1 0 200px;
      height: 200px;
      max-width:200px;
      min-width:200px;
      border-right: 4px solid black;
      border-bottom: 4px solid black;
      background-color: deeppink;
    }
    li:empty {
      height: 0;
      border: none;
    }
    
    *,
    :before,
    :after {
      box-sizing: border-box;
    }
    
    <div>
      <ul>
        <li>a</li>
        <li>b</li>
        <li>c</li>
        <li>d</li>
        <li>e</li>
        <li>f</li>
        <li>g</li>
        <li>h</li>
        <li>i</li>
        <li>j</li>
        <li>k</li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
      </ul>
    </div>
    
  • 0

    似乎没有人在最后一项上提出flex-grow解决方案 . 我们的想法是让你的最后一个flex项目使用flex-grow来占据它所有的位置:1 .

    .grid {
      display: flex;
      flex-flow: row wrap;
      justify-content: space-between;
    }
    
    .grid > *:last-child {
      flex-grow: 1;
    }
    

    注意:此解决方案并不完美,尤其是如果您在Flex项目中设置了居中元素,因为它将以可能巨大的最后一个弹性项目为中心 .

  • 1

    这是很多答案的组合,但它完全符合我的需要 - 也就是说,将Flex容器中的最后一个子节点与在保持空间行为的同时离开(在这种情况下,它是一个三列布局) .

    这是标记:

    .flex-container {
      display: flex;
      justify-content: space-between;
      flex-direction: row;
    }
    
    .flex-container:after {
      content: "";
      flex-basis: 30%;
    }
    
  • 1

    您只需使用flex-start和max-width即可实现此目的 .

    https://codepen.io/moladukes/pen/NvzBrQ

    .container {
      display: flex;
      justify-content: flex-start;
      flex-flow: row wrap;
    }
    
    .item { 
      width: 130px; 
      max-width: 130px; 
      height: 180px; 
      background: red; 
      margin: 20px; 
    }
    
  • 5

    每个答案都是如此错误 . 甚至294赞成(丹安德森) .

    你想 align

    使用 align-content: flex-start; 而不是 justify-content: space-between;

    这将物品的最后一行拉到左边,并且均匀分布空间,

    .container {
      display: flex;
      flex-flow: row wrap;
      align-content: flex-start;
      /*justify-content: space-between; remove this line!!!! */ 
    }
    

    https://codepen.io/anon/pen/aQggBW?editors=1100

  • 0

    有一种没有flexbox的方法,虽然你需要满足以下条件 . 1)容器有衬垫 . 2)项目大小相同,您确切地知道每行的数量 .

    ul {
      padding: 0 3% 0 5%;
    }
    li {
      display: inline-block; 
      padding: 0 2% 2% 0;
      width: 28.66%;
    }
    

    容器右侧的较小填充允许在每个列表项的右侧添加额外的填充 . 假设与列表对象在同一父级中的其他项用0 5%填充,则它们将与它们齐平 . 您还可以将百分比调整为您想要的多少余量或使用计算px值 .

    当然,你可以在没有填充容器的情况下使用nth-child(IE 9)来删除第三个盒子上的边距 .

  • 1

    使用flexbox和一些媒体查询,我做了一点点解决方法:http://codepen.io/una/pen/yNEGjv(它有点hacky但有效):

    .container {
      display: flex;
      flex-flow: row wrap;
      justify-content: flex-start;
      max-width: 1200px;
      margin: 0 auto;
    }
    
    .item {
      background-color: gray;
      height: 300px;
      flex: 0 30%;
      margin: 10px;
    
      @media (max-width: 700px) {
         flex: 0 45%;
      }
    
      @media (max-width: 420px) {
        flex: 0 100%;
      }
    
      &:nth-child(3n-1) {
        margin-left: 10px;
        margin-right: 10px;
      }
    }
    
  • 0

    我为它做了一个SCSS mixin .

    @mixin last-row-flexbox($num-columns, $width-items){
    
      $filled-space: $width-items * $num-columns;
      $margin: calc((100% - #{$filled-space}) / (#{$num-columns} - 1));
    
      $num-cols-1 : $num-columns - 1;
    
      &:nth-child(#{$num-columns}n+1):nth-last-child(-n+#{$num-cols-1}) ~ & {
        margin-left: $margin;
      }
      @for $i from 1 through $num-columns - 2 { 
        $index: $num-columns - $i;
        &:nth-child(#{$num-columns}n+#{$index}):last-child{
          margin-right: auto;
        }
      }
    }
    

    这是codepen链接:http://codepen.io/diana_aceves/pen/KVGNZg

    您只需要以百分比和列数设置项目宽度 .

    我希望这可以帮到你 .

  • 297

    这是另外几个scss mixins .

    这些mixins假设您不会使用像Isotope这样的js插件(他们不尊重html标记顺序,因此搞乱了css nth规则) .

    此外,您将能够充分利用它们,特别是如果您以移动设备方式编写响应断点 . 理想情况下,您将在较小的断点上使用flexbox_grid(),并在以下断点上使用flexbox_cell() . flexbox_cell()将负责重置以前设置的边距,不再用于较大的断点 .

    顺便说一句,只要你正确设置容器的flex属性,如果需要,你也可以只在项目上使用flexbox_cell() .

    这是代码:

    // apply to the container (for ex. <UL> element)
    @mixin flexbox_grid($columns, $gutter_width){
    
      display: flex;
      flex-direction:row;
      flex-wrap:wrap;
      justify-content: flex-start;
    
      > *{
        @include flexbox_cell($columns, $gutter_width);
      }
    }
    
    // apply to the cell (for ex. a <LI> element)
    @mixin flexbox_cell($columns, $gutter_width){
      $base_width: 100 / $columns;
      $gutters: $columns - 1;
      $gutter_offset: $gutter_width * $gutters / $columns;
    
      flex-grow: 0;
      flex-shrink: 1;
      flex-basis: auto; // IE10 doesn't support calc() here
    
      box-sizing:border-box; // so you can freely apply borders/paddings to items
      width: calc( #{$base_width}% - #{$gutter_offset} );
    
      // remove useless margins (for cascading breakponts)
      &:nth-child(#{$columns}n){
        margin-right: 0;
      }
    
      // apply margin
      @for $i from 0 through ($gutters){
        @if($i != 0){
          &:nth-child(#{$columns}n+#{$i}){
            margin-right: $gutter_width;
          }
        }
      }
    }
    

    用法:

    ul{
       // just this:
       @include flexbox_grid(3,20px);
    }
    
    // and maybe in following breakpoints, 
    // where the container is already setted up, 
    // just change only the cells:
    
    li{
       @include flexbox_cell(4,40px);
    }
    

    显然,最终要由你来设置容器的填充/边距/宽度和单元格的底部边距等 .

    希望能帮助到你!

  • 3

    这非常hacky,但它适用于我 . 我试图获得一致的间距/边距 .

    .grid {
      width: 1024px;
      display: flex;
      flex-flow: row wrap;
      padding: 32px;
      background-color: #ddd;  
    
      &:after {
        content: "";
        flex: auto;
        margin-left:-1%;
      }
    
      .item {
        flex: 1 0 24.25%;
        max-width: 24.25%;
        margin-bottom: 10px;
        text-align: center;
        background-color: #bbb;
    
        &:nth-child(4n+2),
        &:nth-child(4n+3),
        &:nth-child(4n+4) {
          margin-left: 1%;
        }
    
        &:nth-child(4n+1):nth-last-child(-n+4),
          &:nth-child(4n+1):nth-last-child(-n+4) ~ .item {
            margin-bottom: 0;
        }    
    
      }
    }
    

    http://codepen.io/rustydev/pen/f7c8920e0beb0ba9a904da7ebd9970ae/

  • 1

    哦,男孩,我想我找到了一个很好的解决方案,最小的CSS,没有JS . 看看这个:

    img {width:100%;}
    li {
      display: inline-block;
      width:8em;
      list-style:none;
    }
    ul {text-align: justify;}
    
    <ul>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li>
        <img src="http://www.planwallpaper.com/static/images/kitty-cat.jpg" />
      </li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
    </ul>
    

    这里的关键是要记住我们想要实现的正是 text-align: justify 的作用!

    HTML中的空元素可以使最后一行显示完美,而不会改变外观,但考虑到您要实现的目标,可能不需要 . 为了在任何情况下实现完美 balancer ,您至少需要x-4个空元素,x是要显示的元素数,或者n-2,n是要显示的列数 .

  • 0

    假设:

    • 您想要包装的4列网格布局

    • 项目数不一定是4的倍数

    在除第1,第5和第9项之外的每个项目上设置左边距,依此类推 . 如果左边距为10px,则每行在4个项目之间将具有30px的边距 . 项目的百分比宽度计算如下:

    100% / 4 - horizontal-border - horizontal-padding - left-margin * (4 - 1) / 4
    

    对于涉及最后一行flexbox的问题,这是一个不错的解决方法 .

    .flex {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      margin: 1em 0;
      background-color: peachpuff;
    }
    
    .item {
      margin-left: 10px;
      border: 1px solid;
      padding: 10px;
      width: calc(100% / 4 - 22px - 2px - 10px * (4 - 1) / 4);
      background-color: papayawhip;
    }
    
    .item:nth-child(4n + 1) {
      margin-left: 0;
    }
    
    .item:nth-child(n + 5) {
      margin-top: 10px;
    }
    
    <div class="flex">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
    </div>
    <div class="flex">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
      <div class="item">6</div>
    </div>
    <div class="flex">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>
      <div class="item">6</div>
      <div class="item">7</div>
      <div class="item">8</div>
      <div class="item">9</div>
    </div>
    
  • 0

    我能够在容器上用 justify-content: space-between 做到这一点

相关问题