假设我有5个300px*300px的卡片,须要根据屏幕宽度自适用平铺排列,并在换行的时候靠左对齐。css
不能用js实现,用js就太简单了,并且代码会比较啰嗦和让人困扰。 html
justify-content: flex-start
和flex-wrap: wrap
完成自动换行靠左需求justify-content: space-evenly
完成不了需求直觉上,利用这个属性和wrap就能够知足,但实际上不能够,由于会每行各自计算空隙,这样会致使最后一行对不齐,效果以下浏览器
flex-start
和margin-left: calc
实现flex-start
能够知足咱们靠左对齐的需求。接下来,咱们只要完成间距的需求就能够了。子项目宽度是固定的300px,那么根据容器的宽度,确定就能计算出来间距了,例如宽1000px的容器,那确定只能容纳3个子项目,剩余100px空间,一个四个空隙,那每一个空隙就是25px。bash
嗯,貌似是搞定了,咱们转化成css中calc就是:布局
margin-left: calc((100% - Math.floor(100% / 300px) * 300px) / Math.floor(100% / 300px))
复制代码
可是,calc根本不支持这样:flex
既然没法经过calc直接计算出来n,那就想办法跳过这一步。这样咱们只须要完成左边的公式就好了。spa
嗯,由于咱们子项目是定宽的300px,那么:容器少于900px,就只能放2个,少于1200px,就只能放3个。。。。 多写几个相似下面的媒体查询就能够了3d
@media screen and (max-width: 1200px) and (min-width: 900px) {
item { --n: 3; }
}
复制代码
而后咱们的margin-left
就能够简化成以下calc支持的左边的公式了code
margin-left: calc((100% - var(--itemWidth) * var(--n)) / (var(--n) + 1));
复制代码
htmlcdn
<div class="container">
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
/div>
复制代码
css
.container {
background: gold;
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}
item {
outline: 1px solid black;
height: 300px;
background: red;
margin-top: 20px;
--itemWidth: 300px; /* 和项目宽度一致 */
width: calc(var(--itemWidth));
margin-left: calc((100% - var(--itemWidth) * var(--n)) / (var(--n) + 1));
}
@media screen and (max-width: 900px) {
item { --n: 2; }
}
@media screen and (max-width: 1200px) and (min-width: 900px) {
item { --n: 3; }
}
@media screen and (max-width: 1500px) and (min-width: 1200px) {
item { --n: 4; }
}
@media screen and (max-width: 8888px) and (min-width: 1500px) {
item { --n: 5; } /* 最多一行显示五个 */
}
复制代码
经过缩放浏览器观察,已经实现自适用屏幕宽度了。
思路同样,可是flex的其余特性就使用不了了
那就只要把margin-left总体写到@media 媒体查询里便可
若是使用grid布局,calc都不须要用到了,只要在@media中写好grid样式,在不一样宽度下有不一样列数便可 请看个人另一篇文章
直接每一个项目宽度 100% / n 便可,可是那样html代码就会很啰嗦,每一个子项目都须要再套一层,做为真正的flex项目使用。