CSS 经典布局实现-九宫格布局

1,460 阅读2分钟

前言

面试中可能会有要求实现九宫格布局。本文介绍了利用 float、inline-block、table、flex、grid 实现品字布局的方法。

九宫格布局

HTML 结构如下:

<div class="box">
  <ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
  </ul>
</div>

公共CSS样式:

ul {
   padding: 0;
   margin: 0;
   width: 100%;
   height: 100%;
}
li {
  list-style: none;
}

float 实现

  • 子元素设置浮动,调整长宽,利用 margin-rightmargin-bottom 调成间距。
  • 第 3、6、9 个盒子的右边距是不需要的,第 7、8、9 个盒子的下边距是不需要的。利用 :nth-of-type() 伪类对边距进行单独设置。

:nth-child() 是相对这个 CSS 伪类找到的所有当前元素的兄弟元素。 :nth-of-type() 是相对这个 CSS 伪类找到的同种兄弟元素。

ul {
  overflow: hidden;
}
li {
  float: left;
  margin-right: 5%;
  margin-bottom: 5%;
  width: 30%;
  height: 30%;
}
li:nth-of-type(3n) {
  margin-right: 0;
}
li:nth-of-type(n + 7) {
  margin-bottom: 0;
}

inline-block 实现

  • inline-block 的作用与上一方法的浮动类似,都是为了让元素排列在同一行。
  • 同样需要利用 :nth-of-type() 伪类对边距进行单独设置。
  • 行内元素间常会出现间距,导致元素被挤到下一行。这种间距是由于换行符被转译产生的,可以在父元素设置 font-size: 0; 来消除,但这又会导致子元素继承字体大小,需要重新设置。也可以在父元素设置 letter-spacing: -5px;(或 word-spacing 为负值)来消除间距,但这又会影响子元素。很难找到有效好用的方法来消除间距。
ul {
  letter-spacing: -5px;
}
li {
  display: inline-block;
  margin-right: 5%;
  margin-bottom: 5%;
  width: 30%;
  height: 30%;
}
li:nth-of-type(3n) {
  margin-right: 0;
}
li:nth-of-type(n + 7) {
  margin-bottom: 0;
}

table 实现

  • 父元素设置为 tableli 元素设置为表格行,里面增加盒子包裹,设置成表格格子,新的 HTML 结构如下。
<div class="box">
  <ul>
    <li>
      <div>1</div>
      <div>2</div>
      <div>3</div>
    </li>
    <li>
      <div>4</div>
      <div>5</div>
      <div>6</div>
    </li>
    <li>
      <div>7</div>
      <div>8</div>
      <div>9</div>
    </li>
  </ul>
</div>
  • 利用模仿 table 布局的方式对元素进行排列。
  • 可以使用 border-spacing 来设置表格间距。
ul {
  display: table;
  border-spacing: 10px;
}
li {
  display: table-row;
}
.box li div {
  display: table-cell;
  width: 30%;
  height: 30%;
}

flex 实现

  • 设置 flex-wrap: wrap; 允许多行显示,使元素自动换行。
  • 同样需要利用 :nth-of-type() 伪类对边距进行单独设置。
ul {
  display: flex;
  flex-wrap: wrap;
}
li {
  margin-right: 5%;
  margin-bottom: 5%;
  width: 30%;
  height: 30%;
}
li:nth-of-type(3n) {
  margin-right: 0;
}
li:nth-of-type(n + 7) {
  margin-bottom: 0;
}

grid 实现

  • 设置显式网格使元素进行类似九宫格的排列。
  • 设置 grid-gap 控制九宫格间隙大小。
  • 网格大小或者设置 repeat(3, 1fr) 也可以实现自适应三等分。
ul {
  display: grid;
  grid-template-columns: 30% 30% 30%;
  grid-template-rows: 30% 30% 30%;
  grid-gap: 5%;
}

参考资料

前端面试题之CSS篇
:nth-child - CSS:层叠样式表 | MDN
:nth-of-type - CSS:层叠样式表 | MDN