手寫一個簡單的響應式柵格
前言
前段時間一衝動搞了個騰訊雲主機,最簡單的配置那種。買完之後一陣折騰,想著不如整個部落格,於是各種部落格搭建方案,看著好多漂亮的部落格,毅然決定搭建一個自己的部落格,正好自己是一個前端新手,寫一個這樣的部落格,正好能鍛鍊自己,說幹就幹,開始逐個解決技術難點。這次我解決的自制響應式柵格。
什麼是柵格系統
在許多前端框架裡,我們都能見到css柵格系統,如Bootstrap,pure等等,通過柵格系統可以實現多種裝置的響應式佈局。那啥是柵格系統?話不多說直接引用。
柵格系統(CSS Grids)是一種運用固定的格子設計版面佈局,在報刊雜誌上尤為常見。 如今響應式設計大行其道,對於前端開發,柵格系統可以:
- 提高生產力,通過在網格的劃分,元素更容易堆放而且在跨瀏覽器上面具有一致性,使我們可以專心的注意佈局而不是相容上。
- 具有靈活性,無論是什麼樣的佈局,都可以拆分到粒度為一個網格的大小。
- 支援響應式設計,柵格系統本身能很好的和響應式設計結合在一起,或者說,我們的柵格系統是基於響應式設計的。
著作權歸作者所有。 商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。 原文: liaokeyu.com/技術/2017/01/…
響應式實現方案
響應式實現方案有許多種,大家也可以去查查,我的實現想法主要有三個關鍵點。
- 媒體查詢
- 浮動
- 流式佈局
媒體查詢
媒體查詢(Media Query)是CSS提出來的一個新的屬性,通過媒體查詢可以查詢到screen的寬度,從而指定某個寬度區間的網頁佈局。
具體實現方式如下:
/*查詢螢幕*/
@media screen and 條件 {
}
/*條件的寫法*/
/*min-width:只要螢幕寬度超過這個值的裝置樣式就能生效*/
/*max-width:只要螢幕寬度小於這個值的裝置樣式就能生效*/
/* 表示可見區域大於1200px樣式生效 */
@media screen and (min-width: 1200px) {
.container {
width: 1170px;
background-color: red;
}
}
/* 表示可見區域大於992px小於1200px樣式生效 */
@media screen and (min-width: 992px ) and (max-width: 1200px) {
.container {
width: 970px;
background-color: blue;
}
}
複製程式碼
流式佈局
流式佈局,也叫百分比佈局,是移動端開發中經常使用的佈局方式之一。
流式佈局的特徵:
- 寬度自適應,高度寫死,並不是百分百還原設計圖
- 圖示都是固定死大小的,包括字型等也是固定死的。並不是所有的東西都是自適應的。
- 一些大的圖片,設定寬度為百分比自適應即可,隨著螢幕大小進行變化
比如,以下程式碼能實現子盒子在可視區中各佔四分之一:
<body>
<div class="container">
<div class="child-one"></div>
<div class="child-two"></div>
<div class="child-three"></div>
<div class="child-four"></div>
</div>
</body>
複製程式碼
.container {
width: 100%;
}
.child-one {
width: 25%;
}
.child-two {
width: 25%;
}
.child-three {
width: 25%;
}
.child-four {
width: 25%;
}
複製程式碼
程式設計實現
定義
當前的主流裝置的螢幕從大概尺寸如下:
- 大屏裝置(>1200px)
- 中屏裝置(992-1200)
- 小屏裝置(768-992)
- 超小屏裝置(<768px)
為了自己的部落格的佈局不需要適配那麼多裝置,根據實際需求,於是就採用三個寬度來定義大、中、小屏和超大屏。
- 小於768px的小屏(sm)
- 大於768px小於960px的中屏(md)
- 大於960px小於1280px的大屏(lg)
- 大於1280px的超大屏
跟隨大眾採用 12 欄形式的柵格,所以-sm-
、-md-
、-lg-
形式的樣式表示小、中、大屏的樣式。
-
小屏隱藏: 表示在小屏隱藏,其他屏顯示
hidden-sm
-
中屏隱藏: 表示在中屏隱藏,其他屏顯示
hidden-md
-
大屏隱藏: 表示在大屏隱藏,其他屏顯示
hidden-lg
-
小屏顯示: 表示在小屏顯示,其他屏隱藏
visible-sm
-
中屏顯示: 表示在小屏顯示,其他屏隱藏
visible-md
-
大屏顯示: 表示在小屏顯示,其他屏隱藏
visible-lg
初始化樣式
為了節省計算於是使用了less
,只是簡單應用了巢狀和變數。直接看程式碼註釋?
/* 設定單位寬度 */
@unit-width: 100%/12;
/* 設定容器居中,寬100% */
.container {
width: 100%;
margin-left: auto;
margin-right: auto;
/* 盒子內減,減少不必要的寬高計算 */
* {
box-sizing: border-box;
}
}
/* 設定行寬100% */
.row {
position: relative;
width: 100%;
padding: 15px;
}
/*設定各列浮動,以及間隔*/
.row [class^="col"] {
float: left;
padding: 15px;
min-height: 1px;
}
/* 清除浮動 */
.row::after {
content: "";
display: table;
clear: both;
}
複製程式碼
小屏樣式
小屏樣式表示在小於768px情況下的樣式
-
col-1
表示在大屏以上的螢幕佔 1/12 -
col-1-md
表示在中屏以上的螢幕佔 1/12 -
col-1-sm
表示在小屏以上的螢幕佔 1/12
/* 大屏和中屏的樣式初始樣式,
小屏情況下,擁有這些樣式的元素會佔據一整行,
簡而言之,就是依次橫著排列變成依次豎著排列 */
.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col-1-md,.col-2-md,.col-3-md,.col-4-md,.col-5-md,.col-6-md,.col-7-md,.col-8-md,.col-9-md,.col-10-md,.col-11-md,.col-12-md {
width: 12 * @unit-width;
}
/*使用這些樣式的元素在小屏情況下*/
.col-1-sm {
width: @unit-width;
}
.col-2-sm {
width: 2 * @unit-width;
}
.col-3-sm {
width: 3 * @unit-width;
}
.col-4-sm {
width: 4 * @unit-width;
}
.col-5-sm {
width: 5 * @unit-width;
}
.col-6-sm {
width: 6 * @unit-width;
}
.col-7-sm {
width: 7 * @unit-width;
}
.col-8-sm {
width: 8 * @unit-width;
}
.col-9-sm {
width: 9 * @unit-width;
}
.col-10-sm {
width: 10 * @unit-width;
}
.col-11-sm {
width: 11 * @unit-width;
}
.col-12-sm {
width: 12 * @unit-width;
}
/* 隱藏 和顯示樣式*/
.hidden-sm,.visible-lg,.visible-md {
display: none;
}
/* 小屏可見 */
.hidden-md,.hidden-lg,.visible-sm {
display: block;
}
複製程式碼
中屏樣式
/* 媒體查詢 大於768px生效*/
@media only screen and (min-width: 768px) {
/* 中屏的容器,版心 */
.container {
width: 96%;
}
/* 中屏時,該樣式會覆蓋之前的樣式,實現中屏的樣式 */
.col-1-md {
width: @unit-width;
}
.col-2-md {
width: 2 * @unit-width;
}
.col-3-md {
width: 3 * @unit-width;
}
.col-4-md {
width: 4 * @unit-width;
}
.col-5-md {
width: 5 * @unit-width;
}
.col-6-md {
width: 6 * @unit-width;
}
.col-7-md {
width: 7 * @unit-width;
}
.col-8-md {
width: 8 * @unit-width;
}
.col-9-md {
width: 9 * @unit-width;
}
.col-10-md {
width: 10 * @unit-width;
}
.col-11-md {
width: 11 * @unit-width;
}
.col-12-md {
width: 12 * @unit-width;
}
.hidden-sm,.visible-md {
display: block;
}
.hidden-md,.visible-sm,.visible-lg {
display: none;
}
}
複製程式碼
大屏樣式
/* 媒體查詢 大於960px生效*/
@media only screen and (min-width: 960px) {
/* 大屏的容器,版心 */
.container {
width: 90%;
}
/* 大屏時,該樣式會覆蓋之前的樣式,實現大屏的樣式 */
.col-1 {
width: @unit-width;
}
.col-2 {
width: 2 * @unit-width;
}
.col-3 {
width: 3 * @unit-width;
}
.col-4 {
width: 4 * @unit-width;
}
.col-5 {
width: 5 * @unit-width;
}
.col-6 {
width: 6 * @unit-width;
}
.col-7 {
width: 7 * @unit-width;
}
.col-8 {
width: 8 * @unit-width;
}
.col-9 {
width: 9 * @unit-width;
}
.col-10 {
width: 10 * @unit-width;
}
.col-11 {
width: 11 * @unit-width;
}
.col-12 {
width: 12 * @unit-width;
}
.hidden-lg,.visible-md {
display: none;
}
.hidden-md,.visible-lg {
display: block;
}
}
複製程式碼
超大屏樣式
/* 超大屏沒有適配,直接給個版心就好 */
@media only screen and (min-width: 1280px) {
.container {
width: 85%;
max-width: 1280px;
}
}
複製程式碼
效果展示
寫完樣式要做個測試,來看看效果,demo 程式碼如下:
<style>
div [class^="col"] {
border: 2px solid #000;
}
.row {
border: 2px solid red;
}
</style>
/************************************/
<div class="container">
<div class="row">
<div class="col-4">
<h5>大屏樣式</h5>
</div>
<div class="col-4-md">
<h5>中屏樣式</h5>
</div>
<div class="col-4-sm">
<h5>小屏樣式</h5>
</div>
</div>
<div class="row">
<div class="col-4-sm hidden-lg">
<h5>大屏隱藏</h5>
</div>
<div class="col-4-sm hidden-md">
<h5>中屏隱藏</h5>
</div>
<div class="col-4-sm hidden-sm">
<h5>小屏隱藏</h5>
</div>
</div>
<div class="row">
<div class="col-4-sm visible-lg">
<h5>大屏顯示</h5>
</div>
<div class="col-4-sm visible-md">
<h5>中屏顯示</h5>
</div>
<div class="col-4-sm visible-sm">
<h5>小屏顯示</h5>
</div>
</div>
</div>
複製程式碼
大功告成! ✌
參考文章和開源專案: