关于列表布局的样式分析

本贴最后更新于 2723 天前,其中的信息可能已经事过境迁

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 来辅助布局,以及使用其他更现代化的适配方式,这里就不再赘述了。

  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1348 回帖
  • 研究
    12 引用 • 34 回帖
  • 黑客派

    黑客派是 B3log 开源社区的线上论坛,这里主要汇聚了程序员和设计师。HacPai 分别取 Hacker / Painter 的头三个字母组成,源自《黑客与画家》。

    359 引用 • 4761 回帖 • 511 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 哈哈,居然把首页都研究了。为了固定左边,右边自适应。

  • someone

    但是感觉很奇怪啊,移动端是3*3,list,1*2这样布局,有什么深意吗?
    还是说11这个数字太尴尬了……?