html无规律卡片布局,如何实现同等间隙的卡片布局
在列表展示中,经常会使用卡片的内容展示形式,为了美观,常常要求各卡片间的间隙是一致的。
卡片内容不一样可能高度不等,但一般来说为了整体的一致性,会限制每个卡片的宽高都相等。
本文就基于宽高一致的多个卡片,在不同屏幕大小下,每行卡片数量可能有调整,考量如何实现等间隙的布局。
放置一张张卡片项,为了设置间距,最常见的就是直接使用一个特定的margin值了,这种方式虽然可以(通过精确计算后确实也可以)
直接设置一个间距,比如统一 margin-left 和 margin-bottom都为 20px ,并不能保证每行最后一个卡片之后的间距是20px
关于如何定这个 margin的值,需要通过一个规则来计算,这个后文再说明
设置同等间距,常用的还有 flex布局中的 justify-content: space-between,可以定义各子项目以相同间距布局,但不好处理左右子项目与边框的间距。 space-around这个就更用不得了,会使得左右子项目右margin == 左margin * 2
所以最终还是回到使用margin值来设置,通过一个可用的规则,来保证间距是一致的。
先把基本结构搭上
项目列表
{{projectname}}
js生成n个项目
function addevent(elem, type, handler) {
elem.addeventlistener(type, handler, false);
}
function qs(selector) {
return document.queryselector(selector);
}
function qsa(selectors) {
return document.queryselectorall(selectors);
}
var mockdata = (function(num) {
var data = [];
for (var i = 1; i <= num; ++i) {
data.push({
projectid: i,
projectname: '项目' + i,
author: '张大大'
});
}
return data;
})(8);
var itemtpl = qs('#proj-item-tpl').innerhtml;
var itemsdom = qs('.proj-items');
/**
* 渲染数据
* @param {[type]} data [description]
* @return {[type]} [description]
*/
function renderlist(data) {
var html = '';
var fragment = document.createdocumentfragment();
data.foreach(function(item) {
var divtemp = document.createelement('div');
// 模板替换
divtemp.innerhtml = itemtpl.replace(/{{(\w+)}}/g, function(input, match) {
return match ? item[match] || '' : '';
});
fragment.appendchild(divtemp.firstelementchild);
});
// 渲染
itemsdom.appendchild(fragment);
}
renderlist(mockdata);
把基础样式放上,这里我们先指定一个特定的itemmargin值为20px
$itemmargin: 20px;
$itemwidth: 130px;
$itemheight: 150px;
.container {
margin: 20px auto;
width: 450px;
background-color: #f2f2f2;
color: #666;
h2 {
margin: 20px;
padding-top: 20px;
font-size: 20px;
}
}
.proj-items {
display: flex;
flex-wrap: wrap;
/* justify-content: space-between; */
padding: 0;
list-style: none;
&:after {
content: "";
display: block;
flex-grow: 99999;
}
}
.proj-item {
margin-left: $itemmargin;
margin-bottom: $itemmargin;
width: $itemwidth;
height: $itemheight;
background-color: #fff;
border-radius: 3px;
text-align: center;
&:hover {
box-shadow: 0 0 20px #ddd;
}
a {
display: block;
padding: 15px;
height: 100%;
color: #666;
text-decoration: none;
}
&__title {
margin-top: 0;
font-size: 16px;
}
&__author {
font-size: 12px;
}
}
可以看到,每行最后一个间距不一致了,所以不能简单的写个margin值
再来看看设置 space-between的时候
.proj-items {
justify-content: space-between;
...
}
.proj-item {
/* margin-left: $itemmargin; */
margin-bottom: $itemmargin;
...
}
看来并不够强大
如果看得仔细,应该能看到项目7和8是挨在一起的,为何没有间距呢
其一是因为没有margin-left值,其二是在项目列表后放了一个坑来占位,防止最后一行项目过少时 space-between的值太大了
把这个撤掉看看这个影响
&:after {
content: "";
display: block;
flex-grow: 99999;
}
还是把目光投向margin值的设定规则吧
在设计一个页面布局时,至少已经确定了xx页面大小的情况下,容器宽度应该设置为多少(比如为1200px),每行放n个项目,项目的宽高是多少
有了这些指标(也必须有这些指标),我们就可以用来计算margin值了
containerwidth == n * itemwidth + (n + 1) * itemmargin
得出
itemmargin = (containerwidth - n * itemwidth) / (n + 1)
代入这里的情况,containerwidth 450px,itemwidth 130px,每行 3个,即可得出 itemmargin 正好为 15px
有了某种特定情况下的布局规则之后,接下来还要考虑不同屏幕大小的情况下,怎么调整这个margin值
这个需要结合媒体查询来设定,同时相应的计算规则也可以通过scss来处理
第一种情况是每行3个,n只可能为整数,即可推算出需要处理的临界值为1 2 3 4 5 6 ... 这些整数值
加入n为4,如果要保证 itemmargin值15px在各种情况下都相等,计算可得 容器宽度containerwidth值 为 595px
同理求得 n是5时为 740px ,n是2时为 305px
当然,如果觉得这个containerwidth值不太好看,也可以自己定义,比如 n是4的时候设置为 600px,代入公式那么 itemmargin值为16px。
为了保证各种请下间距都相等,我个人就不推荐这么干了
通过上述的规则计算,我们可以得出每行项目数量递增时的容器宽度临界值。把这些临界值放在媒体查询里面配置,即可方便地实现这种布局的自适应。
/* 这两个为初始就确定的基准值 */
$containerwidth: 305px;
$itemmargin: 15px;
$itemwidth: 130px;
$itemheight: 150px;
/* 每行项目数量为itemnum时的容器宽度 */
@function getcontainerwidth($itemnum) {
@return $itemnum * $itemwidth + ($itemnum + 1) * $itemmargin;
}
/* 配置各个页面宽度下的容器宽度(应用) */
@mixin adjustcontainerwidth(
$from: 2,
$to: 5
) {
@for $i from $from through $to {
$minwidth: getcontainerwidth($i);
$maxwidth: getcontainerwidth($i + 1);
@media only screen and (min-width: $minwidth) and (max-width: $maxwidth) {
.container {
width: $minwidth;
}
}
}
}
.container {
margin: 20px auto;
width: $containerwidth;
background-color: #f2f2f2;
color: #666;
h2 {
margin: 20px;
padding-top: 20px;
font-size: 20px;
}
}
@include adjustcontainerwidth(
$from: 1,
$to: 7
);
即可实现各个页面大小下的自适应效果
完整的css部分
1 /* 这两个为初始就确定的基准值 */
2 $containerwidth: 305px;
3 $itemmargin: 15px;
4
5 $itemwidth: 130px;
6 $itemheight: 150px;
7
8 /* 每行项目数量为itemnum时的容器宽度 */
9 @function getcontainerwidth($itemnum) {
10 @return $itemnum * $itemwidth + ($itemnum + 1) * $itemmargin;
11 }
12
13 /* 配置各个页面宽度下的容器宽度(应用) */
14 @mixin adjustcontainerwidth(
15 $from: 2,
16 $to: 5
17 ) {
18 @for $i from $from through $to {
19 $minwidth: getcontainerwidth($i);
20 $maxwidth: getcontainerwidth($i + 1);
21
22 @media only screen and (min-width: $minwidth) and (max-width: $maxwidth) {
23 .container {
24 width: $minwidth;
25 }
26 }
27 }
28 }
29
30 .container {
31 margin: 20px auto;
32 width: $containerwidth;
33 background-color: #f2f2f2;
34 color: #666;
35
36 h2 {
37 margin: 20px;
38 padding-top: 20px;
39 font-size: 20px;
40 }
41 }
42
43 @include adjustcontainerwidth(
44 $from: 1,
45 $to: 7
46 );
47
48 .proj-items {
49 display: flex;
50 flex-wrap: wrap;
51 padding: 0;
52 list-style: none;
53 }
54
55 .proj-item {
56 margin-left: $itemmargin;
57 margin-bottom: $itemmargin;
58 width: $itemwidth;
59 height: $itemheight;
60 background-color: #fff;
61 border-radius: 3px;
62 text-align: center;
63
64 &:hover {
65 box-shadow: 0 0 20px #ddd;
66 }
67
68 a {
69 display: block;
70 padding: 15px;
71 height: 100%;
72 color: #666;
73 text-decoration: none;
74 }
75
76 &__title {
77 margin-top: 0;
78 font-size: 16px;
79 }
80
81 &__author {
82 font-size: 12px;
83 }
84 }
view code
总结
以上是生活随笔为你收集整理的html无规律卡片布局,如何实现同等间隙的卡片布局的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: qq个性签名二次元
- 下一篇: express给html设置缓存,web