您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關使用CSS怎么實現一個響應式布局系統,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
css是一種用來表現HTML或XML等文件樣式的計算機語言,主要是用來設計網頁的樣式,使網頁更加美化。它也是一種定義樣式結構如字體、顏色、位置等的語言,并且css樣式可以直接存儲于HTML網頁或者單獨的樣式單文件中,而樣式規則的優先級由css根據這個層次結構決定,從而實現級聯效果,發展至今,css不僅能裝飾網頁,也可以配合各種腳本對于網頁進行格式化。
響應式布局系統,在現在流行的 CSS 框架中已經非常常見了。它主要由容器類和約定一行列數的柵格系統組成,組成了一個框架的骨架。
在流行的前端框架 Bootstrap 和 Bulma CSS 中,就有體現。像 Bootstrap 的 .container 、 .row 、 .col ;還有 Bulma CSS 的 .container 、 columns 、 column 都是表示這類布局系統。雖然名稱不一樣,但原理都是相同的。
隨著 Flex 布局的普及,幾乎現代的柵格系統的實現都選擇使用這一靈活的布局方式。
現在就來看一下,怎樣實現一個最小的 CSS 響應式布局系統吧。
首先從容器說起。
為了保證實現代碼的簡潔,本文將使用 SCSS 來寫。如果你對 SCSS 還不熟悉,沒有關系,行文中會對使用到的知識點做介紹。
容器
容器主要用來包裹網頁的主要內容,常見效果就是將內容居中地顯示在屏幕中間。
我們使用 .container 來約定容器。
首先,容器是水平居中的,這一塊樣式較為容易:
.container { margin-left: auto; margin-right: auto; }
所謂的響應式容器,就是根據不同的斷點(breakpoints),也就是當前的視口寬度,來決定容器使用的 max-width 值。
這里我們借鑒了 Bootstrap 中對斷點的定義,根據視口寬度,分為以下幾類設備:
[0, 576px) [576px, 768px) [768px, 992px) [992px, 1200px) [1200px, +∞)
針對斷點定義,聲明一個變量 $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 提供給我們的數據結構。由一個個 key: value 鍵值對組成。上例中的 key 表示的是設備有效范圍的起始點。
不同的設備下,容器有不同的 max-width 值。所以,這里我們再聲明一個表示容器寬度的變量 $container-max-widths :
$container-max-widths: ( xs: none, sm: 540px, md: 720px, lg: 960px, xl: 1140px );
這里的 $container-max-widths 也是個列表,這里的 key 表示某個設備下容器的最大寬度。比如,在超大屏設備下,容器的最大寬度是 1140px ,而在平常手機下,不設置容器的最大寬度,為默認值 none 。
有了實現的思路,接下來就著手實現。
我們就可以借助媒體查詢指令 @media ,依據視口寬度的范圍,給予 .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 行代碼搞定!
下面解釋下上面的代碼。
我們對列表遍歷,使用的是 @each...in 語法,每一次遍歷取出對應的 key、value,得到當前的 $device 、 $breakpoint 。 map-get 是 SCSS 提供的用來操作列表的方法:根據 key 取出 value。比如,當 $device 值為 xs 的時候, map-get($container-max-widths, $device) 對應值為 none ;當 $device 值為 sm 的時候, map-get($container-max-widths, $device) 對應值為 540px ,以此類推。
@media only screen and (min-width: $breakpoint) { ... }
中包含的代碼,表示從當前設備斷點開始處,應用的 CSS 樣式。 當我們同時按照從小到大的順序設置兩個斷點的媒體查詢時,后者會覆蓋前者的樣式 ,這是實現不同視口下,具有不同寬度容器的核心原理。
接下來,將得到的寬度值賦給容器的 max-width 屬性就可以了。
到現在為止,我們就寫出了一個響應式容器了,我們總攬下代碼:
$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); } } }
點擊這里,查看效果。
下面再來介紹 12 列柵格布局。
12 列柵格布局
先使用 Flex 布局,寫一個最簡的等寬布局。
.row { display: flex; .col { flex-grow: 1; flex-basis: 0; } }
沒錯,這就是使用 Flex 布局實現一個等寬布局的所有代碼了。如果不考慮中間的空白行,只需要 7 行代碼。
這里的原理是,我們將所有 Flex 項目的 flex-basis 設置為 0 了,就是說這些 Flex 項目在 grow 或 shrink 之前都沒有寬度,是一樣長的。這樣最終計算出來的主軸空間會平均地分配給了每個 Flex 項目,這樣它們就等寬了。
到這里,我們所寫的這個簡易柵格布局有兩個局限:
1.不能布局非等寬項目。
2.不支持換行。
換行的話很好弄,為 Flex 容器加個 flex-wrap: wrap 就可以了。那怎樣處理“非等寬項目”排列布局呢。
為了能實現非等寬項目的布局,我們的思路是: 禁用 Flex 項目的伸縮特性,使用百分比 width 指定寬度 。
首先,禁用 Flex 項目的伸縮特性,使用到的屬性如下:
flex-shrink: 0; flex-grow: 0; flex-basis: 0;
這三個屬性等價的快捷寫法是:
flex: none;
然后就是使用百分比 width 指定寬度了。
我們實現的是一行最多 12 列的柵格布局。也就是說把一行劃分成 12 列,每一列的寬度大約占總寬度的 8.33% 。我們用 .is-列數 指定一個項目占據的列數:
.is-1
.is-2
.is-3
.is-4
.is-5
.is-6
.is-7
.is-8
.is-9
.is-10
.is-11
.is-12
根據這個規律,我們可以很容易地寫出柵格布局代碼:
$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>
語法,從 1 遞增到 12,定義了 .is-* 這一系列類名,原理就是我們說過的禁用了 Flex 項目的伸縮特性,指定給它百分比寬度。怎么樣,很簡單吧。
接下來再加上折行( .row.is-multiline
)和 Flex 項目偏移( .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 的效果;項目偏移則借助 margin-left
屬性實現。
到這里,我們的 12 列柵格布局就寫完了 ヾ(?°∇°?)??
完整代碼
我們把上面兩部分的代碼整合起來,就能得到一個最小的響應式布局系統了~ 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); } } } }
關于使用CSS怎么實現一個響應式布局系統就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。