关于列表布局的样式分析

1. 前言

在实际项目开发中,比较常见的是如下图这样的列表布局。
图1
列表布局的好处有很多,如排列整齐,可以很好的聚合同类物品,如果再配上同一色调或者相互搭配的图片,会给人很清爽的感觉。
图2

2. 布局方式

列表布局的方式有很多,我目前在项目中大量使用的方式有 2 种。
一种是使用display: inline-block;来达到列表布局的目的。
还有一种是使用float: left / right;来做到列表布局。

更早些的全局<table/>的方式目前见的比较少,而当下使用最新的CSS3display: flex在一些主流网站上也可以看见其身影。
今天我来说说前两种方式。

2.1 基于display: inline-block的列表布局

block的意思是块级元素,一个div默认的display属性值就是block,它会自动撑满一整行。
inline-block则不同,它会将元素改变为行内元素display: inline-block的元素会与其他带有inline属性的元素一起构成,其行高行内最高的元素决定。
因此,利用其“成行 "的特性,我们可以使用其进行列表布局。
如文章刚开头的那张图片,就是使用inline-block制作的列表布局。
大家可以点击我,查看列表布局。
可以看出代码里有一点奇怪的地方,在父元素.g-wrap内定义了一个奇怪的属性

letter-spacing: -30px;
font-size: 0;

子元素内也相对的定义了

letter-spacing: 0; 
font-size: 16px

这是为了去除inline-block元素之间的间隙而写的。如果不这样的话各个元素之间会空出一定的间隙。
大家可以点击我,查看列表布局的间隙。
点击加上letter-spacing!按钮之后,整体布局会发生变化,此时点击去掉letter-spacing!,可以看出明显的不同。
这是因为inline-block元素在书写的过程中,元素间的空格 / 空行导致的。
除了使用给父类加letter-spacingfont-size: 0的方式之外,我们还可以用更简单粗暴的形式来解决:
图3
我们将代码书写到一行,元素间的间距自然就消失了!
此时我们可以查看效果,会发现

达到了我们想要的效果。
大家可以点击我,查看效果图。
而目前使用的打包工具均具有压缩代码的功能,可以将所有的 html 代码都压缩为一行,所以这个问题其实不是很大。

PS: 上文其实可以只使用font-size: 0来使元素间间距消失。但是在chrome中貌似设置了最小字体大小为12px,所以一般还是使用letter-spacing: 负值的方式来消除间距。

因为inline-block的 "行" 的特性,其可以很方便的将高度不一样的元素整理为列表布局而不会破坏整体。

我们也可以使用vertical-align属性来控制对齐方式。例如vertical-align: middle

2.2.2 基于 float 的列表布局

float布局和inline-block在普通的效果上差不多,代码差别也不大,就是得记住浮动会引起高度塌陷,要清除浮动。关于清除浮动,网络上有许多方式方法,比方说父元素overflow: hidden; zoom: 1,也有给父元素加:after {clear: both; content: ""},用哪种都无所谓,别忘了清除就可以。

大家可以点击我,查看 float 布局
float最大的缺陷就是不支持高度不同的元素一起排列。这也就限制了列表元素必须定高。定高这种做法我是相当反感的,除非策划能保证将来不改需求,否则还是远离固定高度这个大坑比较好。

如果不定高,换言之,有元素的高度超过了其他元素,会造成整体布局混乱。

大家可以点击我,查看混乱的布局

3. 如何选择

实际项目中,我们必须根据相关视觉稿来确定我们使用的布局方式。
比如说最简单的元素定高定宽列表布局,我们可以直接使用float布局的方式直接完成。float也无需考虑元素间隙,就是不能忘记清除浮动。
然而实际中元素定高定宽的列表布局可是少之又少呀!因为谁也不知道下一个超出宽度的元素会是哪个,除非策划能保证将来不改需求。

实际上我比较推荐的还是inline-block的方式。
其一、使用inline-block可以远离float带来的高度塌陷问题;
其二、inline-block的本职工作就是如此,float的本职工作只是将图片 / 文字浮动而已;
其三、inline-block支持变化的高度,更能适应当下快节奏的变更需求;
其四、inline-block配上父元素text-align: justify可以实现完美的自适应的两端对齐布局,而这一切都是浏览器帮你完成的。(大家可以点击我,查看完美的自适应两端对齐布局)

4. 案例

我们通过几个小案例来分析一下使用场景

4.1 案例一


这是最简单的列表布局。推荐使用inine-block的方式实现。因为其内部元素的文案、标志等极有可能发生更替而导致换行。使用inline-block可以有效避免这点。
就不上代码了 ~

4.2 案例二


类似这样的列表布局的变种,我比较倾向于float布局。
因为看图片的样式可以发现,右边的两块高度之和一定等于左图,可以评估一下改需求的可能性不大。
我们可以写出这样的代码很轻松的完成布局。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
* {
  box-sizing: border-box;
}
.g-wrap {
  margin: auto;
  width: 900px;
}
.g-wrap:after {
  display: table;
  content: "";
  clear: both;
}
.m-rect {
  float: left;
  width: 300px;
  border: 1px solid red;
  height: 300px;
}
.m-srect {
  height: 150px;
}
</style>
</head>
<body>
<div class="g-wrap">
  <div class="m-rect"></div>
  <div class="m-rect"></div>
  <div class="m-rect m-srect"></div>  
  <div class="m-rect m-srect"></div>
</div>
</body>
</html>

4.3 案例 3


黑客派的首页的这块地方比较有意思。使用开发者工具查看之后发现是左边 3*3 的方块单独布局,右边的 list 和下方的两块方格单独布局。而且其使用了display: flex的方式,估计是为了能更好的适配移动端。
如果只是需要适配设置最小宽度的 pc 端,我们或许可以好好利用float的特性来布局。

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
* {
  box-sizing: border-box;
}
.g-wrap {
  width: 90%;
  min-width: 792px;
  margin: auto;
  background-color: gray;
}
.u-timeline {
  float: right;
  width: 40%;
  height: 492px;
  border: 1px solid black;
}
.u-timeline .ul {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  list-style: none;
}
.u-list {
  letter-spacing: -30px;
  font-size: 0;
}
.u-list .rect {
  letter-spacing: 0px;
  font-size: 16px;
}
.rect {
  letter-spacing: 0;
  height: 246px;
  width: 20%;
  display: inline-block;
  vertical-align: top;
  background-color: rgba(100,100,100,.6);
  border: 1px solid red;
}
</style>
</head>
<body>
  <div class="g-wrap">
    <div class="u-timeline">
      <ul class="ul">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
        <li>5</li>
        <li>6</li>
        <li>7</li>
      </ul>
    </div>
    <div class="u-list">
      <div class="rect"></div>
      <div class="rect"></div>
      <div class="rect"></div>
      <div class="rect"></div>
      <div class="rect"></div>
      <div class="rect"></div>
      <div class="rect"></div>
      <div class="rect"></div>
      <div class="rect"></div>
      <div class="rect"></div>
      <div class="rect"></div>
    </div>
  </div>
</body>
</html>

PS: 当然了,黑客派的首页不可能像我这样粗糙的布局,这里只是简单的提出一种思路,要想适配更多分辨率或许需要 js 来辅助布局,以及使用其他更现代化的适配方式,这里就不再赘述了。