标题中的图标布局,其实指的是在一个块级容器中,从左至右水平罗列若干大小、间距相等的图标,一行排列满了后自动换行到下一行继续从左至右水平罗列。至于这个布局具体应该叫什么我也不清楚,总之他有点像我们的苹果或者安卓的桌面,也有点像微软的磁贴,还有点像已经被被关闭的webqq,如果你还是不知道我说的布局是什么,看一个图你马上就清楚了。
例图出自于hoorayos
图标布局初看是很简单的,前提是你已经确定了一行图标的个数,或者确定了容器的宽带。当容器的宽带不固定,而图标的大小固定时(也就是一行的图标个数不是固定时),那么如果仅靠css来做的话就困难了,很多桌面软件都是用js计算加绝对定位布局的方式实现,下面笔者分享一下项目中用纯css实现图标布局的几种方式。
例子:浮动布局、行内块级元素布局
我以前都是用浮动布局或者行内块级元素布局做这种,但是无论哪种布局都有一个问题,那就是右侧会有填不满的bug,会空出不到一个图标宽度的距离。
当然这两种布局的好处也很明显,就是图标的间距不会随着容器宽带变化而变化。
此外,如果是行内块级元素布局,要注意行内元素之间会产生距离,解决办法是将容器的字体大小设置为0;而浮动布局会造成容器不能被撑起来的现象,需要使用清除浮动clear:both。相信这些用法大家也都很熟悉了。
为了解决上述两种方法的问题,可以利用属性text-align: justify。这个属性是表示文字自动调整间距使其能够占满一整行,其实他不止对文字起作用,对于行内块级元素通用起作用。然而这样写虽然解决了空隙分配不均的问题,不过会出现另一个问题,那就是最后一行显示完全混乱掉了。
其实也是有解决办法的,参考张鑫旭老师在讲解vertical-align时候,使用的用0高度的元素占位的方法,可以比较完美的解决这个问题。我们需要确定容器支持的最大宽度,用这个宽带除以一个图标的宽带,就得到了最大的列数。然后在最后一个图标的后面,补出这些个0高度的元素来占位。
请查看完整的例子。
这个解决方案已经比较完美了,唯一的缺点是容器和图标元素之间,没有留出空隙,这样会显得布局过于死板,尤其是当一行只有一个图标的时候,就能很明显的看出问题来了(那已经不算图标布局了,所有出现那种情况的可能性很低,如果需要可以用响应式布局处理)。
为了解决text-align: justify布局的问题,我们还有一种可以采用的方式,那就是flex布局。
flex布局大家应该很熟悉了,尽管现在的主流浏览器都已经支持这个布局了,但是在不同浏览器中还是有兼容、标准不相同等问题。但是,如果在合理使用的情况下,绝大多数浏览器都已经很好地支持flex布局了,我们没有必要再对他避而远之了。
flex布局对于这种情况有什么决解方法呢?这个可以参考justify-content属性。justify-content属性用于设置弹性盒子元素在主轴(横轴)方向上的对齐方式,这里列举我们需要的几个可选择值。
flex-start | 默认值。项目位于容器的开头。 |
space-between | 项目位于各行之间留有空白的容器内。 |
space-around | 项目位于各行之前、之间、之后都留有空白的容器内。 |
其中当justify-content值为flex-start,图标布局表现效果如浮动布局,所有图标元素都靠向左边,右边也会留出分配不下的一小段距离;而当justify-content值为space-between的效果和text-align: justify差不多,留出分配不下的一小段距离会自动的分配到各个图标元素之间;而space-around,留出的空隙不但会分配到各个图标元素之间,还会分配到容器与图标元素之间,这样布局看起来就更自然了。
那么仅用justify-content就能够解决了我们问题了吗?还不能,从上图我们可以看出,当容器justify-content值为space-between或者是space-around,最后一行没有填满时候,容器会调整最后一行元素之间的间隙,让剩余元素平均分配到这最后一整行中。这显然是有问题的,如何解决呢?同样使用0高度的元素占位,可以很好的解决这样的问题。
请查看完整的例子。
上述两个布局也是不够完美的,主要是需要设置0高度的元素去占位,这让dom结构不够简洁,毕竟通过改变dom的结构去完成布局的要求,是不符合语义化思想的。而使用响应式布局就没有这样的问题了。
响应式布局利用css3的media query媒体查询功能,在不同显示器的分别率下,分别去设置不同套的css,以实现屏幕适配问题。同时,响应式布局比flex布局兼容性好,除了ie8外的所有主流浏览器都兼容。
响应式布局不是真正的图标布局,事实上他就是浮动布局加百分比布局,只是不同分辨率下的参数不一样,以达到不同分辨率下一行图标个数不同的目的。因为是百分百布局,所以无需考虑剩余空隙分配的问题。而且现在主流框架都提供了一些写好的响应式布局的class,使用这种现成的class开发使用都简单了不少。
基于响应式布局的图标布局缺点也很明显,就是不能使用现成的框架,需要开发者自己去计算各个屏幕的适配情况,是需要一定的计算量的。同时当图标大小发生变化的时候,又需要重新计算,尤其要支持高分辨率的屏幕的时候,需要计算的工作就更多了。同时响应式布局只能根据整个页面的分辨率变化,不能根据一个局部容器的大小变化,也是其不足之处。
请查看完整的例子。
以上就是笔者总结的图标布局的几种实现方式,不知道各位有没有更简单的实现方法,欢迎大家分享经验^_^。