此文翻译自 Creating Your Own CSS Grid System | Jan,英文不好如有错误 ✖ ,请指正。

CSS 网格已经存在很长时间了。它们通常捆绑在 Bootstrap 等框架中。我不是一个 Bootstrap 仇恨者,但如果你真正需要的只是一个网格,有时使用一个框架就“太过分”了。以下是如何从头开始制作自己的 CSS 网格。

CSS 网格的元素

创建自己的 CSS 网格系统 - 图1

我们可以看到,基本网格只包含几个元素:

  • Container(容器)
  • row(行)
  • Column(列)
  • Gutter(列之间的空间)

容器(Container)

创建自己的 CSS 网格系统 - 图2

容器的目的是设置整个网格的宽度。容器的宽度通常为 100%,但你可能希望设置一个最大宽度。
```css .grid-container { width: 100%; max-width: 1200px; }

  1. <a name="a5e63976"></a>
  2. ## 列之间的空间(gutter)
  3. ![](https://cdn.nlark.com/yuque/0/2019/png/213898/1548555257973-3406d58f-a4f2-41a8-8b6f-08d8d59ec85d.png#align=left&display=inline&height=257&originHeight=257&originWidth=458&size=0&status=done&width=458)
  4. row 元素的目的是使其中的列不会溢出到其他行上。为此,我们将使用 clearfix hack 来确保行内的所有内容都保留在行内。
  5. <br />```css
  6. /* 我们的 cleafix hack */
  7. .row: before,
  8. .row: after {
  9. content: "";
  10. display: table;
  11. clear: both;
  12. }

列(Column)

创建自己的 CSS 网格系统 - 图3

column 是网格中最复杂的部分。首先,有几种不同的方法在 CSS 中定位 column,然后有各种宽度要考虑,以及响应式设计等因素。在本教程中,我们将定义 column 并赋予它们宽度。

列定位(Column Positioning)

float, inline-block, display: table, display: flex。这些都是在 CSS 中定位 column 的不同方法。这些方法中最容易出错和最广泛使用的是“浮动”方法。如果我们的列是空的,那么我们的浮动列将堆叠在一起。为了防止这种情况,给 column 提供 1px 的最小高度并使它们浮动。
```css [class*=’col-‘] { float: left; min-height: 1px; }

  1. <br /><a name="89fe4cd3"></a>
  2. ## 列宽(Column Widths)
  3. 要查找一列的宽度,我们所要做的就是将总列数除以容器的宽度。在我们的例子中,容器的宽度是 100%,我们想要6 列,所以 100/6 = 16.66,所以我们的基本列宽度是 16.66%。
  4. <br />```css
  5. [class*='col-'] {
  6. float: left;
  7. min-height: 1px;
  8. width: 16.66%;
  9. }

这当然只是一个开始。如果我们想要一个 2 列宽的部分,我们必须创建一个 2 列宽的 column。计算非常简单。

我们在使用这些列组合时唯一考虑的是,一行中的总列数最多为 6(或者总列数是多少)。

响应式系统中内边距问题

创建自己的 CSS 网格系统 - 图4

在 W3C 标准盒模型条件下,在响应式系统中给宽度单位为百分比的元素设置内边距很麻烦。幸运的是,使用 border-box 模型,我们可以轻松设置内边距。

  1. /* 在网格内的所有元素上改变盒模型 */
  2. .grid-container *{
  3. box-sizing: border-box;
  4. }
  5. [class*='col-'] {
  6. float: left;
  7. min-height: 1px;
  8. width: 16.66%;
  9. /* 设置内边距 */
  10. padding: 12px;
  11. }

使用 * {box-sizing: border-box;} 在 CSS 中改变所有元素的盒模型。

基本网格准备好了

  1. <div class="grid-container outline">
  2. <div class="row">
  3. <div class="col-1"><p>col-1</p></div>
  4. <div class="col-1"><p>col-1</p></div>
  5. <div class="col-1"><p>col-1</p></div>
  6. <div class="col-1"><p>col-1</p></div>
  7. <div class="col-1"><p>col-1</p></div>
  8. <div class="col-1"><p>col-1</p></div>
  9. </div>
  10. <div class="row">
  11. <div class="col-2"><p>col-2</p></div>
  12. <div class="col-2"><p>col-2</p></div>
  13. <div class="col-2"><p>col-2</p></div>
  14. </div>
  15. <div class="row">
  16. <div class="col-3"><p>col-3</p></div>
  17. <div class="col-3"><p>col-3</p></div>
  18. </div>
  19. </div>

CSS

  1. .grid-container{
  2. width: 100%;
  3. max-width: 1200px;
  4. }
  5. /* cleafix hack */
  6. .row:before,
  7. .row:after {
  8. content:"";
  9. display: table ;
  10. clear:both;
  11. }
  12. [class*='col-'] {
  13. float: left;
  14. min-height: 1px;
  15. width: 16.66%;
  16. padding: 12px;
  17. background-color: #FFDCDC;
  18. }
  19. .col-1{ width: 16.66%; }
  20. .col-2{ width: 33.33%; }
  21. .col-3{ width: 50%; }
  22. .col-4{ width: 66.66%; }
  23. .col-5{ width: 83.33%; }
  24. .col-6{ width: 100%; }
  25. .outline,
  26. .outline *{
  27. outline: 1px solid #F6A1A1;
  28. }
  29. /* 一些额外的列内容样式 */
  30. [class*='col-'] > p {
  31. background-color: #FFC2C2;
  32. padding: 0;
  33. margin: 0;
  34. text-align: center;
  35. color: white;
  36. }

HTML

  1. <div class="grid-container outline">
  2. <div class="row">
  3. <div class="col-1"><p>col-1</p></div>
  4. <div class="col-1"><p>col-1</p></div>
  5. <div class="col-1"><p>col-1</p></div>
  6. <div class="col-1"><p>col-1</p></div>
  7. <div class="col-1"><p>col-1</p></div>
  8. <div class="col-1"><p>col-1</p></div>
  9. </div>
  10. <div class="row">
  11. <div class="col-2"><p>col-2</p></div>
  12. <div class="col-2"><p>col-2</p></div>
  13. <div class="col-2"><p>col-2</p></div>
  14. </div>
  15. <div class="row">
  16. <div class="col-3"><p>col-3</p></div>
  17. <div class="col-3"><p>col-3</p></div>
  18. </div>
  19. </div>

使我们的网格系统响应

调整我们的网格以实现移动布局非常简单。我们所要做的就是调整列的宽度。为了简单起见,我将为 800px 以下的屏幕加倍列宽。唯一需要注意的是一些例外,例如:大于 col-3 的列在视口小于 800px 时铺满。

  1. @media all and (max-width:800px){
  2. .col-1{ width: 33.33%; }
  3. .col-2{ width: 50%; }
  4. .col-3{ width: 83.33%; }
  5. .col-4{ width: 100%; }
  6. .col-5{ width: 100%; }
  7. .col-6{ width: 100%; }
  8. .row .col-2:last-of-type{
  9. width: 100%;
  10. }
  11. .row .col-5 ~ .col-1{
  12. width: 100%;
  13. }
  14. }

对于小于 650px 的屏幕。

  1. @media all and (max-width:650px){
  2. .col-1{ width: 50%; }
  3. .col-2{ width: 100%; }
  4. .col-3{ width: 100%; }
  5. .col-4{ width: 100%; }
  6. .col-5{ width: 100%; }
  7. .col-6{ width: 100%; }
  8. }

我们现在创建了自己的响应式网格系统,而不使用框架。

  1. <div class="grid-container outline">
  2. <div class="row">
  3. <div class="col-1"><p>col-1</p></div>
  4. <div class="col-1"><p>col-1</p></div>
  5. <div class="col-1"><p>col-1</p></div>
  6. <div class="col-1"><p>col-1</p></div>
  7. <div class="col-1"><p>col-1</p></div>
  8. <div class="col-1"><p>col-1</p></div>
  9. </div>
  10. <div class="row">
  11. <div class="col-2"><p>col-2</p></div>
  12. <div class="col-2"><p>col-2</p></div>
  13. <div class="col-2"><p>col-2</p></div>
  14. </div>
  15. <div class="row">
  16. <div class="col-3"><p>col-3</p></div>
  17. <div class="col-3"><p>col-3</p></div>
  18. </div>
  19. <div class="row">
  20. <div class="col-4"><p>col-4</p></div>
  21. <div class="col-2"><p>col-2</p></div>
  22. </div>
  23. <div class="row">
  24. <div class="col-5"><p>col-5</p></div>
  25. <div class="col-1"><p>col-1</p></div>
  26. </div>
  27. <div class="row">
  28. <div class="col-6"><p>col-6</p></div>
  29. </div>
  30. </div>

注意:本指南只是创建自己响应式网格系统的起点。它不是一个框架,甚至不是一个完整的解决方案,我希望它能够揭开 CSS 网格的神秘面纱。

参考

【1】Creating Your Own CSS Grid System | Jan