CSS 響應(yīng)式布局系統(tǒng)的實(shí)例代碼

響應(yīng)式布局系統(tǒng),在現(xiàn)在流行的 CSS 框架中已經(jīng)非常常見(jiàn)了。它主要由容器類和約定一行列數(shù)的柵格系統(tǒng)組成,組成了一個(gè)框架的骨架。
在流行的前端框架 Bootstrap 和 Bulma CSS 中,就有體現(xiàn)。像 Bootstrap 的 .container 、 .row 、 .col ;還有 Bulma CSS 的 .container 、 columns 、 column 都是表示這類布局系統(tǒng)。雖然名稱不一樣,但原理都是相同的。
隨著 Flex 布局的普及,幾乎現(xiàn)代的柵格系統(tǒng)的實(shí)現(xiàn)都選擇使用這一靈活的布局方式。
現(xiàn)在就來(lái)看一下,怎樣實(shí)現(xiàn)一個(gè)最小的 CSS 響應(yīng)式布局系統(tǒng)吧。
首先從容器說(shuō)起。
為了保證實(shí)現(xiàn)代碼的簡(jiǎn)潔,本文將使用 SCSS 來(lái)寫。如果你對(duì) SCSS 還不熟悉,沒(méi)有關(guān)系,行文中會(huì)對(duì)使用到的知識(shí)點(diǎn)做介紹。
容器
容器主要用來(lái)包裹網(wǎng)頁(yè)的主要內(nèi)容,常見(jiàn)效果就是將內(nèi)容居中地顯示在屏幕中間。
我們使用 .container 來(lái)約定容器。
首先,容器是水平居中的,這一塊樣式較為容易:
.container { margin-left: auto; margin-right: auto; }
所謂的響應(yīng)式容器,就是根據(jù)不同的斷點(diǎn)(breakpoints),也就是當(dāng)前的視口寬度,來(lái)決定容器使用的 max-width 值。
這里我們借鑒了 Bootstrap 中對(duì)斷點(diǎn)的定義,根據(jù)視口寬度,分為以下幾類設(shè)備:
[0, 576px) [576px, 768px) [768px, 992px) [992px, 1200px) [1200px, +∞)
針對(duì)斷點(diǎn)定義,聲明一個(gè)變量 $breakpoints :
$breakpoints: ( // Extra small screen / phone xs: 0, // Small screen / phone sm: 576px, // Medium screen / tablet md: 768px, // Large screen / desktop lg: 992px, // Extra large screen / wide desktop xl: 1200px );
$breakpoints 稱為“列表”,是 SCSS 提供給我們的數(shù)據(jù)結(jié)構(gòu)。由一個(gè)個(gè) key: value 鍵值對(duì)組成。上例中的 key 表示的是設(shè)備有效范圍的起始點(diǎn)。
不同的設(shè)備下,容器有不同的 max-width 值。所以,這里我們?cè)俾暶饕粋€(gè)表示容器寬度的變量 $container-max-widths :
$container-max-widths: ( xs: none, sm: 540px, md: 720px, lg: 960px, xl: 1140px );
這里的 $container-max-widths 也是個(gè)列表,這里的 key 表示某個(gè)設(shè)備下容器的最大寬度。比如,在超大屏設(shè)備下,容器的最大寬度是 1140px ,而在平常手機(jī)下,不設(shè)置容器的最大寬度,為默認(rèn)值 none 。
有了實(shí)現(xiàn)的思路,接下來(lái)就著手實(shí)現(xiàn)。
我們就可以借助媒體查詢指令 @media ,依據(jù)視口寬度的范圍,給予 .container 不同的 max-width 值。
@each $device, $breakpoint in $breakpoints { @media only screen and (min-width: $breakpoint) { .container { max-width: map-get($container-max-widths, $device); } } }
7 行代碼搞定!
下面解釋下上面的代碼。
我們對(duì)列表遍歷,使用的是 @each...in 語(yǔ)法,每一次遍歷取出對(duì)應(yīng)的 key、value,得到當(dāng)前的 $device 、 $breakpoint 。 map-get 是 SCSS 提供的用來(lái)操作列表的方法:根據(jù) key 取出 value。比如,當(dāng) $device 值為 xs 的時(shí)候, map-get($container-max-widths, $device) 對(duì)應(yīng)值為 none ;當(dāng) $device 值為 sm 的時(shí)候, map-get($container-max-widths, $device) 對(duì)應(yīng)值為 540px ,以此類推。
@media only screen and (min-width: $breakpoint) { ... }
中包含的代碼,表示從當(dāng)前設(shè)備斷點(diǎn)開(kāi)始處,應(yīng)用的 CSS 樣式。 當(dāng)我們同時(shí)按照從小到大的順序設(shè)置兩個(gè)斷點(diǎn)的媒體查詢時(shí),后者會(huì)覆蓋前者的樣式 ,這是實(shí)現(xiàn)不同視口下,具有不同寬度容器的核心原理。
接下來(lái),將得到的寬度值賦給容器的 max-width 屬性就可以了。
到現(xiàn)在為止,我們就寫出了一個(gè)響應(yīng)式容器了,我們總攬下代碼:
$breakpoints: ( // Extra small screen / phone xs: 0, // Small screen / phone sm: 576px, // Medium screen / tablet md: 768px, // Large screen / desktop lg: 992px, // Extra large screen / wide desktop xl: 1200px ); $container-max-widths: ( xs: none, sm: 540px, md: 720px, lg: 960px, xl: 1140px ); .container { margin-left: auto; margin-right: auto; } @each $device, $breakpoint in $breakpoints { @media only screen and (min-width: $breakpoint) { .container { max-width: map-get($container-max-widths, $device); } } }
點(diǎn)擊這里,查看效果。
下面再來(lái)介紹 12 列柵格布局。
12 列柵格布局
先使用 Flex 布局,寫一個(gè)最簡(jiǎn)的等寬布局。
.row { display: flex; .col { flex-grow: 1; flex-basis: 0; } }
沒(méi)錯(cuò),這就是使用 Flex 布局實(shí)現(xiàn)一個(gè)等寬布局的所有代碼了。如果不考慮中間的空白行,只需要 7 行代碼。
這里的原理是,我們將所有 Flex 項(xiàng)目的 flex-basis 設(shè)置為 0 了,就是說(shuō)這些 Flex 項(xiàng)目在 grow 或 shrink 之前都沒(méi)有寬度,是一樣長(zhǎng)的。這樣最終計(jì)算出來(lái)的主軸空間會(huì)平均地分配給了每個(gè) Flex 項(xiàng)目,這樣它們就等寬了。
到這里,我們所寫的這個(gè)簡(jiǎn)易柵格布局有兩個(gè)局限:
1.不能布局非等寬項(xiàng)目。
2.不支持換行。
換行的話很好弄,為 Flex 容器加個(gè) flex-wrap: wrap 就可以了。那怎樣處理“非等寬項(xiàng)目”排列布局呢。
為了能實(shí)現(xiàn)非等寬項(xiàng)目的布局,我們的思路是: 禁用 Flex 項(xiàng)目的伸縮特性,使用百分比 width 指定寬度 。
首先,禁用 Flex 項(xiàng)目的伸縮特性,使用到的屬性如下:
flex-shrink: 0; flex-grow: 0; flex-basis: 0;
這三個(gè)屬性等價(jià)的快捷寫法是:
flex: none;
然后就是使用百分比 width 指定寬度了。
我們實(shí)現(xiàn)的是一行最多 12 列的柵格布局。也就是說(shuō)把一行劃分成 12 列,每一列的寬度大約占總寬度的 8.33% 。我們用 .is-列數(shù) 指定一個(gè)項(xiàng)目占據(jù)的列數(shù):
.is-1
.is-2
.is-3
.is-4
.is-5
.is-6
.is-7
.is-8
.is-9
.is-10
.is-11
.is-12
根據(jù)這個(gè)規(guī)律,我們可以很容易地寫出柵格布局代碼:
$columns: 12; .row { display: flex; .col { flex-grow: 1; flex-basis: 0; @for $i from 1 through 12 { &.is-#{$i} { flex: none; width: percentage($i / 12); } } } }
這里我們使用 @for 指令的 @for $var from <start> through <end>
語(yǔ)法,從 1 遞增到 12,定義了 .is-* 這一系列類名,原理就是我們說(shuō)過(guò)的禁用了 Flex 項(xiàng)目的伸縮特性,指定給它百分比寬度。怎么樣,很簡(jiǎn)單吧。
接下來(lái)再加上折行( .row.is-multiline
)和 Flex 項(xiàng)目偏移( .is-offset-*
)的支持。
我們總攬下代碼:
$columns: 12; .row { display: flex; &.is-multiline { flex-wrap: wrap; } .col { flex-grow: 1; flex-basis: 0; @for $i from 1 through 12 { &.is-#{$i} { flex: none; width: percentage($i / 12); } &.is-offset-#{$i} { margin-left: percentage($i / 12); } } } }
.is-multiline 是跟隨 .row 一起使用的,得到的就是 flex-wrap: wrap 的效果;項(xiàng)目偏移則借助 margin-left
屬性實(shí)現(xiàn)。
到這里,我們的 12 列柵格布局就寫完了 ヾ(◍°∇°◍)ノ゙
完整代碼
我們把上面兩部分的代碼整合起來(lái),就能得到一個(gè)最小的響應(yīng)式布局系統(tǒng)了~ O(∩_∩)O
$breakpoints: ( // Extra small screen / phone xs: 0, // Small screen / phone sm: 576px, // Medium screen / tablet md: 768px, // Large screen / desktop lg: 992px, // Extra large screen / wide desktop xl: 1200px ); $container-max-widths: ( xs: none, sm: 540px, md: 720px, lg: 960px, xl: 1140px ); .container { margin-left: auto; margin-right: auto; } @each $device, $breakpoint in $breakpoints { @media only screen and (min-width: $breakpoint) { .container { max-width: map-get($container-max-widths, $device); } } } $columns: 12; .row { display: flex; &.is-multiline { flex-wrap: wrap; } .col { flex-grow: 1; flex-basis: 0; @for $i from 1 through 12 { &.is-#{$i} { flex: none; width: percentage($i / 12); } &.is-offset-#{$i} { margin-left: percentage($i / 12); } } } }
可以 在此查看效果 。
當(dāng)然,更多其他豐富的功能任君添加,這里只是提供了一個(gè)最簡(jiǎn)單的代碼實(shí)現(xiàn)。
總結(jié)
以上所述是小編給大家介紹的CSS 響應(yīng)式布局系統(tǒng)的實(shí)例代碼,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
CSS3移動(dòng)端vw+rem不依賴JS實(shí)現(xiàn)響應(yīng)式布局的方法
這篇文章主要介紹了CSS3移動(dòng)端vw+rem不依賴JS實(shí)現(xiàn)響應(yīng)式布局的方法的相關(guān)資料,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-23html5/css3響應(yīng)式頁(yè)面開(kāi)發(fā)總結(jié)
響應(yīng)式一套模板適應(yīng)所有終端,但每種設(shè)備看到的版式可以是不一樣的。這篇文章主要介紹了html5/css3響應(yīng)式頁(yè)面開(kāi)發(fā)總結(jié) ,需要的朋友可以參考下2018-10-16- 本篇文章主要介紹了CSS banner圖響應(yīng)式居中顯示的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-03
詳解使用CSS3的@media來(lái)編寫響應(yīng)式的頁(yè)面
這篇文章主要介紹了詳解使用CSS3的@media來(lái)編寫響應(yīng)式的頁(yè)面,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-01jQuery和CSS3響應(yīng)式輪播插件jcSlider
jcSlider是一款jquery和CSS3響應(yīng)式輪播圖插件。生成60多種輪播圖過(guò)渡動(dòng)畫效果,簡(jiǎn)單實(shí)用,歡迎下載2017-07-21純CSS3大轉(zhuǎn)盤抽獎(jiǎng)示例代碼(響應(yīng)式、可配置)
這篇文章主要介紹了純CSS3大轉(zhuǎn)盤抽獎(jiǎng)示例代碼(響應(yīng)式、可配置),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。2017-01-13CSS3 media queries + jQuery實(shí)現(xiàn)響應(yīng)式導(dǎo)航
這篇文章主要介紹了CSS3 media queries + jQuery實(shí)現(xiàn)響應(yīng)式導(dǎo)航的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-30