弹性框:将最后一行alignment到网格
我有一个简单的弹性框布局,像一个容器:
.grid { display: flex; flex-flow: row wrap; justify-content: space-between; }
现在我想把最后一行中的项目与其他项目alignment。 justify-content: space-between;
应该使用,因为网格的宽度和高度可以调整。
目前看起来像
在这里,我想让右下方的项目位于“中间栏”中。 什么是最简单的方法来完成呢? 这是一个显示这种行为的小jsfiddle 。
添加: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; }
一种技术是插入一些额外的元素(与连续期望的元素的最大数量一样多),给定零高度。 空间仍然分裂,但多余的行倒塌到没有:
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
为我指定列的宽度。
.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>
你不能。 Flexbox不是一个网格系统。 它没有语言结构来做你所要求的,至less在你使用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; }
一个可能的解决scheme是使用justify-content: flex-start;
在.grid
容器上,对其子级的大小限制以及相应子元素上的边距 – 取决于所需的列数。
对于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%; }
这是另一个不完美的解决scheme,但它的工作。
可以使用“flex-start”并手动添加边距。 它需要进行一些math黑客攻击,但是确实很容易,并且可以轻松使用像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; }
这是一个例子
如果要将最后一项alignment到网格,请使用以下代码:
网格容器
.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%; }
项目在网格中
.card { flex: 1 1 100%; box-sizing: border-box; -webkit-box-flex: 1; max-width: 32%; display: block; position: relative; }
诀窍是将项目的最大宽度设置为等于.card-grid的最大宽度:after。
在Codepen上进行现场演示
正如其他海报所提到的 – 没有一个干净的方法来将最后一行与flexbox左alignment(至less按照当前的规范)
但是,它的价值在于:使用CSS Grid Layout Module,这个工作非常容易:
基本上相关的代码归结为:
ul { display: grid; /* 1 */ grid-template-columns: repeat(auto-fit, 100px); /* 2 */ grid-gap: 1rem; /* 3 */ justify-content: space-between; /* 4 */ }
1)使容器元素成为网格容器
2)设置宽度为100px的自动列的网格。 (注意使用自动 auto-fill
(与auto-fill
)(对于1行布局)将空轨道折叠为0 – 允许项目展开占据剩余空间。
3)为网格行和列设置间隙/排水沟 – 在这里,因为想要一个“空间”布局 – 差距实际上是一个最小的差距,因为它会根据需要增长。
4)类似于flexbox。
ul { display: grid; grid-template-columns: repeat(auto-fit, 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>
这个版本是固定宽度块的最佳方法:
http://codepen.io/7iomka/pen/oxxeNE
在其他情况下 – 达尔格的版本
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>
似乎没有人提出最后一项Flex-Grow解决scheme。 这个想法是让你的最后一个弹性项目采取所有可以使用的地方flex-grow:1。
.grid { display: flex; flex-flow: row wrap; justify-content: space-between; } .grid > *:last-child { flex-grow: 1; }
注意:这个解决scheme并不完美,尤其是如果你在flex项目中居中放置元素,因为它将集中在可能巨大的最后一个flex项目上。
这是很多答案的组合,但它确实是我所需要的 – 也就是将flex容器中的最后一个孩子alignment到左边,同时保持行为之间的空间(在这种情况下,它是一个三列布局)。
这是标记:
.flex-container { display: flex; justify-content: space-between; flex-direction: row; } .flex-container:after { content: ""; flex-basis: 30%; }
是。! 我们可以但有一些媒体查询和最大列数是预定义的 。
这里使用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>
有没有flexbox的方法,虽然你需要满足以下条件。 1)容器有填充物。 2)项目是相同的大小,你确切地知道你想要每行。
ul { padding: 0 3% 0 5%; } li { display: inline-block; padding: 0 2% 2% 0; width: 28.66%; }
容器右侧的较小的填充可以在每个列表项的右侧添加额外的填充。 假设与列表对象相同的父项中的其他项目用0 5%填充,则将与它们齐平。 您也可以调整百分比,无论您想要多less保证金或使用计算px值。
当然,你也可以使用nth-child(IE 9+)删除容器上的边距来删除每个第三个边框上的边距。
使用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; } }
我为它做了一个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
你只需要设置项目宽度的百分比和列数。
我希望这可以帮助你。
这是另外两个scss mixins。
这些mixin假设你不会使用像Isotope这样的js插件(他们不尊重html标记顺序,从而搞砸了CSS第n条规则)。
而且,如果您是以移动的方式编写响应式断点,您将能够充分利用它们。 理想情况下,您可以在较小的断点上使用flexbox_grid(),在下面的断点上使用flexbox_cell()。 flexbox_cell()将负责重置先前设置的边距,而不再使用较大的断点。
顺便说一句,只要你正确地设置你的容器的弹性属性,你也可以在项目上只使用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); }
显然,最终你需要设置容器的填充/边距/宽度和单元格的底部边距等。
希望它有帮助!
这很不好意思,但对我很有用。 我试图实现一致的间距/利润率。
.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/
如果子元素的宽度是可变的(导致每行子元素数量可变),那么单独使用CSS
就没有办法做到这一点。 所以我转向JavaScript来:
- 添加
.sizer
元素作为最后一个孩子,最初以flex-basis:100%
- 逐渐减less它的
flex-basis
直到它跳到上一行(或者flex-basis:0%
) - 当上述情况发生时,它会将行的最后一行中的所有项目都推送出去:作业完成!
工作,通用的例子:
// first part of the script generates cards with random words, ignore it let words = [ 'interesting', 'tongue', 'excellent', 'start', 'sticky', 'lame', 'lopsided', 'ill-informed', 'terrible', 'reduce', 'near', 'order' ] for (var i = 0; i < 20; i++) { let text = ''; for (var j = 0; j < 3; j++) { text += words[parseInt(Math.random() * words.length)] + ' ' } $('.container').append($('<div />', { class: 'card', text: text })) } // the juice starts here: $('.container').append( $('<div />', { class:'sizer' })); let topSizer = $('.sizer')[0].getBoundingClientRect().top, perCent = 100; while ( $('.sizer')[0].getBoundingClientRect().top === topSizer && topSizer > 0 ) { $('.sizer').css({flexBasis:(perCent--)+'%'}); }
.container { display: flex; flex-flow: row wrap; align-content: flex-start; } .card { flex: 1 1 0; padding: .8rem; border: 1px solid #ccc; margin: 0 -1px -1px 0; } .sizer { flex-basis: 100%; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="container"></div>
你可以简单地通过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; }
我能够用容器上的justify-content: space-between
来做到这justify-content: space-between