栅格化系统的原理以及实现

更多技术文章什么是栅格化在一个有限的、固定的平面上,用水平线和垂直线(虚拟的线,“参考线”),将平面划分成有规律的一系列“格子”(虚拟的格子),并依托这些格子、或以格子的边线为基准线,来进行有规律的版面布局。通俗点来说,就是人为的把网页中的一行,等比例划分,比如将一行划分为 12 等分。然后在每个格子里进行页面开发,这就栅格化。原理假如在页面里定义了一个 DIV,并设置如下 CSS 属性:div { border: 1px solid #ddd; height: 200px; width: 100%;}页面上将会展示一个带有灰色边框的,宽度 100% 的矩形。如果手动控制浏览器放大缩小,此 DIV 也会相应的放大缩小,但宽度始终是 100%。如果在页面定义了两个 DIV,并设置如下 CSS 属性:body { font-size: 0; // 将inline-block布局两个DIV之间的距离清除}div { height: 200px; border: 1px solid #ddd; width: 50%; display: inline-block; box-sizing: border-box; vertical-align: top; // 顶部对齐}页面上将会有两个宽度各占 50% 的 DIV,如果页面放大或缩小,这两个 DIV 都会始终保持着页面 50% 的宽度。相信到这里,应该有人看出来了,这就是栅格化,只不过第一个例子是将一行划分为 1 等分,即只有一个格子。第二个例子将一行划分为 2 等分,即有两个格子。如果我将一行划分为 12 等分,那就跟 bootstrap 中的栅格化系统一模一样了,有 12 个格子。实现让我们来亲自实现一个栅格化系统,假设我们要将一行划分为 12 等分,那 1 等分就占有 100% / 12 = 8.33% 的宽度。相应的 CSS 可以这样设置:.col1 {width: 8.33%}.col2 {width: 16.66%}.col3 {width: 25%}.col4 {width: 33.33%}.col5 {width: 41.66%}.col6 {width: 50%}.col7 {width: 58.33%}.col8 {width: 66.66%}.col9 {width: 75%}.col10 {width: 83.33%}.col11 {width: 91.66%}.col12 {width: 100%}上一个完整的示例来看看吧:<html lang=“en”><head> <meta charset=“UTF-8”> <title>Title</title> <style> body { margin: 0; } .app { font-size: 0; } .app div { box-sizing: border-box; border: 1px solid red; height: 200px; display: inline-block; vertical-align: top; } .col1 {width: 8.33%} .col2 {width: 16.66%} .col3 {width: 25%} .col4 {width: 33.33%} .col5 {width: 41.66%} .col6 {width: 50%} .col7 {width: 58.33%} .col8 {width: 66.66%} .col9 {width: 75%} .col10 {width: 83.33%} .col11 {width: 91.66%} .col12 {width: 100%} </style></head><body> <div class=“app”> <!– 4个div 占满一行 –> <div class=“col1”></div> <div class=“col2”></div> <div class=“col3”></div> <div class=“col6”></div> </div></script></body></html>最后呈现出来的效果是这样的。怎么样?是不是很简单。进阶结合 @media 媒体查询,我们可以做得更多。@media 详情请看MDN相信用过 bootstrap 栅格化系统的都知道,在 bootstrap 栅格化系统中,有一些 col-md col-sm 属性,它们是干什么用的呢?其实,它们都是栅格化系统的 CSS 类名,只是针对了不同的屏幕宽度。假如我们有这样的一个需求:在 PC 上,因为屏幕比较大,我们要求一行显示 4 列的内容。但是在手机上,因为屏幕比较小,要求一行显示 3 列的内容。即一个网站同时适配 PC 和手机端,根据不同的端自动调整页面。此时,我们可以这样做:<html lang=“en”><head> <meta charset=“UTF-8”> <title>Title</title> <style> body { margin: 0; } .app { font-size: 0; } .app div { box-sizing: border-box; border: 1px solid red; height: 200px; display: inline-block; vertical-align: top; } /* 针对屏幕分辨率大于等于1200的 / @media (min-width: 1200px) { .col-md1 {width: 8.33%} .col-md2 {width: 16.66%} .col-md3 {width: 25%} .col-md4 {width: 33.33%} .col-md5 {width: 41.66%} .col-md6 {width: 50%} .col-md7 {width: 58.33%} .col-md8 {width: 66.66%} .col-md9 {width: 75%} .col-md10 {width: 83.33%} .col-md11 {width: 91.66%} .col-md12 {width: 100%} } / 针对屏幕分辨率小于1200的 */ @media (max-width: 1199px) { .col-sm1 {width: 8.33%} .col-sm2 {width: 16.66%} .col-sm3 {width: 25%} .col-sm4 {width: 33.33%} .col-sm5 {width: 41.66%} .col-sm6 {width: 50%} .col-sm7 {width: 58.33%} .col-sm8 {width: 66.66%} .col-sm9 {width: 75%} .col-sm10 {width: 83.33%} .col-sm11 {width: 91.66%} .col-sm12 {width: 100%} } </style></head><body> <div class=“app”> <div class=“col-md3 col-sm4”></div> <div class=“col-md3 col-sm4”></div> <div class=“col-md3 col-sm4”></div> <div class=“col-md3 col-sm4”></div> </div></script></body></html>一个 DIV,同时设置两个类名。当屏幕 >=1200px 时,一行显示 4 列,当屏幕 <1200px 时,一行显示3列,而且是浏览器自动调整。一个栅格化系统就这样实现了。练习任务对于栅格化的介绍就到此结束了,但如果你看完文章后什么都不做,不到一周,就会把学到的知识忘得七七八八,为了帮助你巩固知识,特地布置了一个小任务,按要求实现如下页面:图一图二任务要求:当页面大于 768px 时,页面如图1所示。当页面小于等于 768px 时, 页面如图2所示。这里是答案和在线DEMO,但是最好先试试能不能自己做出来,如果实在做不出来,再看答案。 ...

April 4, 2019 · 2 min · jiezi

创建自己的 CSS 网格系统【转载 | 译】

此文翻译自 Creating Your Own CSS Grid System | Jan,英文不好如有错误 ✖ ,请指正。CSS 网格已经存在很长时间了。它们通常捆绑在 Bootstrap 等框架中。我不是一个 Bootstrap 仇恨者,但如果你真正需要的只是一个网格,有时使用一个框架就“太过分”了。以下是如何从头开始制作自己的 CSS 网格。CSS 网格的元素我们可以看到,基本网格只包含几个元素:Container(容器)row(行)Column(列)Gutter(列之间的空间)容器(Container)容器的目的是设置整个网格的宽度。容器的宽度通常为 100%,但你可能希望设置一个最大宽度。.grid-container { width: 100%; max-width: 1200px;}列之间的空间(gutter)row 元素的目的是使其中的列不会溢出到其他行上。为此,我们将使用 clearfix hack 来确保行内的所有内容都保留在行内。/* 我们的 cleafix hack /.row: before,.row: after { content: “”; display: table; clear: both;}列(Column)column 是网格中最复杂的部分。首先,有几种不同的方法在 CSS 中定位 column,然后有各种宽度要考虑,以及响应式设计等因素。在本教程中,我们将定义 column 并赋予它们宽度。列定位(Column Positioning)float, inline-block, display: table, display: flex。这些都是在 CSS 中定位 column 的不同方法。这些方法中最容易出错和最广泛使用的是“浮动”方法。如果我们的列是空的,那么我们的浮动列将堆叠在一起。为了防止这种情况,给 column 提供 1px 的最小高度并使它们浮动。[class=‘col-’] { float: left; min-height: 1px; }列宽(Column Widths)要查找一列的宽度,我们所要做的就是将总列数除以容器的宽度。在我们的例子中,容器的宽度是 100%,我们想要6 列,所以 100/6 = 16.66,所以我们的基本列宽度是 16.66%。[class*=‘col-’] { float: left; min-height: 1px; width: 16.66%; }这当然只是一个开始。如果我们想要一个 2 列宽的部分,我们必须创建一个 2 列宽的 column。计算非常简单。我们在使用这些列组合时唯一考虑的是,一行中的总列数最多为 6(或者总列数是多少)。响应式系统中内边距问题在 W3C 标准盒模型条件下,在响应式系统中给宽度单位为百分比的元素设置内边距很麻烦。幸运的是,使用 border-box 模型,我们可以轻松设置内边距。 /* 在网格内的所有元素上改变盒模型 /.grid-container { box-sizing: border-box; }[class=‘col-’] { float: left; min-height: 1px; width: 16.66%; / 设置内边距 / padding: 12px;}使用 * {box-sizing: border-box;} 在 CSS 中改变所有元素的盒模型。基本网格准备好了<div class=“grid-container outline”> <div class=“row”> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> </div> <div class=“row”> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> </div> <div class=“row”> <div class=“col-3”><p>col-3</p></div> <div class=“col-3”><p>col-3</p></div> </div> </div>CSS.grid-container{ width: 100%; max-width: 1200px;}/ cleafix hack /.row:before,.row:after { content:""; display: table ; clear:both;}[class=‘col-’] { float: left; min-height: 1px; width: 16.66%; padding: 12px; background-color: #FFDCDC;}.col-1{ width: 16.66%; }.col-2{ width: 33.33%; }.col-3{ width: 50%; }.col-4{ width: 66.66%; }.col-5{ width: 83.33%; }.col-6{ width: 100%; }.outline, .outline { outline: 1px solid #F6A1A1;}/ 一些额外的列内容样式 /[class=‘col-’] > p { background-color: #FFC2C2; padding: 0; margin: 0; text-align: center; color: white;}HTML<div class=“grid-container outline”> <div class=“row”> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> </div> <div class=“row”> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> </div> <div class=“row”> <div class=“col-3”><p>col-3</p></div> <div class=“col-3”><p>col-3</p></div> </div></div>使我们的网格系统响应调整我们的网格以实现移动布局非常简单。我们所要做的就是调整列的宽度。为了简单起见,我将为 800px 以下的屏幕加倍列宽。唯一需要注意的是一些例外,例如:大于 col-3 的列在视口小于 800px 时铺满。@media all and (max-width:800px){ .col-1{ width: 33.33%; } .col-2{ width: 50%; } .col-3{ width: 83.33%; } .col-4{ width: 100%; } .col-5{ width: 100%; } .col-6{ width: 100%; } .row .col-2:last-of-type{ width: 100%; } .row .col-5 ~ .col-1{ width: 100%; }}对于小于 650px 的屏幕。@media all and (max-width:650px){ .col-1{ width: 50%; } .col-2{ width: 100%; } .col-3{ width: 100%; } .col-4{ width: 100%; } .col-5{ width: 100%; } .col-6{ width: 100%; }}我们现在创建了自己的响应式网格系统,而不使用框架。<div class=“grid-container outline”> <div class=“row”> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> <div class=“col-1”><p>col-1</p></div> </div> <div class=“row”> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> <div class=“col-2”><p>col-2</p></div> </div> <div class=“row”> <div class=“col-3”><p>col-3</p></div> <div class=“col-3”><p>col-3</p></div> </div> <div class=“row”> <div class=“col-4”><p>col-4</p></div> <div class=“col-2”><p>col-2</p></div> </div> <div class=“row”> <div class=“col-5”><p>col-5</p></div> <div class=“col-1”><p>col-1</p></div> </div> <div class=“row”> <div class=“col-6”><p>col-6</p></div> </div></div>注意:本指南只是创建自己响应式网格系统的起点。它不是一个框架,甚至不是一个完整的解决方案,我希望它能够揭开 CSS 网格的神秘面纱。参考【1】Creating Your Own CSS Grid System | Jan ...

January 27, 2019 · 2 min · jiezi