💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 响应式之栅格系统 1. 为什么响应式开发需要栅格化? 2. 栅格化解决了什么问题? 3. 栅格化是怎么工作,是怎样解决问题的? 4. 怎么使用合适的栅格化类? 阅读完本文后,相信你就会有这些问题的答案了。 ***** https://v3.bootcss.com/css/#grid-media-queries ```css /* 超小屏幕(手机,小于 768px) */ /* 没有任何媒体查询相关的代码,因为这在 Bootstrap 中是默认的(还记得 Bootstrap 是移动设备优先的吗?) */ /* 小屏幕(平板,大于等于 768px) */ @media (min-width: @screen-sm-min) { ... } /* 中等屏幕(桌面显示器,大于等于 992px) */ @media (min-width: @screen-md-min) { ... } /* 大屏幕(大桌面显示器,大于等于 1200px) */ @media (min-width: @screen-lg-min) { ... } ``` 移动优先,样式先从移动端开始写,没有查询代码,默认就代表为移动端准备的。然后依次考虑屏幕变大,逐步覆盖、重写样式以满足屏幕越大时的样式,当然 “偶尔也会在媒体查询代码中包含 max-width 从而将 CSS 的影响限制在更小范围的屏幕大小之内。” ![](http://cdn.aipin100.cn/18-11-15/97968706.jpg) bootstrap 系统的栅格化起作用是通过作用于元素的 `width: {0~100}%` 和 `float: left` 两个样式(布局样式)而生效的。为元素添加这两种样式属性达到栅格效果,我们将这种方式称之为 **栅格作用** ,而 栅格作用 是有 阈值 的,只有在屏幕满足阈值 时 栅格作用才会生效(即 `>=阈值`),`.col-xs-`、`.col-sm-`、`.col-md-`、`.col-lg-` 就是用来控制这个 栅格作用 生效的 阈值的(我们称之为 `阈值类`)。 比如:`.col-md-` 表示 在 `中等屏幕 桌面显示器 (≥992px)` 时 适配元素才会具有 栅格作用。所以你看到的效果就是,在屏幕 ≥992px 时,适配元素具有 栅格的列排列效果(`width: {0~100}%` 和 `float: left`),在屏幕 <992px 时,适配元素不在具有 栅格作用,变的和普通元素一样(`width: 100%; `),就是普通的块级元素,不在水平排列,而是独占一行,即传统的行排列。 那么 这个通过 阈值(阈值类) 来控制 栅格作用 是否有效 的做法有什么用呢?要回答这个问题,就要弄清楚下面这些问题? **Q:手机和平板、PC的区别?** A:我们知道,移动网站的布局不能照搬PC上的布局,手机屏幕比较窄,与PC相比,在内容布局上就有很大的差异,PC上很多左右水平布局,而在手机上,为了不出现水平滚动条,内容更多是单行排列(较小的内容也可以水平排列,这也是我们栅格化解决的问题之一)。平板介于手机和PC的中间。 **Q:为什么你想将某些元素水平排列?** A:水平排列可以展示更多的信息,通常只要屏幕足够宽,我们就越想利用水平排列以展示更多内容。 **Q:为什么你想让一个元素总是水平排列?** A:这个元素比较小,我认为即使屏幕再小也能显示。 **Q:为什么你要控制某些元素只在大屏幕中才水平排列显示?** 这个元素比较大,我认为小屏幕下水平一行展示不了(会出现水平滚动条或溢出截断),所以只在大屏幕下水平排列,小屏幕下还是传统的行排列。 **Q:为什么有时候用多个 阈值(多个`.col-`)来控制 元素的 栅格作用 是否有效?** 在屏幕越小的过程中,`.col-lg-`、`.col-md-`、`.col-sm-` **是逐渐媒体查询失效的** (**注意 `.col-xs-` 自始至终都不会失效,而是被覆盖的,要知道它不在媒体查询之内哦**),所以如果你想让元素在屏幕越小的这个过程中 保持 栅格作用,那么你就需要 多个 阈值来控制。 反之 在屏幕越大的过程中,`.col-xs-`、`.col-sm-`、`.col-md-`、`.col-lg-` **是逐渐被媒体查询覆盖的**。 反复体验这个屏幕变化的过程,你就会知道在什么时候为元素使用合适的 阈值类名了。 **换句话来说,就是 你想为多种设备 提供不同的 展示效果,想让元素在不同设备下有不同的显示效果。** 一般情况下,我们只使用 `.col-sm-`就可以了,只区分手机就行了,平板和PC都展示一样的效果,即表示我们只区分 **是否为手机** (PC有栅格效果,手机版为传统的行排列)。 ***** ### 栅格系统-特性实例demo https://material.io ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <style> // 注意这在 bootstrap.min.css 的前面 ,以不影响栅格类,满足bootstrap的栅格条件时会被覆盖的 [class*=col-] { // 过度效果让你更好的观察到栅格元素的布局变化 transition: all 0.3s ease-in-out; // 事实上100%为块级元素的默认值,这里显式的声明下,以配合后面的栅格以实现过度效果 width: 100%; } .demo .demo-wrap { margin: 30px auto; border: 1px #dedede dashed; } .demo .demo-wrap .demo-content { height: 100px; line-height: 100px; color: #fff; text-align: center; border-radius: 15px; transition: all 0.3s ease-in-out; margin: 20px 0; overflow: hidden; } .demo .demo-wrap:nth-child(1) .demo-content { background-color: #ff86b1; } .demo .demo-wrap:nth-child(2) .demo-content { background-color: #5179ff; } .demo .demo-wrap:nth-child(3) .demo-content { background-color: #1fb729; } .demo .demo-wrap:nth-child(4) .demo-content { background-color: #fba223; } .demo .demo-wrap:nth-child(5) .demo-content { background-color: #b749ff; } </style> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> </head> <body> <div class="demo"> <div class="container demo-wrap"> <div class="row"> <div class="col-xs-8 col-sm-4 col-md-4 col-lg-4"><div class="demo-content">col-xs-8 col-sm-4 col-md-4 col-lg-4</div></div> <div class="col-xs-4 col-sm-4 col-md-4 col-lg-4"><div class="demo-content">col-xs-4 col-sm-4 col-md-4 col-lg-4</div></div> <div class="col-xs-12 col-sm-4 col-md-4 col-lg-4"><div class="demo-content">col-xs-12 col-sm-4 col-md-4 col-lg-4</div></div> </div> </div> <div class="container demo-wrap"> <div class="row"> <div class="col-xs-4"><div class="demo-content">col-xs-4</div></div> <div class="col-xs-4"><div class="demo-content">col-xs-4</div></div> <div class="col-xs-4"><div class="demo-content">col-xs-4</div></div> </div> </div> <div class="container demo-wrap"> <div class="row"> <div class="col-sm-4"><div class="demo-content">col-sm-4</div></div> <div class="col-sm-4"><div class="demo-content">col-sm-4</div></div> <div class="col-sm-4"><div class="demo-content">col-sm-4</div></div> </div> </div> <div class="container demo-wrap"> <div class="row"> <div class="col-md-4"><div class="demo-content">col-md-4</div></div> <div class="col-md-4"><div class="demo-content">col-md-4</div></div> <div class="col-md-4"><div class="demo-content">col-md-4</div></div> </div> </div> <div class="container demo-wrap"> <div class="row"> <div class="col-lg-4"><div class="demo-content">col-lg-4</div></div> <div class="col-lg-4"><div class="demo-content">col-lg-4</div></div> <div class="col-lg-4"><div class="demo-content">col-lg-4</div></div> </div> </div> </div> </body> </html> ``` ***** ### 响应式开发注意事项 #### 1. 移动优先:媒体查询代码的书写顺序 >[tip] **注意移动优先,任何时候,媒体查询代码都有写在后面,否则因为css覆盖特性而可能不会生效,而不在媒体查询之内的代码默认就为移动端的。** (媒体查询代码的书写顺序对css覆盖特性的影响和普通代码是一样的) ```css .login-btn { border: 1px #828282 solid; padding: 5px 12px !important; border-radius: 15px; font-size: 15px; margin-top: 18px; } /* 平板时的导航样式 768px <= x < 992px */ @media (min-width: 768px) and (max-width: 992px) { .navbar .container { width: 100%; } .navbar-nav>li>a { padding: 20px; } .login-btn { // 如果顺序不对,这里会被覆盖 margin-top: 13px; } } -------------------------- 要特别注意以下书写规则,不按照这个规则书写,会有问题 @media (min-width: a){} @media (min-width: b){} @media (min-width: c){} 这里 a < b < c @media (max-width: a){} @media (max-width: b){} @media (max-width: c){} 这里 c < b < a ``` #### 2. 媒体查询代码要写精确 如果你发现需要经常使用 `!important`,则要思考是不是你的媒体查询代码写的不够精确,要知道这可不是一个好的信号,过多的 `!important` 会使你的代码在不知不觉中陷入这种优先级争夺的泥潭中。大多数情况下,只要媒体查询代码写精确了(**有区间限定值**),都是可以避免 `!important` 的,只有特殊情况下,在没有更好的办法了时才用它。 比如: ```css // 默认没有媒体查询即为手机 // 1. 平板 // 没有区间限定值时表示并不准确,例如:此时不只表示为 平板,还可能为桌面显示器、大桌面显示器;没有限定区间的媒体查询都可能表示多种设备 @media (min-width: 768px) {} // 2. 平板 @media (min-width: 768px) and (max-width: 992px) {} // 中等屏幕 桌面显示器 @media (min-width: 992px) and (max-width: 1200px) {} // 大屏幕 大桌面显示器 @media (min-width: 1200px) {} ``` 显然使用第二种媒体查询表示平板要更加精确,使用精确的媒体查询能避免后面很多不必要的麻烦。 #### 3. 移动优先 移动优先,通常都是在媒体查询里面写布局样式,不在媒体查询里面的代码,直接就是移动端的和元素本来的基本样式,因为元素形态样式不论多大屏幕小都是相同的,不同的基本都是布局样式和大小等。当然也有例外,那就是你想让某元素在不同屏幕下呈现不同的效果,这也没什么不可以,但是通常这种情况很少见,因为这不能使移动端到pc端过度时,页面整体内容保持一致,这就像是两个网站了。 **bootstrap 是如何体现自己是移动优先的?** ```css .collapse { display: none; } @media (min-width: 768px) bootstrap.css:4186 .navbar-collapse.collapse { display: block!important; height: auto!important; padding-bottom: 0; overflow: visible!important; } ``` 先直接定义的就是移动端的,然后才是大屏幕的。 #### 4. 如果不想重用 https://v3.bootcss.com/css/#grid-media-queries ```css /* 超小屏幕(手机,小于 768px) .col-xs- */ /* .col-xs- 不在媒体查询中 */ /* 没有任何媒体查询相关的代码,因为这在 Bootstrap 中是默认的(还记得 Bootstrap 是移动设备优先的吗?) */ /* 但是如果不想重用,或实际重用较少,导致需要覆盖太多属性比较麻烦时,也可以用媒体查询 */ /* 另外在实际编码时往往很难严格的遵守“移动优先”(没有任何媒体查询相关的代码就是移动端的代码)的编码方式,所以也可以违背常规,此时也需要用媒体查询 */ /* 超小屏幕(手机,小于 768px) */ @media (max-width: 768px) { /* 不需要重用的属性 */ /* ... */ } /* 小屏幕(平板,大于等于 768px) .col-sm- */ @media (min-width: 768px) {} /* 中等屏幕(桌面显示器,大于等于 992px) .col-md- */ @media (min-width: 992px) {} /* 大屏幕(大桌面显示器,大于等于 1200px) .col-lg- */ @media (min-width: 1200px) {} ``` 15英寸笔记本屏幕一般为 `1366px` >[tip] <768px 时导航折叠,=768px 时不会折叠,而iPad刚好是 768px ,所以这里写代码时要注意一下。(还有栅格化生效的节点也包括等于,有时这也需要注意) ***** ### 扩展 [Bootstrap栅格系统详解,响应式布局 - 流风,飘然的风 - 博客园](https://www.cnblogs.com/zdz8207/p/Bootstrap-row-container.html) > Bootstrap 栅格系统的精妙之处, 通过container, row, column都有15px的padding槽边和 row的margin -15px设置,巧妙实现在 column 中嵌套 row进行nesting 扩展(超过12列),而不需要再套一层 container > > 正确使用:container > row > column 或 column > row > column (因为column 和 container 有同样的内补) [手机屏幕尺寸大全-25学堂](https://www.25xt.com/screen/phone.html) [一行css代码搞定响应式布局](https://mp.weixin.qq.com/s/oIszJeXGWA0Xfo0SyFqhnA) [关于响应式布局,你必须要知道的](https://mp.weixin.qq.com/s/y0a5t3Kd-GWACRlEg1cprQ) [响应式布局新方案](https://mp.weixin.qq.com/s/qi92_WQz2CaqYHTtvE7SzA) ***** ### 如何学习 学一个东西,一定要有学习过程的学习笔记(提问,思考验证,记录等),然后还要动手实践,并且要做实际项目来印证锻炼。这样才能真正掌握。 (那一晚做梦都是栅格系统布局,屏幕逐渐变大,覆盖,逐渐变小,失效……) ***** last update:2018-12-9 15:08:33